@nervur-org/dock 0.3.1 → 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.
Files changed (212) hide show
  1. package/GETTING_STARTED.md +22 -12
  2. package/{beings/GLOSSARY.md → GLOSSARY.md} +3 -3
  3. package/NOTICE +1 -1
  4. package/README.md +20 -16
  5. package/{beings/WORLDS.md → WORLDS.md} +6 -4
  6. package/api/route.ts +3 -3
  7. package/beings/avatar.ts +2 -2
  8. package/beings/carry.ts +2 -2
  9. package/beings/clock.ts +2 -2
  10. package/beings/courier.ts +2 -2
  11. package/beings/desk.ts +2 -2
  12. package/beings/doorbell.ts +2 -2
  13. package/beings/envoy.ts +2 -2
  14. package/beings/join.ts +2 -2
  15. package/beings/link.ts +5 -5
  16. package/beings/look.ts +1 -1
  17. package/beings/porter.ts +2 -2
  18. package/beings/presence.ts +1 -1
  19. package/beings/setup.ts +3 -3
  20. package/beings/side.ts +2 -2
  21. package/beings/user.ts +2 -2
  22. package/beings/way.ts +1 -1
  23. package/cli/client.ts +6 -6
  24. package/cli/daemon.ts +7 -7
  25. package/cli/estate/{quo.service → nervur.service} +12 -12
  26. package/cli/estate/org.nervur.plist +44 -0
  27. package/cli/estate.ts +6 -6
  28. package/cli/{quo.ts → nervur.ts} +43 -37
  29. package/cli/pilot.ts +3 -3
  30. package/cli/stand.ts +3 -3
  31. package/dist/api/route.d.ts +2 -2
  32. package/dist/api/route.js +2 -2
  33. package/dist/beings/avatar.d.ts +1 -1
  34. package/dist/beings/avatar.js +1 -1
  35. package/dist/beings/carry.d.ts +2 -2
  36. package/dist/beings/carry.js +1 -1
  37. package/dist/beings/clock.d.ts +2 -2
  38. package/dist/beings/clock.js +1 -1
  39. package/dist/beings/courier.d.ts +2 -2
  40. package/dist/beings/courier.js +1 -1
  41. package/dist/beings/desk.d.ts +3 -3
  42. package/dist/beings/desk.js +1 -1
  43. package/dist/beings/doorbell.d.ts +3 -3
  44. package/dist/beings/doorbell.js +1 -1
  45. package/dist/beings/envoy.d.ts +2 -2
  46. package/dist/beings/envoy.js +1 -1
  47. package/dist/beings/join.d.ts +2 -2
  48. package/dist/beings/link.d.ts +2 -2
  49. package/dist/beings/link.js +3 -3
  50. package/dist/beings/look.d.ts +1 -1
  51. package/dist/beings/porter.d.ts +2 -2
  52. package/dist/beings/porter.js +1 -1
  53. package/dist/beings/presence.d.ts +1 -1
  54. package/dist/beings/setup.d.ts +1 -1
  55. package/dist/beings/side.d.ts +1 -1
  56. package/dist/beings/side.js +1 -1
  57. package/dist/beings/user.d.ts +3 -3
  58. package/dist/beings/user.js +1 -1
  59. package/dist/beings/way.d.ts +1 -1
  60. package/dist/cli/client.js +4 -4
  61. package/dist/cli/daemon.d.ts +1 -1
  62. package/dist/cli/daemon.js +6 -6
  63. package/dist/cli/estate/{quo.service → nervur.service} +12 -12
  64. package/dist/cli/estate/org.nervur.plist +44 -0
  65. package/dist/cli/estate.js +6 -6
  66. package/dist/cli/{quo.js → nervur.js} +43 -37
  67. package/dist/cli/stand.d.ts +2 -2
  68. package/dist/dock/agents.d.ts +1 -1
  69. package/dist/dock/agents.js +1 -1
  70. package/dist/dock/apns.js +1 -1
  71. package/dist/dock/console.d.ts +1 -1
  72. package/dist/dock/dialers.d.ts +2 -2
  73. package/dist/dock/dialers.js +2 -2
  74. package/dist/dock/faculty.d.ts +2 -2
  75. package/dist/dock/faculty.js +1 -1
  76. package/dist/dock/grants.d.ts +1 -1
  77. package/dist/dock/grants.js +1 -1
  78. package/dist/dock/http2.js +1 -1
  79. package/dist/dock/index.d.ts +1 -1
  80. package/dist/dock/index.js +1 -1
  81. package/dist/dock/local.d.ts +2 -2
  82. package/dist/dock/location.d.ts +1 -1
  83. package/dist/dock/notifications.d.ts +1 -1
  84. package/dist/dock/notifications.js +1 -1
  85. package/dist/dock/push.d.ts +1 -1
  86. package/dist/dock/push.js +3 -3
  87. package/dist/dock/service.js +1 -1
  88. package/dist/dock/timer.d.ts +1 -1
  89. package/dist/harbor/browser.d.ts +2 -2
  90. package/dist/harbor/browser.js +4 -4
  91. package/dist/harbor/capacitor.d.ts +1 -1
  92. package/dist/harbor/capacitor.js +1 -1
  93. package/dist/harbor/disk.d.ts +4 -4
  94. package/dist/harbor/disk.js +5 -5
  95. package/dist/harbor/edge/edge.d.ts +2 -2
  96. package/dist/harbor/edge/edge.js +5 -5
  97. package/dist/harbor/edge/exercise.js +8 -8
  98. package/dist/harbor/edge/given.d.ts +1 -1
  99. package/dist/harbor/edge/platform.d.ts +1 -1
  100. package/dist/harbor/edge/storage.d.ts +1 -1
  101. package/dist/harbor/edge/storage.js +2 -2
  102. package/dist/harbor/edge/worker.js +2 -2
  103. package/dist/harbor/files.d.ts +1 -1
  104. package/dist/harbor/files.js +2 -2
  105. package/dist/harbor/http.d.ts +2 -2
  106. package/dist/harbor/http.js +1 -1
  107. package/dist/harbor/idb.d.ts +1 -1
  108. package/dist/harbor/idb.js +0 -0
  109. package/dist/harbor/quo.js +1 -1
  110. package/dist/harbor/seal.js +1 -1
  111. package/dist/harbor/sealed.d.ts +1 -1
  112. package/dist/harbor/sealed.js +4 -4
  113. package/dist/harbor/tauri.d.ts +1 -1
  114. package/dist/harbor/tauri.js +1 -1
  115. package/dist/harbor/ward.d.ts +1 -1
  116. package/dist/human/app.d.ts +2 -2
  117. package/dist/human/door.js +4 -4
  118. package/dist/human/guest.js +1 -1
  119. package/dist/human/html.d.ts +1 -1
  120. package/dist/human/html.js +1 -1
  121. package/dist/human/local.d.ts +1 -1
  122. package/dist/human/mark.js +2 -2
  123. package/dist/human/move.d.ts +2 -2
  124. package/dist/human/move.js +1 -1
  125. package/dist/human/screen.d.ts +1 -1
  126. package/dist/human/screen.js +3 -3
  127. package/dist/human/tab.bundle.txt +32 -32
  128. package/dist/human/tab.js +7 -7
  129. package/dist/human/tree.d.ts +1 -1
  130. package/dist/human/wake.d.ts +2 -2
  131. package/dist/human/wake.js +1 -1
  132. package/dist/human/web.d.ts +1 -1
  133. package/dist/human/web.js +4 -4
  134. package/dist/human/worker.bundle.txt +27 -27
  135. package/dist/human/worker.js +4 -4
  136. package/dist/human/worlds.d.ts +2 -2
  137. package/dist/human/worlds.js +4 -4
  138. package/dist/mcp/agent.d.ts +1 -1
  139. package/dist/mcp/allow.d.ts +1 -1
  140. package/dist/mcp/allow.js +2 -2
  141. package/dist/mcp/oauth.js +1 -1
  142. package/dist/mcp/runner.d.ts +1 -1
  143. package/dist/mcp/server.d.ts +2 -2
  144. package/dist/mcp/server.js +2 -2
  145. package/dock/agents.ts +2 -2
  146. package/dock/apns.ts +1 -1
  147. package/dock/console.ts +1 -1
  148. package/dock/dialers.ts +3 -3
  149. package/dock/faculty.ts +2 -2
  150. package/dock/grants.ts +2 -2
  151. package/dock/http2.ts +1 -1
  152. package/dock/index.ts +3 -3
  153. package/dock/local.ts +1 -1
  154. package/dock/location.ts +1 -1
  155. package/dock/notifications.ts +2 -2
  156. package/dock/push.ts +4 -4
  157. package/dock/service.ts +1 -1
  158. package/dock/timer.ts +1 -1
  159. package/harbor/browser.ts +5 -5
  160. package/harbor/capacitor.ts +2 -2
  161. package/harbor/disk.ts +8 -8
  162. package/harbor/edge/edge.ts +7 -7
  163. package/harbor/edge/exercise.ts +11 -11
  164. package/harbor/edge/given.ts +1 -1
  165. package/harbor/edge/platform.d.ts +1 -1
  166. package/harbor/edge/storage.ts +2 -2
  167. package/harbor/edge/worker.ts +2 -2
  168. package/harbor/edge/wrangler.toml +3 -3
  169. package/harbor/files.ts +2 -2
  170. package/harbor/http.ts +2 -2
  171. package/harbor/idb.ts +0 -0
  172. package/harbor/quo.ts +1 -1
  173. package/harbor/resolve.ts +1 -1
  174. package/harbor/seal.ts +1 -1
  175. package/harbor/sealed.ts +5 -5
  176. package/harbor/tauri.ts +2 -2
  177. package/harbor/ward.ts +1 -1
  178. package/human/app.ts +2 -2
  179. package/human/apps.ts +1 -1
  180. package/human/door.ts +4 -4
  181. package/human/guest.ts +2 -2
  182. package/human/html.ts +2 -2
  183. package/human/local.ts +1 -1
  184. package/human/mark.ts +2 -2
  185. package/human/move.ts +3 -3
  186. package/human/screen.ts +5 -5
  187. package/human/tab.bundle.txt +32 -32
  188. package/human/tab.ts +10 -10
  189. package/human/tree.ts +1 -1
  190. package/human/wake.ts +3 -3
  191. package/human/web.ts +5 -5
  192. package/human/worker.bundle.txt +27 -27
  193. package/human/worker.ts +6 -6
  194. package/human/worlds.ts +5 -5
  195. package/mcp/agent.ts +1 -1
  196. package/mcp/allow.ts +5 -5
  197. package/mcp/oauth.ts +1 -1
  198. package/mcp/runner.ts +1 -1
  199. package/mcp/server.ts +3 -3
  200. package/package.json +15 -7
  201. package/{api/quo-api.md → quo-api.md} +1 -1
  202. package/{beings/quo-dock.md → quo-dock.md} +74 -71
  203. package/{harbor/quo-harbor.md → quo-harbor.md} +54 -30
  204. package/{human/quo-human.md → quo-human.md} +7 -7
  205. package/{mcp/quo-mcp.md → quo-mcp.md} +10 -10
  206. package/cli/estate/systems.quo.plist +0 -44
  207. package/cli/quo-dock.md +0 -1942
  208. package/dist/cli/estate/systems.quo.plist +0 -44
  209. package/dock/quo-app-bells.md +0 -280
  210. package/dock/quo-dock.md +0 -1942
  211. /package/dist/cli/{quo.d.ts → nervur.d.ts} +0 -0
  212. /package/{beings/quo-app-bells.md → quo-app-bells.md} +0 -0
