@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
@@ -1,4 +1,4 @@
1
- import type { AskSpec, Json } from '@nervur-org/nervur';
1
+ import type { AskSpec, Json } from 'nervur';
2
2
  export type Proof = {
3
3
  kind: string;
4
4
  [more: string]: Json;
@@ -10,14 +10,14 @@ import { sockPath, sidePath } from './daemon.js';
10
10
  export function ask(dir, method, args = {}, ward, via) {
11
11
  return line(dir, { ...(ward === undefined ? {} : { ward }), method, args, ...(via === undefined ? {} : { via }) });
12
12
  }
13
- // `quo ask`: the root asking a being of its own ward, as the device. The six
13
+ // `nervur ask`: the root asking a being of its own ward, as the device. The six
14
14
  // owner asks make and place beings; this is the other half of the owner role,
15
15
  // reaching into one, and without it a being's owner-gated ask had no caller
16
16
  // but the daemon itself.
17
17
  export function askBeing(dir, being, method, args = {}, ward) {
18
18
  return line(dir, { ...(ward === undefined ? {} : { ward }), being, method, args });
19
19
  }
20
- // `quo reach`: a hint for the harbor's directory, which is the harbor's and
20
+ // `nervur reach`: a hint for the harbor's directory, which is the harbor's and
21
21
  // not a ward's, so it crosses the root socket as its own line.
22
22
  export function reach(dir, pk, url) {
23
23
  return line(dir, { reach: { pk, url } });
@@ -26,7 +26,7 @@ function line(dir, body) {
26
26
  return new Promise((ok, no) => {
27
27
  const c = connect(sockPath(dir));
28
28
  const id = Math.random().toString(36).slice(2);
29
- c.once('error', (e) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`quo serve\``) : e));
29
+ c.once('error', (e) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`nervur serve\``) : e));
30
30
  c.once('connect', () => {
31
31
  c.write(JSON.stringify({ id, ...body }) + '\n');
32
32
  createInterface({ input: c }).once('line', (reply) => {
@@ -40,7 +40,7 @@ function line(dir, body) {
40
40
  export function side(dir, as, ward, run) {
41
41
  return new Promise((ok, no) => {
42
42
  const c = connect(sidePath(dir));
43
- c.once('error', (e) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`quo serve\``) : e));
43
+ c.once('error', (e) => no(e.code === 'ENOENT' || e.code === 'ECONNREFUSED' ? new Error(`no daemon at ${dir}: run \`nervur serve\``) : e));
44
44
  c.once('connect', () => {
45
45
  c.write(JSON.stringify(run ? { as, ward, run } : { as, ward }) + '\n');
46
46
  const lines = createInterface({ input: c });
@@ -1,5 +1,5 @@
1
1
  import { DiskHarbor, type Hosted } from '../harbor/disk.ts';
2
- import type { Harbor } from '@nervur-org/nervur/harbor';
2
+ import type { Harbor } from 'nervur/harbor';
3
3
  import type { Avatar } from '../beings/index.ts';
4
4
  export { avatarOf, letIn, find } from '../beings/join.ts';
5
5
  import { type Ring } from '../dock/index.ts';
@@ -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,
@@ -85,7 +85,7 @@ import { createHash, randomBytes } from 'node:crypto';
85
85
  import { tmpdir } from 'node:os';
86
86
  import { join, resolve } from 'node:path';
87
87
  import { createInterface } from 'node:readline';
88
- import { isSilence, isWord, wordOf } from '@nervur-org/nervur';
88
+ import { isSilence, isWord, wordOf } from 'nervur';
89
89
  import { DiskHarbor, defaultWard } from '../harbor/disk.js';
90
90
  // an identity in a world: the three asks any terrain's routes make at a ward
91
91
  export { avatarOf, letIn, find } from '../beings/join.js';
@@ -116,9 +116,9 @@ const socketPath = (dir, name) => {
116
116
  const inside = join(resolve(dir), `${name}.sock`);
117
117
  if (inside.length < 100)
118
118
  return inside;
119
- return join(tmpdir(), `quo-${createHash('sha256').update(resolve(dir)).digest('hex').slice(0, 16)}-${name}.sock`);
119
+ return join(tmpdir(), `nervur-${createHash('sha256').update(resolve(dir)).digest('hex').slice(0, 16)}-${name}.sock`);
120
120
  };
121
- export const sockPath = (dir) => socketPath(dir, 'quo');
121
+ export const sockPath = (dir) => socketPath(dir, 'nervur');
122
122
  export const sidePath = (dir) => socketPath(dir, 'side');
123
123
  // Admit a local client identity into a ward: find or boot her avatar, and
124
124
  // enter her with a nonce the box's way in honours once. On a reconnect she
@@ -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]
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ The daemon on a Mac, as the user, forever: a launchd agent. It holds the
4
+ harbor at ~/.nervur and the socket to every quo. route ~/.nervur/dial.json
5
+ names, so a Mac behind NAT is reached through the droplet it dialed. The
6
+ daemon runs the dock's emitted `dist/cli/nervur.js` from where the estate
7
+ installed it, never the source. Install, with node on the path:
8
+
9
+ sed "s#HOME#$HOME#g; s#NODE#$(which node)#g" mac/org.nervur.plist > ~/Library/LaunchAgents/org.nervur.plist
10
+ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/org.nervur.plist
11
+
12
+ Remove with `launchctl bootout gui/$(id -u)/org.nervur`; restart after a
13
+ wire change with `launchctl kickstart -k gui/$(id -u)/org.nervur`. The
14
+ log is ~/.nervur/serve.log. No HTTP door: a Mac is a dialer, not a listener.
15
+ -->
16
+ <plist version="1.0">
17
+ <dict>
18
+ <key>Label</key>
19
+ <string>org.nervur</string>
20
+ <key>ProgramArguments</key>
21
+ <array>
22
+ <string>NODE</string>
23
+ <string>HOME/ESTATE/node_modules/@nervur-org/dock/dist/cli/nervur.js</string>
24
+ <string>serve</string>
25
+ </array>
26
+ <key>EnvironmentVariables</key>
27
+ <dict>
28
+ <key>NERVUR_DIR</key>
29
+ <string>HOME/.nervur</string>
30
+ </dict>
31
+ <key>WorkingDirectory</key>
32
+ <string>HOME/ESTATE</string>
33
+ <key>RunAtLoad</key>
34
+ <true/>
35
+ <key>KeepAlive</key>
36
+ <true/>
37
+ <key>ThrottleInterval</key>
38
+ <integer>2</integer>
39
+ <key>StandardOutPath</key>
40
+ <string>HOME/.nervur/serve.log</string>
41
+ <key>StandardErrorPath</key>
42
+ <string>HOME/.nervur/serve.log</string>
43
+ </dict>
44
+ </plist>
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- // `quo estate DIR --domain D`: an estate folder, written once, of the shape
3
- // every estate has. One folder per harbor: `droplet/`, the quo directory
2
+ // `nervur estate DIR --domain D`: an estate folder, written once, of the shape
3
+ // every estate has. One folder per harbor: `droplet/`, the harbor directory
4
4
  // that device runs minus what it mints, its routes under the domain, no
5
5
  // agents, no schedules, no classes of its own, and that device's unit and
6
6
  // Caddyfile; and `mac/`, the launchd agent that runs the daemon on an
@@ -34,13 +34,13 @@ export async function estate(dir, domain) {
34
34
  const name = basename(dir);
35
35
  const files = {
36
36
  'package.json': JSON.stringify({ name, private: true, description: `The ${name} estate: one owner's harbors, built on the dock and nothing else.`, type: 'module', dependencies: { '@nervur-org/dock': `^${await version()}` } }, null, 2) + '\n',
37
- [`${name}.md`]: `# ${name}\n\nAn estate: all of one owner's harbors. One folder per harbor, each the quo\ndirectory that device runs minus what it mints, plus that device's unit.\n\`droplet/\` is the first: its routes under \`${domain}\`, its agents, its\nclasses, its systemd unit and its Caddyfile. This folder depends on the\ndock and nothing else.\n\n## The droplet\n\nWhere it is, how it is reached, and what was done to stand it up: yours\nto write.\n`,
37
+ [`${name}.md`]: `# ${name}\n\nAn estate: all of one owner's harbors. One folder per harbor, each the harbor\ndirectory that device runs minus what it mints, plus that device's unit.\n\`droplet/\` is the first: its routes under \`${domain}\`, its agents, its\nclasses, its systemd unit and its Caddyfile. This folder depends on the\ndock and nothing else.\n\n## The droplet\n\nWhere it is, how it is reached, and what was done to stand it up: yours\nto write.\n`,
38
38
  'droplet/routes.json': JSON.stringify(routesFor(domain)) + '\n',
39
- 'droplet/stand.ts': `// SPDX-License-Identifier: Apache-2.0\n// What the root stands up on this harbor, once, after the inits and with no\n// daemon over the folder: the beings the estate boots for its own working\n// and the relations between them, placed on real invitations. Run as\n// \`node droplet/stand.ts <dir>\`; twice is once.\nimport { stand } from '@nervur-org/dock/stand';\n\nconsole.log(await stand(process.argv[2] ?? process.env.QUO_DIR ?? '', { boot: [], wire: [] }));\n`,
39
+ 'droplet/stand.ts': `// SPDX-License-Identifier: Apache-2.0\n// What the root stands up on this harbor, once, after the inits and with no\n// daemon over the folder: the beings the estate boots for its own working\n// and the relations between them, placed on real invitations. Run as\n// \`node droplet/stand.ts <dir>\`; twice is once.\nimport { stand } from '@nervur-org/dock/stand';\n\nconsole.log(await stand(process.argv[2] ?? process.env.NERVUR_DIR ?? '', { boot: [], wire: [] }));\n`,
40
40
  'droplet/classes/index.ts': '// The classes this harbor holds beside the dock\'s built-in ones, exported\n// by name.\nexport {};\n',
41
- 'droplet/quo.service': (await template('quo.service')).replaceAll('ESTATE', name),
41
+ 'droplet/nervur.service': (await template('nervur.service')).replaceAll('ESTATE', name),
42
42
  'droplet/Caddyfile': (await template('Caddyfile')).replaceAll('DOMAIN', domain),
43
- 'mac/systems.quo.plist': (await template('systems.quo.plist')).replaceAll('ESTATE', name),
43
+ 'mac/org.nervur.plist': (await template('org.nervur.plist')).replaceAll('ESTATE', name),
44
44
  };
45
45
  for (const [rel, text] of Object.entries(files)) {
46
46
  await mkdir(join(dir, rel, '..'), { recursive: true });
@@ -1,32 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- // `quo`: the one command of the estate. Thin on purpose: each subcommand
3
+ // `nervur`: the one command of the estate. Thin on purpose: each subcommand
4
4
  // picks a folder, reaches the daemon or the disk, and hands off. Logic that
5
5
  // appears here was missing from a being or a side, and moves there.
6
6
  //
7
- // quo 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 the ward's home being, User unless said; --default marks it the default ward; --show shows it at the web route; --domain writes the four routes under DOM
8
- // quo default [--dir D] <ward> mark one ward the default, the one a caller means when naming none; the one ward hosted is the default unmarked
9
- // quo show|hide [--dir D] <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, and a hidden ward's page is the plain door
10
- // quo domain [--dir D] <domain> write routes.json by the convention: mcp., web., quo. and api. under the domain, over https
11
- // quo serve [--dir D] [--http PORT] the daemon: harbor from disk, the two sockets, the HTTP door on loopback, a socket held to every route the dialers faculty keeps
12
- // quo census [--dir D] [--ward W] [--via S] the empty ask: pk and every being
13
- // quo boot [--dir D] [--ward W] [--via S] <json> { key, class, public? }
14
- // quo invite [--dir D] [--ward W] [--via S] <json> { being, id }; with routes.json naming web., the answer carries the link
15
- // quo knock [--dir D] [--ward W] [--via S] <json> { being | { boot, key }, id, invitation, method?, args?, wanted? }
16
- // quo remove [--dir D] [--ward W] [--via S] <json> { being, id }: a relation out of a being; on the ward pk, an owner
17
- // quo unboot [--dir D] [--ward W] [--via S] <json> { being }: a being out of the ward, with every relation she holds
18
- // quo ask [--dir D] [--ward W] <being> [method] [json] the root asking a being of its own ward, as the device
19
- // quo side [--dir D] [--ward W] --as NAME an avatar over stdio for a local MCP client; NAME is the client identity
20
- // quo run [--dir D] [--ward W] --as NAME --url URL --model NAME [--turns N] a human at a terminal talking to a model through an avatar: a line in, the model's final text out
21
- // quo pilot [--dir D] [--ward W] [--via S] the owner pilot over stdio: census, boot, invite, knock, remove
22
- // quo reach [--dir D] <pk> <url> a hint for the harbor's directory: that ward pk lives at that quo. route
23
- // quo estate <dir> --domain D an estate folder of the shape every estate has: a droplet's quo directory, unit and Caddyfile, a Mac's launchd agent, on this dock
7
+ // The command carries the kit's name and never the protocol's. `quo` is
8
+ // Quo's word, and it stays on the wire: the `quo.` route, a ward's door, the
9
+ // sealed wards' folder. Nothing a person types is called quo, and nothing a
10
+ // device holds for the daemon is either: the unit, the unix user, the home
11
+ // and the environment file all say nervur.
24
12
  //
25
- // D defaults to $QUO_DIR, then ~/.quo. W defaults to the default ward, and
13
+ // 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 the ward's home being, User unless said; --default marks it the default ward; --show shows it at the web route; --domain writes the four routes under DOM
14
+ // nervur default [--dir D] <ward> mark one ward the default, the one a caller means when naming none; the one ward hosted is the default unmarked
15
+ // nervur show|hide [--dir D] <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, and a hidden ward's page is the plain door
16
+ // nervur domain [--dir D] <domain> write routes.json by the convention: mcp., web., quo. and api. under the domain, over https
17
+ // nervur serve [--dir D] [--http PORT] the daemon: harbor from disk, the two sockets, the HTTP door on loopback, a socket held to every route the dialers faculty keeps
18
+ // nervur census [--dir D] [--ward W] [--via S] the empty ask: pk and every being
19
+ // nervur boot [--dir D] [--ward W] [--via S] <json> { key, class, public? }
20
+ // nervur invite [--dir D] [--ward W] [--via S] <json> { being, id }; with routes.json naming web., the answer carries the link
21
+ // nervur knock [--dir D] [--ward W] [--via S] <json> { being | { boot, key }, id, invitation, method?, args?, wanted? }
22
+ // nervur remove [--dir D] [--ward W] [--via S] <json> { being, id }: a relation out of a being; on the ward pk, an owner
23
+ // nervur unboot [--dir D] [--ward W] [--via S] <json> { being }: a being out of the ward, with every relation she holds
24
+ // nervur ask [--dir D] [--ward W] <being> [method] [json] the root asking a being of its own ward, as the device
25
+ // nervur side [--dir D] [--ward W] --as NAME an avatar over stdio for a local MCP client; NAME is the client identity
26
+ // nervur run [--dir D] [--ward W] --as NAME --url URL --model NAME [--turns N] a human at a terminal talking to a model through an avatar: a line in, the model's final text out
27
+ // nervur pilot [--dir D] [--ward W] [--via S] the owner pilot over stdio: census, boot, invite, knock, remove
28
+ // nervur reach [--dir D] <pk> <url> a hint for the harbor's directory: that ward pk lives at that quo. route
29
+ // nervur estate <dir> --domain D an estate folder of the shape every estate has: a droplet's harbor directory, unit and Caddyfile, a Mac's launchd agent, on this dock
30
+ //
31
+ // D defaults to $NERVUR_DIR, then ~/.nervur. W defaults to the default ward, and
26
32
  // init names a new ward main when none is given. init takes
27
33
  // --user NAME for the user being, defaulting to the device's user. run
28
- // takes the model's base URL as --url or $QUO_MODEL_URL, its name as
29
- // --model or $QUO_MODEL, a bearer from $QUO_MODEL_KEY, read here and never
34
+ // takes the model's base URL as --url or $NERVUR_MODEL_URL, its name as
35
+ // --model or $NERVUR_MODEL, a bearer from $NERVUR_MODEL_KEY, read here and never
30
36
  // kept, and --turns as the ceiling of model calls in one turn. S is a
31
37
  // standing the user being holds at another ward, one the root there invited
32
38
  // as an owner: with --via, the owner asks go to that ward's door, sealed,
@@ -34,7 +40,7 @@
34
40
  import { homedir, userInfo } from 'node:os';
35
41
  import { join } from 'node:path';
36
42
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
37
- import { isInvitation } from '@nervur-org/nervur';
43
+ import { isInvitation } from 'nervur';
38
44
  import { DiskHarbor } from '../harbor/disk.js';
39
45
  import { serve, readRoutes, writeRoutes } from './daemon.js';
40
46
  import { ask, askBeing, side, reach } from './client.js';
@@ -55,7 +61,7 @@ function parse(argv) {
55
61
  rest.push(a);
56
62
  }
57
63
  const [cmd, json, more, third] = rest;
58
- return { cmd, json, more, third, flags, dir: flags.dir ?? process.env.QUO_DIR ?? join(homedir(), '.quo'), ward: flags.ward, via: flags.via };
64
+ return { cmd, json, more, third, flags, dir: flags.dir ?? process.env.NERVUR_DIR ?? join(homedir(), '.nervur'), ward: flags.ward, via: flags.via };
59
65
  }
60
66
  const print = (v) => console.log(JSON.stringify(v, null, 2));
61
67
  async function main(argv) {
@@ -67,7 +73,7 @@ async function main(argv) {
67
73
  }
68
74
  if (cmd === 'default') {
69
75
  if (!json) {
70
- console.error('quo default <ward>');
76
+ console.error('nervur default <ward>');
71
77
  return 2;
72
78
  }
73
79
  await DiskHarbor.setDefault(dir, json);
@@ -76,7 +82,7 @@ async function main(argv) {
76
82
  }
77
83
  if (cmd === 'show' || cmd === 'hide') {
78
84
  if (!json) {
79
- console.error(`quo ${cmd} <ward>`);
85
+ console.error(`nervur ${cmd} <ward>`);
80
86
  return 2;
81
87
  }
82
88
  await DiskHarbor.setShown(dir, json, cmd === 'show');
@@ -85,7 +91,7 @@ async function main(argv) {
85
91
  }
86
92
  if (cmd === 'domain') {
87
93
  if (!json) {
88
- console.error('quo domain <domain>');
94
+ console.error('nervur domain <domain>');
89
95
  return 2;
90
96
  }
91
97
  print({ routes: await writeRoutes(dir, json) });
@@ -97,18 +103,18 @@ async function main(argv) {
97
103
  const wardOf = async () => flags.ward ?? (await DiskHarbor.defaultOf(dir));
98
104
  if (cmd === 'side' || cmd === 'run') {
99
105
  if (!flags.as) {
100
- console.error(`quo ${cmd} needs --as NAME`);
106
+ console.error(`nervur ${cmd} needs --as NAME`);
101
107
  return 2;
102
108
  }
103
109
  let run;
104
110
  if (cmd === 'run') {
105
- const url = flags.url ?? process.env.QUO_MODEL_URL;
106
- const model = flags.model ?? process.env.QUO_MODEL;
111
+ const url = flags.url ?? process.env.NERVUR_MODEL_URL;
112
+ const model = flags.model ?? process.env.NERVUR_MODEL;
107
113
  if (!url || !model) {
108
- console.error('quo run needs --url URL and --model NAME, or QUO_MODEL_URL and QUO_MODEL');
114
+ console.error('nervur run needs --url URL and --model NAME, or NERVUR_MODEL_URL and NERVUR_MODEL');
109
115
  return 2;
110
116
  }
111
- const key = process.env.QUO_MODEL_KEY;
117
+ const key = process.env.NERVUR_MODEL_KEY;
112
118
  const turns = flags.turns !== undefined ? Number(flags.turns) : undefined;
113
119
  if (turns !== undefined && !(Number.isInteger(turns) && turns > 0)) {
114
120
  console.error('--turns is a positive integer');
@@ -127,7 +133,7 @@ async function main(argv) {
127
133
  return -1;
128
134
  }
129
135
  if (cmd === 'serve') {
130
- const port = flags.http ?? process.env.QUO_HTTP;
136
+ const port = flags.http ?? process.env.NERVUR_HTTP;
131
137
  const s = await serve(dir, port !== undefined ? { http: { port: Number(port) } } : {});
132
138
  print({ dir: s.harbor.dir, sock: s.sock, side: s.side, http: s.http ? `http://${s.http.host}:${s.http.port}` : null, dial: s.quo.dialers.map((d) => d.url), wards: Object.fromEntries([...s.harbor.wards].map(([n, h]) => [n, h.pk])) });
133
139
  const stop = () => void s.close().then(() => process.exit(0));
@@ -137,19 +143,19 @@ async function main(argv) {
137
143
  }
138
144
  if (cmd === 'estate') {
139
145
  if (!json || !flags.domain) {
140
- console.error('quo estate needs <dir> --domain D');
146
+ console.error('nervur estate needs <dir> --domain D');
141
147
  return 2;
142
148
  }
143
149
  print(await estate(json, flags.domain));
144
150
  return 0;
145
151
  }
146
152
  // The root reaching into a being of its own ward. Two positionals and the
147
- // args as JSON, because a human writes this one by hand: `quo ask clock keep
153
+ // args as JSON, because a human writes this one by hand: `nervur ask clock keep
148
154
  // '{"id":"nightly","ask":"desk.hello","cron":"0 3 * * *"}'`. With no
149
155
  // method it is that being's describe, as the device sees her.
150
156
  if (cmd === 'ask') {
151
157
  if (!json) {
152
- console.error('quo ask needs <being> [method] [json]');
158
+ console.error('nervur ask needs <being> [method] [json]');
153
159
  return 2;
154
160
  }
155
161
  const out = await askBeing(dir, json, more, third ? JSON.parse(third) : {}, await wardOf());
@@ -159,7 +165,7 @@ async function main(argv) {
159
165
  }
160
166
  if (cmd === 'reach') {
161
167
  if (!json || !more) {
162
- console.error('quo reach needs <pk> <url>');
168
+ console.error('nervur reach needs <pk> <url>');
163
169
  return 2;
164
170
  }
165
171
  const out = await reach(dir, json, more);
@@ -189,7 +195,7 @@ async function main(argv) {
189
195
  const failed = 'error' in out || (typeof out.result === 'object' && out.result !== null && 'error' in out.result);
190
196
  return failed ? 1 : 0;
191
197
  }
192
- console.error('usage: quo init|default|show|hide|domain|serve|census|boot|public|invite|knock|remove|unboot|ask|side|run|pilot|reach|estate [--dir D] [--ward W] [--via S] [--as NAME] [--url URL --model NAME] [json]');
198
+ console.error('usage: nervur init|default|show|hide|domain|serve|census|boot|public|invite|knock|remove|unboot|ask|side|run|pilot|reach|estate [--dir D] [--ward W] [--via S] [--as NAME] [--url URL --model NAME] [json]');
193
199
  return 2;
194
200
  }
195
201
  main(process.argv.slice(2)).then((code) => {
@@ -1,5 +1,5 @@
1
- import type { JsonObject } from '@nervur-org/nervur';
2
- import type { Harbor } from '@nervur-org/nervur/harbor';
1
+ import type { JsonObject } from 'nervur';
2
+ import type { Harbor } from 'nervur/harbor';
3
3
  export type Boot = {
4
4
  ward: string;
5
5
  key: string;
@@ -1,4 +1,4 @@
1
- import type { Asker, JsonObject, OccupantRecord } from '@nervur-org/nervur';
1
+ import type { Asker, JsonObject, OccupantRecord } from 'nervur';
2
2
  import { Faculty } from './faculty.ts';
3
3
  export declare const AGENTS = "agents";
4
4
  export type Process = {
@@ -21,7 +21,7 @@
21
21
  // to persist: running an agent is admitting through a socket only a daemon
22
22
  // has, and this file is not in the dock's index, since a tab has no process
23
23
  // to spawn. A box with no runner keeps the table and runs nobody.
24
- import { OWNER } from '@nervur-org/nervur';
24
+ import { OWNER } from 'nervur';
25
25
  import { Faculty } from './faculty.js';
26
26
  // The name the dock ward holds her under.
27
27
  export const AGENTS = 'agents';
package/dist/dock/apns.js CHANGED
@@ -61,7 +61,7 @@ export function device(token) {
61
61
  export function request(a, jwt, token, sealed) {
62
62
  const said = sealed === undefined
63
63
  ? { aps: { 'content-available': 1 } }
64
- : { aps: { alert: { 'loc-key': 'quo.ring' }, 'mutable-content': 1, sound: 'default' }, sealed };
64
+ : { aps: { alert: { 'loc-key': 'nervur.ring' }, 'mutable-content': 1, sound: 'default' }, sealed };
65
65
  return {
66
66
  path: `/3/device/${device(token)}`,
67
67
  headers: {
@@ -1,5 +1,5 @@
1
1
  import { Carrier } from '../beings/carry.ts';
2
- import type { Asker, OccupantRecord } from '@nervur-org/nervur';
2
+ import type { Asker, OccupantRecord } from 'nervur';
3
3
  export declare const CONSOLE = "console";
4
4
  export declare class Console extends Carrier {
5
5
  static carries(occupant: OccupantRecord | undefined, _asker: Asker): boolean;
@@ -1,5 +1,5 @@
1
- import type { Asker, JsonObject, OccupantRecord } from '@nervur-org/nervur';
2
- import { type Dialer, type Harbor } from '@nervur-org/nervur/harbor';
1
+ import type { Asker, JsonObject, OccupantRecord } from 'nervur';
2
+ import { type Dialer, type Harbor } from 'nervur/harbor';
3
3
  import { Faculty } from './faculty.ts';
4
4
  export declare const DIALERS = "dialers";
5
5
  export type Row = {
@@ -14,8 +14,8 @@
14
14
  // library's, written on the standard socket surface, so this faculty holds
15
15
  // on every terrain that has a socket; the daemon hands her the harbor to
16
16
  // dial for, as it hands the agents faculty how to run a row.
17
- import { OWNER } from '@nervur-org/nervur';
18
- import { dial } from '@nervur-org/nervur/harbor';
17
+ import { OWNER } from 'nervur';
18
+ import { dial } from 'nervur/harbor';
19
19
  import { Faculty } from './faculty.js';
20
20
  // The name the dock ward holds her under.
21
21
  export const DIALERS = 'dialers';
@@ -1,5 +1,5 @@
1
- import { Being } from '@nervur-org/nervur';
2
- import type { Asker, JsonObject } from '@nervur-org/nervur';
1
+ import { Being } from 'nervur';
2
+ import type { Asker, JsonObject } from 'nervur';
3
3
  export type Watched = {
4
4
  by: string;
5
5
  method: string;
@@ -17,7 +17,7 @@
17
17
  // connection, the interval, the worker, the route are opened in her
18
18
  // constructor, and she is born whether or not the thing is reachable,
19
19
  // answering an error object while it is not.
20
- import { Being, isInvitation, isSilence, isWord, wordOf } from '@nervur-org/nervur';
20
+ import { Being, isInvitation, isSilence, isWord, wordOf } from 'nervur';
21
21
  export class Faculty extends Being {
22
22
  static cells = { watched: {}, minted: 0 };
23
23
  // Someone wants waking. She hands the invitation she minted and says what
@@ -17,7 +17,7 @@ export type Tokens = {
17
17
  token_type: 'Bearer';
18
18
  expires_in: number;
19
19
  refresh_token: string;
20
- scope: 'quo';
20
+ scope: 'nervur';
21
21
  };
22
22
  export declare class Grants extends Faculty {
23
23
  static cells: {
@@ -57,7 +57,7 @@ export class Grants extends Faculty {
57
57
  this.kept.refresh[refresh_token] = { identity, ward, client, exp: this.now() + REFRESH_TTL };
58
58
  this.sweep();
59
59
  await this.persist();
60
- return { access_token, token_type: 'Bearer', expires_in: ACCESS_TTL / 1000, refresh_token, scope: 'quo' };
60
+ return { access_token, token_type: 'Bearer', expires_in: ACCESS_TTL / 1000, refresh_token, scope: 'nervur' };
61
61
  }
62
62
  // Rotated: the old one is gone with the new one's birth. Null is a token
63
63
  // nobody issued, or one that died.
@@ -21,7 +21,7 @@ import { HOSTS, answered, provider, request } from './apns.js';
21
21
  // which app is being rung. A box holding none is a box that rings no
22
22
  // iPhones, which is every box but a bell's.
23
23
  export function apnsOf(env) {
24
- const { QUO_APNS_KEY: key, QUO_APNS_KEY_ID: keyId, QUO_APNS_TEAM: teamId, QUO_APNS_TOPIC: topic } = env;
24
+ const { NERVUR_APNS_KEY: key, NERVUR_APNS_KEY_ID: keyId, NERVUR_APNS_TEAM: teamId, NERVUR_APNS_TOPIC: topic } = env;
25
25
  return key && keyId && teamId && topic ? { key, keyId, teamId, topic } : null;
26
26
  }
27
27
  // How long a ring waits on Apple before it is a ring that did not leave. A
@@ -1,4 +1,4 @@
1
- import type { Harbor, Lend } from '@nervur-org/nervur/harbor';
1
+ import type { Harbor, Lend } from 'nervur/harbor';
2
2
  import { Faculty } from './faculty.ts';
3
3
  import { Console } from './console.ts';
4
4
  import { Local } from './local.ts';
@@ -1,4 +1,4 @@
1
- import { isInvitation } from '@nervur-org/nervur';
1
+ import { isInvitation } from 'nervur';
2
2
  import { Faculty } from './faculty.js';
3
3
  import { Console, CONSOLE } from './console.js';
4
4
  import { Local } from './local.js';
@@ -1,11 +1,11 @@
1
1
  import { Faculty } from './faculty.ts';
2
- import type { JsonObject } from '@nervur-org/nervur';
2
+ import type { JsonObject } from 'nervur';
3
3
  import { type Verified } from '../beings/way.ts';
4
4
  export declare const LOCAL = "local";
5
5
  export declare class Local extends Faculty {
6
6
  #private;
7
7
  static asks: {
8
- verify: import("@nervur-org/nervur").AskSpec;
8
+ verify: import("nervur").AskSpec;
9
9
  };
10
10
  mint(nonce: string, who: Verified): void;
11
11
  drop(nonce: string): void;
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from '@nervur-org/nervur';
1
+ import type { JsonObject } from 'nervur';
2
2
  import { Faculty } from './faculty.ts';
3
3
  export type Where = {
4
4
  lat: number;
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from '@nervur-org/nervur';
1
+ import type { JsonObject } from 'nervur';
2
2
  import { Faculty } from './faculty.ts';
3
3
  export declare class Notifications extends Faculty {
4
4
  static cells: JsonObject;
@@ -21,7 +21,7 @@
21
21
  // is kept so that it never leaves the device at all. This one opens
22
22
  // banners, and if the process that draws them were ever turned against her
23
23
  // it would cost her a line of text rather than her world.
24
- import { arithmetic } from '@nervur-org/nervur/ward';
24
+ import { arithmetic } from 'nervur/ward';
25
25
  import { Faculty } from './faculty.js';
26
26
  // A key is thirty two bytes of the platform's own randomness, as every seed
27
27
  // in this kit is.
@@ -1,4 +1,4 @@
1
- import type { Asker, JsonObject, OccupantRecord } from '@nervur-org/nervur';
1
+ import type { Asker, JsonObject, OccupantRecord } from 'nervur';
2
2
  import { Faculty } from './faculty.ts';
3
3
  export type Token = {
4
4
  kind: string;
package/dist/dock/push.js CHANGED
@@ -12,8 +12,8 @@
12
12
  // The rings are live objects and not values, so they are not cells: a
13
13
  // terrain subclasses and builds its own in `rings`, out of what its
14
14
  // environment and this being's cells give it.
15
- import { OWNER } from '@nervur-org/nervur';
16
- import { arithmetic } from '@nervur-org/nervur/ward';
15
+ import { OWNER } from 'nervur';
16
+ import { arithmetic } from 'nervur/ward';
17
17
  import { Faculty } from './faculty.js';
18
18
  import { mintVapid } from './webpush.js';
19
19
  export const isToken = (v) => v !== null && typeof v === 'object' && !Array.isArray(v) && typeof v.kind === 'string';
@@ -38,7 +38,7 @@ export const SEAL = 4096;
38
38
  // object is shown as it is when they are not.
39
39
  export function banner(o) {
40
40
  const text = (v) => (typeof v === 'string' && v.trim() ? v.trim() : '');
41
- const title = text(o.title) || text(o.from) || 'quo';
41
+ const title = text(o.title) || text(o.from) || 'Nervur';
42
42
  const body = text(o.body) ||
43
43
  text(o.said) ||
44
44
  Object.entries(o)
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // Why there is one at all. Apple and Google accept a push only when it is
7
7
  // signed with the key of the team that published the app, so a world's
8
- // droplet cannot ring the Quo app however much its human wants it to: the
8
+ // droplet cannot ring the Nervur app however much its human wants it to: the
9
9
  // key belongs to whoever publishes the app and to nobody else. So a world's
10
10
  // world hands the ring on, a token and a sealed banner, to a service the
11
11
  // publisher runs. It is the one server the app has. An estate that ships
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from '@nervur-org/nervur';
1
+ import type { JsonObject } from 'nervur';
2
2
  import { Faculty, type Woke } from './faculty.ts';
3
3
  export declare class Timer extends Faculty {
4
4
  #private;