@@ -8,27 +8,37 @@ This is the shortest road from nothing to each of the three, for a
8
8
  stranger with a terminal. `SPEC.md` is the truth behind every sentence
9
9
  here and assumes nothing; `quo-dock.md` is the dock, the part a box runs.
10
10
 
11
+ Quo is the protocol and Nervur is this kit of it. Every name you install
12
+ and every command you type is Nervur's; `quo` stays on the wire, as the
13
+ `quo.` route a ward's door answers at.
14
+
11
15
  Two packages, and you start with the one that fits what you have:
12
16
 
13
- - `@nervur-org/nervur`, the library. A harbor, a ward and a being in one
17
+ - `nervur`, the library. A harbor, a ward and a being in one
14
18
  process, no wire, no files. For a program that wants Quo inside it.
15
- - `@nervur-org/dock`, the dock. A daemon and one command, `quo`, that
19
+ - `@nervur-org/dock`, the dock. A daemon and one command, `nervur`, that
16
20
  stand a box up: a person's world with a page, a model's side, an api, a
17
21
  door on the wire. For a box that receives people and models.
18
22
 
23
+ The command is in the dock and not in the library, so `npm install nervur`
24
+ gives you something to import and no command, and the command arrives with
25
+ `npm install -g @nervur-org/dock`. That is how a kit of this shape is
26
+ always named: one unscoped headline name for the library, the parts under
27
+ the scope, and the CLI in the package that owns it.
28
+
19
29
  ## A being, in one process
20
30
 
21
31
  ```bash
22
- npm install @nervur-org/nervur
32
+ npm install nervur
23
33
  ```
24
34
 
25
35
  A being is a class with `asks`, the methods anyone may reach, each with
26
36
  the JSON schema of its input. Everything else on the class is hers alone.
27
37
 
28
38
  ```js
29
- import { Being } from '@nervur-org/nervur';
30
- import { Ward } from '@nervur-org/nervur/ward';
31
- import { MemoryHarbor } from '@nervur-org/nervur/harbor';
39
+ import { Being } from 'nervur';
40
+ import { Ward } from 'nervur/ward';
41
+ import { MemoryHarbor } from 'nervur/harbor';
32
42
 
33
43
  class Shop extends Being {
34
44
  static asks = { price: { input: { type: 'object', properties: { item: { type: 'string' } } } } };
@@ -78,8 +88,8 @@ ward, never held.
78
88
 
79
89
  ```bash
80
90
  npm install @nervur-org/dock
81
- npx quo init --dir ~/.quo --ward acme --user razvan --domain acme.com --default --show
82
- npx quo serve --dir ~/.quo --http 8787
91
+ npx nervur init --dir ~/.nervur --ward acme --user razvan --domain acme.com --default --show
92
+ npx nervur serve --dir ~/.nervur --http 8787
83
93
  ```
84
94
 
85
95
  `init` mints the ward `acme`, boots razvan's user being, her doorbell and
@@ -97,7 +107,7 @@ at one loopback address:
97
107
  command is its client. From a second terminal, a phone:
98
108
 
99
109
  ```bash
100
- npx quo invite --dir ~/.quo '{"being":"razvan","id":"phone"}'
110
+ npx nervur invite --dir ~/.nervur '{"being":"razvan","id":"phone"}'
101
111
  ```
102
112
 
103
113
  The answer carries `link`, the ward's page with the invitation in its
@@ -108,7 +118,7 @@ JSON at `api.`, and what another box gets is the door at `quo.`; a being
108
118
  answers each the same, because each is an ask at her door.
109
119
 
110
120
  The box's own doings are rows on the faculties of its dock ward, placed by
111
- the root with `quo ask --ward dock`: a socket held to another box, an
121
+ the root with `nervur ask --ward dock`: a socket held to another box, an
112
122
  agent run for a ward, a schedule on the clock. A second box owns this one
113
123
  across the wire with an invitation on the ward's own pk, knocked with
114
124
  from there, and every owner command with `--via` from then on. Each of
@@ -119,8 +129,8 @@ somebody with nothing else to read.
119
129
  ## Your own beings on a box
120
130
 
121
131
  A box holds the dock's classes and yours. `classes/index.ts` beside the
122
- wards exports each of yours by name, and `quo boot '{"key":"shop",
123
- "class":"Shop"}'` boots one; `quo init --class Shop` makes the ward's home
132
+ wards exports each of yours by name, and `nervur boot '{"key":"shop",
133
+ "class":"Shop"}'` boots one; `nervur init --class Shop` makes the ward's home
124
134
  being one of yours, an organisation's ward with the org as its being. A
125
135
  being's asks may name who may reach them, `for`, over the record of the
126
136
  occupant asking, and her `cells` are what she keeps between boots: the
@@ -50,14 +50,14 @@ are where the rest are built.
50
50
  faculties that box lends. Never a home, and never migrated.
51
51
  - **estate**: all of one owner's harbors, with what is theirs alone, in a
52
52
  tree of the owner's own and never published.
53
- - **daemon**: `quo serve`, the one process on a device that holds a harbor.
53
+ - **daemon**: `nervur serve`, the one process on a device that holds a harbor.
54
54
  - **route**: a hostname a reverse proxy sends to one process: `web.`,
55
55
  `quo.`, `mcp.`, `api.`.
56
56
  - **user being**: the org being of an org of one: a human's own, holding
57
57
  all of her standings. The dock's `User` class, which also serves a
58
58
  membership the desk makes in another org's ward.
59
59
  - **front desk**: the being every fresh client meets; hands out invitations
60
- minted by the ward's being, and is what `quo init` marks public in a
60
+ minted by the ward's being, and is what `nervur init` marks public in a
61
61
  fresh ward. Any ward may mark one being of any class public instead.
62
62
  - **avatar**: a being that is someone's voice from outside Quo, one per
63
63
  client identity.
@@ -106,7 +106,7 @@ are where the rest are built.
106
106
  - **look**: how a being is presented, as values; one optional ask.
107
107
  - **page**: a being's page as a tree of values in the screen's grammar; one
108
108
  optional ask, read by a screen alone.
109
- - **owner pilot**: `quo pilot`, the model side over a ward's owner asks,
109
+ - **owner pilot**: `nervur pilot`, the model side over a ward's owner asks,
110
110
  reaching the daemon's socket; with `--via`, a ward elsewhere through a
111
111
  standing. Under cron, the estate's own agent.
112
112
 
package/NOTICE CHANGED
@@ -1,4 +1,4 @@
1
- Quo
1
+ Nervur
2
2
  Copyright 2026 Razvan Gherghina
3
3
 
4
4
  This product includes software developed by Razvan Gherghina.
package/README.md CHANGED
@@ -1,35 +1,39 @@
1
1
  # The dock
2
2
 
3
3
  What every estate on Quo needs and nobody writes twice: a daemon and the
4
- `quo` command, the front desk, the user being and the avatar, harbors on
4
+ `nervur` command, the front desk, the user being and the avatar, harbors on
5
5
  disk, in a tab and on the edge, the model sides and the screen, the
6
6
  credential exchange. An estate is all of one owner's harbors, and it is
7
7
  built on the dock, on Quo.
8
8
 
9
9
  ```bash
10
10
  npm install @nervur-org/dock
11
- npx quo estate my-estate --domain example.com
12
- npx quo init --dir my-estate/droplet
13
- npx quo serve --dir my-estate/droplet
11
+ npx nervur estate my-estate --domain example.com
12
+ npx nervur init --dir my-estate/droplet
13
+ npx nervur serve --dir my-estate/droplet
14
14
  ```
15
15
 
16
- `quo estate` writes an estate folder: one folder per harbor, the first a
17
- droplet's quo directory with its routes under your domain, its unit and
16
+ `nervur estate` writes an estate folder: one folder per harbor, the first a
17
+ droplet's harbor directory with its routes under your domain, its unit and
18
18
  its Caddyfile, and a package file that depends on the dock and nothing
19
19
  else. Add your beings to `droplet/classes/`, and your placement to the
20
20
  routes and agents files.
21
21
 
22
- `beings/quo-dock.md` is the truth of this package and the trunk of its
23
- documents; read it first. It knows nothing the spec of Quo does not say,
22
+ [`quo-dock.md`](quo-dock.md) is the truth of this package and the trunk of
23
+ its documents; read it first. It knows nothing the spec of Quo does not say,
24
24
  and adds no word to harbor, ward or being. Beside it are the sides,
25
- `human/quo-human.md`, `mcp/quo-mcp.md`, `api/quo-api.md` and
26
- `harbor/quo-harbor.md`; `beings/WORLDS.md` is what home, presence and
27
- membership mean, and `beings/GLOSSARY.md` is every word above the spec.
28
-
29
- ## Publishing
30
-
31
- Published from 0.1.0 with no compatibility promise before 1.0.0. The
32
- package ships an emitted `dist/` with its command, and the source beside it.
25
+ [`quo-human.md`](quo-human.md), [`quo-mcp.md`](quo-mcp.md),
26
+ [`quo-api.md`](quo-api.md) and [`quo-harbor.md`](quo-harbor.md), and the
27
+ bells, [`quo-app-bells.md`](quo-app-bells.md);
28
+ [`WORLDS.md`](WORLDS.md) is what home, presence and membership mean, and
29
+ [`GLOSSARY.md`](GLOSSARY.md) is every word above the spec. Each stands once,
30
+ at the root of the package, the way `nervur` and `@nervur-org/ui` carry
31
+ theirs.
32
+
33
+ ## Versions
34
+
35
+ No compatibility promise before 1.0.0. The package ships an emitted `dist/`
36
+ with its command, and the source beside it.
33
37
 
34
38
  ## License
35
39
 
@@ -55,9 +55,11 @@ That is the whole of it, and this is what it leaves open:
55
55
  - **Quo has no home.** Three boxes rooted by one party, each holding
56
56
  standings on the other two, is Quo, and so is one box with a hundred
57
57
  wards. Nothing says which ward, if any, is the one that matters.
58
- - **Quo has no route.** How bytes arrive at a device is the harbor's
59
- directory, and Quo says nothing about it. A hostname, a socket, a screen
60
- and a tool list are all outside the protocol.
58
+ - **Quo has no route.** It pins the two shapes a reach may take and the
59
+ frames they carry, because two harbors meet on those, and it says nothing
60
+ about where a ward lives: which hostname answers, how a harbor learns a
61
+ foreign pk, and whether anyone can be dialed at all are the device's. A
62
+ hostname, a screen and a tool list are outside the protocol entirely.
61
63
  - **Quo has four rungs and no more.** A stranger hears the public being as
62
64
  `{}`. An occupant hears what the gate shows that occupant. An owner
63
65
  reaches in. A root holds the ask pointer. Guest, member, subscriber,
@@ -356,7 +358,7 @@ An org's box hears the world on three routes, and a route is a hostname the
356
358
  reverse proxy sends to one process. `web.` speaks a being's describe as
357
359
  forms and a page, for a human at a screen. `mcp.` speaks it as tools, for a
358
360
  model at its client. `api.` speaks it as plain HTTP and JSON, for a
359
- program, a script or a tab on another origin. A fourth voice, the `quo`
361
+ program, a script or a tab on another origin. A fourth voice, the `nervur`
360
362
  command on the device itself, speaks it as lines, and reaches the daemon's
361
363
  socket rather than a hostname.
362
364
 
package/api/route.ts CHANGED
@@ -34,13 +34,13 @@
34
34
  // shapes, are the route's own 404 and never a being's.
35
35
  import type { Handler } from '../harbor/http.ts';
36
36
  import { readText } from '../harbor/http.ts';
37
- import type { Hosted } from '@nervur-org/nervur/harbor';
37
+ import type { Hosted } from 'nervur/harbor';
38
38
  import type { Avatar } from '../beings/avatar.ts';
39
39
  import { invitationOf } from '../beings/link.ts';
40
40
  import { landed, POLICY } from '../human/door.ts';
41
41
  import { CSS } from '../human/style.ts';
42
42
  import type { Grants } from '../dock/grants.ts';
43
- import { isInvitation, isSilence, isWord, wordOf, type Invitation, type JsonObject } from '@nervur-org/nervur';
43
+ import { isInvitation, isSilence, isWord, wordOf, type Invitation, type JsonObject } from 'nervur';
44
44
 
45
45
  const open = { 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET, POST, OPTIONS', 'access-control-allow-headers': 'content-type, authorization' };
46
46
 
@@ -75,7 +75,7 @@ export function apiRoute(harbor: Held, o: Options): Handler {
75
75
  // is the allow page's, and for the same reason: a page that runs no
76
76
  // script of its own should be allowed none.
77
77
  const page = (status: number, body: string) =>
78
- new Response(`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>quo</title>\n<style>${CSS}</style>\n</head><body>${body}</body></html>`, {
78
+ new Response(`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>nervur</title>\n<style>${CSS}</style>\n</head><body>${body}</body></html>`, {
79
79
  status,
80
80
  headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store', 'content-security-policy': POLICY, 'referrer-policy': 'no-referrer' },
81
81
  });
package/beings/avatar.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  // calls the four methods below: one of the two ways in, `enter` behind a
8
8
  // route's proof or `join` with an invitation, then `tools` and `call`.
9
9
  // Nothing of a side is in her cells.
10
- import { isSilence, isWord, wordOf } from '@nervur-org/nervur';
11
- import type { Answer, Blueprint, Invitation, JsonObject, OccupantRecord, Wanted } from '@nervur-org/nervur';
10
+ import { isSilence, isWord, wordOf } from 'nervur';
11
+ import type { Answer, Blueprint, Invitation, JsonObject, OccupantRecord, Wanted } from 'nervur';
12
12
  import { Carrier } from './carry.ts';
13
13
 
14
14
  // Her one standing, and the id under which the user being pushes to her.
package/beings/carry.ts CHANGED
@@ -18,8 +18,8 @@
18
18
  // `look` once per digest, and keeps both in her cells. So a describe of
19
19
  // hers may cost one ask per stale standing, which is the price of a page
20
20
  // that is never more than one ask behind.
21
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
22
- import type { Asker, Blueprint, JsonObject, OccupantRecord, Reply } from '@nervur-org/nervur';
21
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
22
+ import type { Asker, Blueprint, JsonObject, OccupantRecord, Reply } from 'nervur';
23
23
  import { sanitise, type Look } from './look.ts';
24
24
 
25
25
  type Carried = Record<string, { id: string; ask: string }>;
package/beings/clock.ts CHANGED
@@ -29,8 +29,8 @@
29
29
  // and what an occupant registered on the service placement. Nothing is read
30
30
  // from a file and nothing is set on the class, so a schedule outlives the
31
31
  // process the way every cell does, and is gone when it is dropped.
32
- import { Being, isSilence, isWord, wordOf, OWNER } from '@nervur-org/nervur';
33
- import type { Asker, Invitation, Json, JsonObject, OccupantRecord, Stance } from '@nervur-org/nervur';
32
+ import { Being, isSilence, isWord, wordOf, OWNER } from 'nervur';
33
+ import type { Asker, Invitation, Json, JsonObject, OccupantRecord, Stance } from 'nervur';
34
34
  import { TIMER, join } from '../dock/index.ts';
35
35
 
36
36
  // The root and nobody else. `OWNER` is one of the ward's own words, refused at
package/beings/courier.ts CHANGED
@@ -26,8 +26,8 @@
26
26
  // the shell holding this device when it is asked for, and what arrives goes
27
27
  // back to the shell, since a partition written into another ward's cells is
28
28
  // a copy nobody asked for.
29
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
30
- import type { Answer, Invitation, JsonObject, OccupantRecord } from '@nervur-org/nervur';
29
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
30
+ import type { Answer, Invitation, JsonObject, OccupantRecord } from 'nervur';
31
31
 
32
32
  // The id each end knows the other by for the length of one move.
33
33
  export const MOVER = 'mover';
package/beings/desk.ts CHANGED
@@ -16,8 +16,8 @@
16
16
  // judges nothing here: she does not know what an address is, whether one was
17
17
  // sent to before, or what a link says. She keeps the ways in named in one
18
18
  // place, so a side that renders her renders every way into this world.
19
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
20
- import type { Asker, Blueprint, JsonObject, Reply, Stance } from '@nervur-org/nervur';
19
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
20
+ import type { Asker, Blueprint, JsonObject, Reply, Stance } from 'nervur';
21
21
  import { join } from '../dock/faculty.ts';
22
22
  import { LOCAL } from '../dock/local.ts';
23
23
  import { WAY, kindOf, verified } from './way.ts';
@@ -21,8 +21,8 @@
21
21
  // in. The device hands its banner key to a world itself, beside the
22
22
  // invitation to this doorbell, so a bell that held both halves of the
23
23
  // relation is a bell that could read a banner, and this one cannot.
24
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
25
- import type { Asker, JsonObject, OccupantRecord } from '@nervur-org/nervur';
24
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
25
+ import type { Asker, JsonObject, OccupantRecord } from 'nervur';
26
26
 
27
27
  const DEVICE = 'device';
28
28
  // Her standing at the box's push faculty, under an id of her own. The ward
package/beings/envoy.ts CHANGED
@@ -18,8 +18,8 @@
18
18
  // bytes checked before anything is parsed, the id kept bounded so a retry
19
19
  // lands once, `{ ok }` answered before the wake goes out, a wake that meets
20
20
  // silence written down and never retried.
21
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
22
- import type { Asker, AskSpec, JsonObject, OccupantRecord } from '@nervur-org/nervur';
21
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
22
+ import type { Asker, AskSpec, JsonObject, OccupantRecord } from 'nervur';
23
23
 
24
24
  // The two gates. The owner is the ward's ask pointer, `{ id: 'OWNER' }`,
25
25
  // which is how the daemon asks `deliver` and how the root places a
package/beings/join.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  // A way in that is the box's own, a nonce on the `local` faculty, is not
8
8
  // here: it is a process the device saw on its own socket, which only a
9
9
  // terrain with processes has, and the daemon keeps it.
10
- import type { Hosted } from '@nervur-org/nervur/harbor';
11
- import type { Invitation } from '@nervur-org/nervur';
10
+ import type { Hosted } from 'nervur/harbor';
11
+ import type { Invitation } from 'nervur';
12
12
  import type { Avatar } from './avatar.ts';
13
13
 
14
14
  // Her avatar in a ward, found or booted under the identity's key. An
package/beings/link.ts CHANGED
@@ -2,15 +2,15 @@
2
2
  // A link: a world's page with an invitation in the fragment. The page is the
3
3
  // hint, where the world lives; the fragment is the invitation, which never
4
4
  // leaves the browser: a query string reaches the server, its logs and every
5
- // referer, and an invitation is a capability. One reserved key, `quo`, the
5
+ // referer, and an invitation is a capability. One reserved key, `nervur`, the
6
6
  // one word no page uses for anything else, and the value is the invitation
7
7
  // compact: `ward.heir.secret`, three hex strings, or `ward` alone for a
8
8
  // world's public being. The dock's human module reads it, strips it before
9
9
  // any page code runs, and joins. One other key is reserved, `proof`, for the
10
10
  // way in a world sent out itself, and it is read the same way.
11
- import type { Invitation } from '@nervur-org/nervur';
11
+ import type { Invitation } from 'nervur';
12
12
 
13
- export const KEY = 'quo';
13
+ export const KEY = 'nervur';
14
14
  // The other reserved key: a proof, for a way in the world sent out itself.
15
15
  // A proof is not a capability into a ward, it is a word one door will trade
16
16
  // once for an invitation, and it rides in the fragment for the same reason:
@@ -29,7 +29,7 @@ export function format(inv: Invitation): string {
29
29
  // The invitation in a fragment, or null. Anything else in the fragment is
30
30
  // the page's own and is left alone.
31
31
  export function parse(hash: string): Invitation | null {
32
- const m = /(?:^#|&)quo=([^&]+)/.exec(hash.startsWith('#') ? hash : `#${hash}`);
32
+ const m = new RegExp(`(?:^#|&)${KEY}=([^&]+)`).exec(hash.startsWith('#') ? hash : `#${hash}`);
33
33
  if (!m) return null;
34
34
  const v = decodeURIComponent(m[1]);
35
35
  const full = FULL.exec(v);
@@ -70,7 +70,7 @@ export function proofLink(page: string, kind: string, token: string): string {
70
70
  }
71
71
 
72
72
  // The invitation as a human hands it over: the compact form, the whole link
73
- // it came in, or the JSON value `quo invite` printed. Wherever a person
73
+ // it came in, or the JSON value `nervur invite` printed. Wherever a person
74
74
  // types or pastes an invitation, this is what reads it, so the three forms
75
75
  // are one form everywhere.
76
76
  export function invitationOf(text: string): Invitation | null {
package/beings/look.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  // is a list of origins a side reads to decide whether to vouch for an
13
13
  // address the being's own page named, and nothing in the dock ever fetches
14
14
  // one.
15
- import type { Blueprint, Json } from '@nervur-org/nervur';
15
+ import type { Blueprint, Json } from 'nervur';
16
16
 
17
17
  // What a side may do with one ask. `title` is a human label instead of the
18
18
  // name; `readOnly` says the ask changes nothing, so a screen may run it on
package/beings/porter.ts CHANGED
@@ -13,8 +13,8 @@
13
13
  // twice is two doorbells and no harm. A stranger who keeps knocking is the
14
14
  // harbor's, never hers and never the door's, and the count below is only so
15
15
  // that a loop in this session stops somewhere a human can see.
16
- import { Being, isSilence, isWord, wordOf } from '@nervur-org/nervur';
17
- import type { JsonObject } from '@nervur-org/nervur';
16
+ import { Being, isSilence, isWord, wordOf } from 'nervur';
17
+ import type { JsonObject } from 'nervur';
18
18
 
19
19
  const ROOM = 64;
20
20
 
@@ -13,7 +13,7 @@
13
13
  // to her, and birth is synchronous while taking a standing is not, so what
14
14
  // she holds is settled after her constructor returns; the terrain waits on
15
15
  // `settled` before it says the box is up.
16
- import type { Asker, OccupantRecord, Stance } from '@nervur-org/nervur';
16
+ import type { Asker, OccupantRecord, Stance } from 'nervur';
17
17
  import { Avatar, PUSHER, USER } from './avatar.ts';
18
18
  import { FACULTIES, join } from '../dock/index.ts';
19
19
 
package/beings/setup.ts CHANGED
@@ -4,10 +4,10 @@
4
4
  // `user:<name>`, placed by the root's knock, and she holding her own ward's
5
5
  // door as an owner under `home`. She names the desk `desk`,
6
6
  // and that id is the only thing that makes it the desk. A disk harbor does
7
- // this at `quo init`, the edge at its root route's init; the memory
7
+ // this at `nervur init`, the edge at its root route's init; the memory
8
8
  // harbor's test world does the same by hand.
9
- import type { Invitation } from '@nervur-org/nervur';
10
- import type { Hosted } from '@nervur-org/nervur/harbor';
9
+ import type { Invitation } from 'nervur';
10
+ import type { Hosted } from 'nervur/harbor';
11
11
  import { DESK, HOME } from './user.ts';
12
12
 
13
13
  // The root boots and steps back: it invites an owner on the ward's own pk
package/beings/side.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  // her one standing, and a push as a notification. Sides in this repository:
6
6
  // a screen, an MCP server, a runner, an event-driven agent. None knows
7
7
  // another exists, and none of this file names a platform.
8
- import { isSilence, isUnreached, isWord, wordOf } from '@nervur-org/nervur';
9
- import type { Answer, Blueprint, Json, JsonObject, Wanted, WordName } from '@nervur-org/nervur';
8
+ import { isSilence, isUnreached, isWord, wordOf } from 'nervur';
9
+ import type { Answer, Blueprint, Json, JsonObject, Wanted, WordName } from 'nervur';
10
10
  import type { Avatar } from './avatar.ts';
11
11
 
12
12
  // A side, running: it holds the avatar until closed.
package/beings/user.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  // client identity the desk established. A device she let mint brings the
8
8
  // next one in, so a human adds a device from a device already in and only
9
9
  // the first one has to come from the root, on the box.
10
- import { isInvitation, isSilence, isWord, wordOf } from '@nervur-org/nervur';
11
- import type { Asker, Blueprint, Invitation, JsonObject, OccupantRecord, Stance } from '@nervur-org/nervur';
10
+ import { isInvitation, isSilence, isWord, wordOf } from 'nervur';
11
+ import type { Asker, Blueprint, Invitation, JsonObject, OccupantRecord, Stance } from 'nervur';
12
12
  import { Carrier } from './carry.ts';
13
13
  import { PUSH, banner, isToken, join, sealBanner } from '../dock/index.ts';
14
14
 
package/beings/way.ts CHANGED
@@ -24,7 +24,7 @@
24
24
  // `send` beside it, and the desk shows the form for it because her standing
25
25
  // says the being can be asked it. She judges neither: she does not know what
26
26
  // an address is, whether one was sent to before, or what a link says.
27
- import type { AskSpec, Json } from '@nervur-org/nervur';
27
+ import type { AskSpec, Json } from 'nervur';
28
28
 
29
29
  export type Proof = { kind: string; [more: string]: Json };
30
30
  // Who the proof is for, and how far the device it admits may go. `make` is
package/cli/client.ts CHANGED
@@ -14,7 +14,7 @@ export function ask(dir: string, method: string | undefined, args: Record<string
14
14
  return line(dir, { ...(ward === undefined ? {} : { ward }), method, args, ...(via === undefined ? {} : { via }) });
15
15
  }
16
16
 
17
- // `quo ask`: the root asking a being of its own ward, as the device. The six
17
+ // `nervur ask`: the root asking a being of its own ward, as the device. The six
18
18
  // owner asks make and place beings; this is the other half of the owner role,
19
19
  // reaching into one, and without it a being's owner-gated ask had no caller
20
20
  // but the daemon itself.
@@ -22,7 +22,7 @@ export function askBeing(dir: string, being: string, method?: string, args: Reco
22
22
  return line(dir, { ...(ward === undefined ? {} : { ward }), being, method, args });
23
23
  }
24
24
 
25
- // `quo reach`: a hint for the harbor's directory, which is the harbor's and
25
+ // `nervur reach`: a hint for the harbor's directory, which is the harbor's and
26
26
  // not a ward's, so it crosses the root socket as its own line.
27
27
  export function reach(dir: string, pk: string, url: string): Promise<Answer> {
28
28
  return line(dir, { reach: { pk, url } });
@@ -32,7 +32,7 @@ function line(dir: string, body: Record<string, unknown>): Promise<Answer> {
32
32
  return new Promise((ok, no) => {
33
33
  const c = connect(sockPath(dir));
34
34
  const id = Math.random().toString(36).slice(2);
35
- c.once('error', (e: NodeJS.ErrnoException) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`quo serve\``) : e));
35
+ c.once('error', (e: NodeJS.ErrnoException) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`nervur serve\``) : e));
36
36
  c.once('connect', () => {
37
37
  c.write(JSON.stringify({ id, ...body }) + '\n');
38
38
  createInterface({ input: c }).once('line', (reply) => {
@@ -44,19 +44,19 @@ function line(dir: string, body: Record<string, unknown>): Promise<Answer> {
44
44
  });
45
45
  }
46
46
 
47
- // `quo side`: a pipe. Hello to the daemon's side socket, then stdin to the
47
+ // `nervur side`: a pipe. Hello to the daemon's side socket, then stdin to the
48
48
  // socket and the socket to stdout, line for line, until either end closes.
49
49
  // The MCP server runs in the daemon, beside the avatar; this process knows
50
50
  // nothing of MCP but its newlines.
51
51
  //
52
- // `quo run` is the same pipe with a model named in the hello: the daemon
52
+ // `nervur run` is the same pipe with a model named in the hello: the daemon
53
53
  // runs the runner beside the avatar, each line typed is a turn, and each
54
54
  // final text comes back as a line.
55
55
  export type Run = { url: string; model: string; key?: string; turns?: number };
56
56
  export function side(dir: string, as: string, ward: string, run?: Run): Promise<void> {
57
57
  return new Promise((ok, no) => {
58
58
  const c = connect(sidePath(dir));
59
- c.once('error', (e: NodeJS.ErrnoException) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`quo serve\``) : e));
59
+ c.once('error', (e: NodeJS.ErrnoException) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`nervur serve\``) : e));
60
60
  c.once('connect', () => {
61
61
  c.write(JSON.stringify(run ? { as, ward, run } : { as, ward }) + '\n');
62
62
  const lines = createInterface({ input: c });
package/cli/daemon.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- // The daemon: `quo serve`. One process holds the harbor and the ask pointer
2
+ // The daemon: `nervur serve`. One process holds the harbor and the ask pointer
3
3
  // of every ward in it. Two local doors, never mixed, each a unix socket only
4
4
  // the device's user can read:
5
5
  //
6
- // quo.sock the root. One line of JSON in, one line out.
6
+ // nervur.sock the root. One line of JSON in, one line out.
7
7
  // -> { id, ward?, method?, args?, via? }
8
8
  // <- { id, result } | { id, error }
9
9
  // With `being`, the line is the owner's `ask`, forwarded like
@@ -59,7 +59,7 @@
59
59
  // push faculty with one ring per token kind this device can ring.
60
60
  //
61
61
  // The default ward is the one a caller means when naming none: the one ward
62
- // hosted, or the one marked in its own folder by `quo default`. A harbor is
62
+ // hosted, or the one marked in its own folder by `nervur default`. A harbor is
63
63
  // not a being and has no self to be, so the one thing it can do is point at
64
64
  // one of its wards. Its agents boot there and its door answers for it when a
65
65
  // caller names no ward. Several wards and no mark is refused here, by name,
@@ -86,11 +86,11 @@ import { createHash, randomBytes } from 'node:crypto';
86
86
  import { tmpdir } from 'node:os';
87
87
  import { join, resolve } from 'node:path';
88
88
  import { createInterface } from 'node:readline';
89
- import { isSilence, isWord, wordOf, type Invitation, type JsonObject } from '@nervur-org/nervur';
89
+ import { isSilence, isWord, wordOf, type Invitation, type JsonObject } from 'nervur';
90
90
  import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
91
91
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
92
92
  import { DiskHarbor, defaultWard, type Hosted } from '../harbor/disk.ts';
93
- import type { Harbor } from '@nervur-org/nervur/harbor';
93
+ import type { Harbor } from 'nervur/harbor';
94
94
  import type { Avatar, User } from '../beings/index.ts';
95
95
  // an identity in a world: the three asks any terrain's routes make at a ward
96
96
  export { avatarOf, letIn, find } from '../beings/join.ts';
@@ -128,9 +128,9 @@ export type Options = { http?: { port: number; host?: string }; routes?: Routes;
128
128
  const socketPath = (dir: string, name: string): string => {
129
129
  const inside = join(resolve(dir), `${name}.sock`);
130
130
  if (inside.length < 100) return inside;
131
- return join(tmpdir(), `quo-${createHash('sha256').update(resolve(dir)).digest('hex').slice(0, 16)}-${name}.sock`);
131
+ return join(tmpdir(), `nervur-${createHash('sha256').update(resolve(dir)).digest('hex').slice(0, 16)}-${name}.sock`);
132
132
  };
133
- export const sockPath = (dir: string) => socketPath(dir, 'quo');
133
+ export const sockPath = (dir: string) => socketPath(dir, 'nervur');
134
134
  export const sidePath = (dir: string) => socketPath(dir, 'side');
135
135
 
136
136
  // Admit a local client identity into a ward: find or boot her avatar, and
@@ -1,24 +1,24 @@
1
1
  # The daemon on a droplet, as one user, forever. Install with:
2
- # sudo cp droplet/quo.service /etc/systemd/system/quo.service
3
- # sudo systemctl enable --now quo
4
- # The unit runs as the `quo` user, whose home holds the estate folder and
2
+ # sudo cp droplet/nervur.service /etc/systemd/system/nervur.service
3
+ # sudo systemctl enable --now nervur
4
+ # The unit runs as the `nervur` user, whose home holds the estate folder and
5
5
  # the harbor folder, so the seed, the lease and the sockets are that user's
6
6
  # alone. The HTTP door is loopback only; Caddy fronts it. See Caddyfile
7
7
  # beside this file.
8
8
  [Unit]
9
- Description=quo: one harbor on this device
9
+ Description=nervur: one harbor on this device
10
10
  After=network.target
11
11
 
12
12
  [Service]
13
- User=quo
14
- Group=quo
15
- Environment=QUO_DIR=/home/quo/.quo
16
- Environment=QUO_HTTP=8787
13
+ User=nervur
14
+ Group=nervur
15
+ Environment=NERVUR_DIR=/home/nervur/.nervur
16
+ Environment=NERVUR_HTTP=8787
17
17
  # CLAUDE_CODE_OAUTH_TOKEN, when an agent folder runs `claude -p`: the agent
18
18
  # reads its credential from the device, never from cells.
19
- EnvironmentFile=-/etc/quo/env
20
- WorkingDirectory=/home/quo/ESTATE
21
- ExecStart=/usr/bin/node /home/quo/ESTATE/node_modules/@nervur-org/dock/dist/cli/quo.js serve
19
+ EnvironmentFile=-/etc/nervur/env
20
+ WorkingDirectory=/home/nervur/ESTATE
21
+ ExecStart=/usr/bin/node /home/nervur/ESTATE/node_modules/@nervur-org/dock/dist/cli/nervur.js serve
22
22
  Restart=always
23
23
  RestartSec=2
24
24
  KillSignal=SIGTERM
@@ -28,7 +28,7 @@ ProtectSystem=strict
28
28
  # Agents run in their folders and Claude Code keeps its own state in the
29
29
  # user's home; both must be writable for a run to happen, and a harbor
30
30
  # with no agent has neither.
31
- ReadWritePaths=/home/quo/.quo -/home/quo/agents -/home/quo/.claude -/home/quo/.claude.json /tmp
31
+ ReadWritePaths=/home/nervur/.nervur -/home/nervur/agents -/home/nervur/.claude -/home/nervur/.claude.json /tmp
32
32
  PrivateTmp=false
33
33
 
34
34
  [Install]