@nestor-home/satellite 0.1.0 → 0.3.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 (44) hide show
  1. package/README.md +17 -108
  2. package/dist/codes.d.ts +3 -3
  3. package/dist/codes.js +2 -2
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/node/cli.d.ts +2 -2
  7. package/dist/node/cli.js +3 -3
  8. package/dist/node/env.d.ts +1 -1
  9. package/dist/node/env.js +1 -1
  10. package/dist/node/tokens.js +1 -1
  11. package/dist/node/tokens.js.map +1 -1
  12. package/dist/pairing.d.ts +2 -2
  13. package/dist/pairing.js +1 -1
  14. package/dist/protocol.d.ts +3 -3
  15. package/dist/protocol.js +3 -3
  16. package/dist/satellite.d.ts +2 -2
  17. package/dist/satellite.js +1 -1
  18. package/dist/version.d.ts +1 -1
  19. package/dist/version.js +1 -1
  20. package/package.json +3 -3
  21. package/schemas/ack.json +2 -2
  22. package/schemas/hello.json +2 -2
  23. package/schemas/intent.beat.json +2 -2
  24. package/schemas/intent.behavior.json +2 -2
  25. package/schemas/intent.expression.json +2 -2
  26. package/schemas/intent.identify.json +2 -2
  27. package/schemas/manifest.json +3 -3
  28. package/schemas/observation.person.detected.json +2 -2
  29. package/schemas/observation.speech.activity.json +2 -2
  30. package/schemas/pairing.enrollment.json +2 -2
  31. package/schemas/pairing.error.json +2 -2
  32. package/schemas/pairing.request.json +2 -2
  33. package/schemas/pairing.state.json +2 -2
  34. package/schemas/pairing.ticket.json +2 -2
  35. package/schemas/welcome.json +2 -2
  36. package/src/codes.ts +3 -3
  37. package/src/index.ts +1 -1
  38. package/src/node/cli.ts +3 -3
  39. package/src/node/env.ts +1 -1
  40. package/src/node/tokens.ts +1 -1
  41. package/src/pairing.ts +2 -2
  42. package/src/protocol.ts +3 -3
  43. package/src/satellite.ts +2 -2
  44. package/src/version.ts +1 -1
package/README.md CHANGED
@@ -1,93 +1,19 @@
1
1
  # @nestor-home/satellite
2
2
 
3
- TypeScript SDK to write **satellites** for [Nestor](https://github.com/nestor-home/nestor), in
4
- browsers and in Node: devices (a tab on a wall tablet, a Raspberry Pi speaker, a robot) that pair
5
- with a Nestor core, stream audio over WebRTC, carry out the core's intents and report what they
6
- observe, following the `nestor.satellite/2` protocol. The SDK does not depend on the Nestor server.
3
+ TypeScript SDK to write **satellites** for [Nestor](https://nestorhome.dev), in browsers and in
4
+ Node: devices (a tab on a wall tablet, a Raspberry Pi speaker, a robot) that pair with a Nestor
5
+ server, stream audio over WebRTC, carry out its intents and report what they observe, following the
6
+ `nestor.satellite/1` protocol. It does not depend on the Nestor server.
7
7
 
8
- ## Pairing
9
-
10
- A person pairs a satellite from Nestor's admin, with one of two proofs:
11
-
12
- - an **enrollment code** (`K7QF-2M9X`, or the pairing URI `nestor+http://nestor.local:7860/?code=K7QF2M9X`)
13
- made in the admin and handed to the device: set in its configuration, typed on it, or scanned;
14
- - a **device code** (6 digits) the device presents, on its screen, aloud or in its log, and the
15
- person types in the admin.
16
-
17
- The SDK uses the enrollment code it is given; otherwise it asks for a device code and presents it
18
- through every output the driver provides, and always in the log. While it waits, `satellite.enroll()`
19
- still takes an enrollment code; whichever proof the core accepts first wins. A refused enrollment code
20
- is never sent again, even after a restart: its SHA-256 hash is kept in the token store, never the code.
21
-
22
- The manifest's `pairing_methods` follow from what the device can do, never declared by hand:
23
-
24
- | Method | When |
25
- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
- | `enrollment.provisioning` | always |
27
- | `device_code.display` | `pairing.display` is given |
28
- | `device_code.speech` | `pairing.speak` is given, or the device has a speaker (`audio.playback`) and no `display`: the SDK then says the code itself, offline, with recorded clips (`pairing.voice: true` to also do it with a screen) |
29
- | `enrollment.input` | `pairing.accepts: ["enrollment.input"]` |
30
- | `enrollment.qr` | `pairing.scanner` reads QR codes with a camera (`@nestor-home/satellite/qr`, browsers) |
31
-
32
- What the device says to people is translated (English and French, Fluent catalogues): `locale`
33
- option, else the platform's language. The bundled voice has English and French clips; another
34
- language is said in English.
35
-
36
- ## In Node, headless
37
-
38
- `pnpm add @nestor-home/satellite @roamhq/wrtc`. Add a satellite in Nestor with an enrollment code, and
39
- hand its pairing URI to the device:
8
+ **Documentation:** [nestorhome.dev/docs/sdks/typescript](https://nestorhome.dev/docs/sdks/typescript/)
9
+ (Node, pairing options, QR codes, the command, conformance).
40
10
 
41
11
  ```bash
42
- NESTOR_PAIRING_URI='nestor+http://nestor.local:7860/?code=K7QF2M9X' npx @nestor-home/satellite run --room salon
43
- # or
44
- npx @nestor-home/satellite run --room salon --pairing-uri 'nestor+http://nestor.local:7860/?code=K7QF2M9X'
45
- ```
46
-
47
- The URI gives the core's address; with a bare code (`--pairing-code K7QF-2M9X`, or
48
- `NESTOR_PAIRING_CODE`), give it with `--core`. Without either, the satellite says a device code to
49
- type in Nestor on its speaker, and logs it (`--output none`: only logs it). The token is kept in `~/.config/nestor-satellite/<id>.json` (mode 600); see
50
- `nestor-satellite --help`.
51
-
52
- The same in code:
53
-
54
- ```ts
55
- import { AUDIO_CAPTURE, AUDIO_PLAYBACK, EXPRESSION, Manifest, Satellite } from "@nestor-home/satellite";
56
- import {
57
- CommandSink,
58
- CommandSource,
59
- FileTokenStore,
60
- languagesFromEnv,
61
- nodeWebRtc,
62
- provisioningFromEnv,
63
- } from "@nestor-home/satellite/node";
64
-
65
- const provisioning = provisioningFromEnv(); // NESTOR_PAIRING_URI or NESTOR_PAIRING_CODE, if set
66
- const satellite = new Satellite({
67
- core: provisioning?.core ?? "http://nestor.local:7860",
68
- manifest: Manifest.of(
69
- { id: "enceinte-salon", model: "raspberry-pi-4", room: "salon" },
70
- AUDIO_CAPTURE,
71
- AUDIO_PLAYBACK,
72
- EXPRESSION,
73
- ),
74
- tokens: new FileTokenStore("~/.config/salon.json"), // mode 600
75
- webrtc: nodeWebRtc({
76
- source: new CommandSource("arecord -q -t raw -f S16_LE -c 1 -r 48000"),
77
- sink: new CommandSink("aplay -q -t raw -f S16_LE -c 1 -r 48000"),
78
- }),
79
- pairing: { enrollment: provisioning?.enrollment }, // no screen: the device code is said on the sink, and logged
80
- locale: languagesFromEnv(), // LC_ALL, LC_MESSAGES, LANG
81
- body: { expression: (expression) => console.log("expression:", expression) },
82
- });
83
- const stop = new AbortController();
84
- process.once("SIGINT", () => stop.abort());
85
- await satellite.run(stop.signal); // pairs the first time, then reconnects forever
12
+ pnpm add @nestor-home/satellite
13
+ pnpm add @roamhq/wrtc # in Node only
86
14
  ```
87
15
 
88
- ## In a browser, with a screen
89
-
90
- Served over `https:` or `localhost`, from the core's origin or through a proxy:
16
+ A tab as a satellite:
91
17
 
92
18
  ```ts
93
19
  import {
@@ -99,8 +25,6 @@ import {
99
25
  Manifest,
100
26
  Satellite,
101
27
  } from "@nestor-home/satellite";
102
- import { cameraQrScanner } from "@nestor-home/satellite/qr"; // needs `pnpm add zxing-wasm`
103
- import wasmUrl from "zxing-wasm/reader/zxing_reader.wasm?url"; // Vite: served by the page, not a CDN
104
28
 
105
29
  const satellite = new Satellite({
106
30
  core: location.origin,
@@ -113,50 +37,35 @@ const satellite = new Satellite({
113
37
  tokens: new LocalStorageTokenStore(),
114
38
  webrtc: browserWebRtc(),
115
39
  pairing: {
116
- // The device code and what to do with it; `code` is null once it is no longer needed.
40
+ // the device code to type in Nestor; `code` is null once it is no longer needed
117
41
  display: (code, text) => {
118
42
  document.querySelector("#code")!.textContent = code ?? "";
119
43
  document.querySelector("#status")!.textContent = text;
120
44
  },
121
- voice: true, // optional: says the code aloud too, with the bundled voice (Web Audio)
122
- accepts: ["enrollment.input"], // an enrollment code can be typed in the page
123
- scanner: cameraQrScanner({ wasmUrl }), // optional: reads the pairing URI's QR code with the camera
124
45
  },
125
46
  body: {
126
47
  behavior: (behavior) => (document.body.dataset.behavior = behavior),
127
48
  identify: () => document.body.animate([{ opacity: 0.2 }, { opacity: 1 }], { duration: 500, iterations: 6 }),
128
49
  },
129
50
  });
130
- form.onsubmit = async () => console.log(await satellite.enroll(input.value)); // approved, refused…
131
51
  button.onclick = () => satellite.run(); // a click: browsers only play sound after a gesture
132
52
  ```
133
53
 
134
- A tab as a satellite: `NESTOR_CORE=http://nestor.local:7860 pnpm example`, then open the page
135
- (`?pairing_uri=…` pairs it with an enrollment code, `?lang=fr` speaks French, `?speak` says the code,
136
- `?qr` scans QR codes).
137
-
138
- QR codes are decoded by [`zxing-wasm`](https://github.com/Sec-ant/zxing-wasm) (ZXing-C++ in
139
- WebAssembly, MIT, an optional peer dependency; its reader is about 1 MB of WebAssembly, fetched from
140
- jsDelivr unless `wasmUrl` says where the page serves it). Node has no camera, so a Node satellite never
141
- declares `enrollment.qr`.
54
+ In Node, the machine's microphone and speaker, with nothing to write:
142
55
 
143
- ## The bundled voice
144
-
145
- `voice/` holds the clips the SDK says a device code with (16 kHz mono WAV, about 500 KB), identical in
146
- the Python SDK, which records them with Kokoro-82M. They are shared under CC BY 4.0: see
147
- [`voice/LICENSE`](voice/LICENSE) for the attribution. A driver with a voice of its own passes
148
- `pairing.speak`, which gets the whole sentence.
56
+ ```bash
57
+ NESTOR_PAIRING_URI='nestor+http://nestor.local:8471/?code=K7QF2M9X' npx nestor-satellite run --room salon
58
+ ```
149
59
 
150
- In Node, WebRTC is [`@roamhq/wrtc`](https://github.com/WonderInventions/node-webrtc), an optional
151
- peer dependency: libwebrtc, as in browsers, with Opus and RTCP built in, prebuilt for Linux and
152
- macOS (x64, arm64) and Windows x64.
60
+ The recorded voice that says device codes is shared under CC BY 4.0: see
61
+ [`voice/LICENSE`](voice/LICENSE).
153
62
 
154
63
  ## Development
155
64
 
156
65
  ```bash
157
66
  pnpm install
158
67
  pnpm lint && pnpm typecheck && pnpm test
159
- pnpm conformance # the server's conformance suite; needs ../nestor with its venv
68
+ pnpm conformance # the published server's conformance suite (uvx; version in .nestor-version)
160
69
  ```
161
70
 
162
71
  ## License
package/dist/codes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The codes of `nestor.satellite/2` pairing, and the pairing URI that carries an enrollment code.
2
+ * The codes of `nestor.satellite/1` pairing, and the pairing URI that carries an enrollment code.
3
3
  *
4
4
  * Device code: 6 decimal digits the core gives the device, which presents them (screen, voice, log)
5
5
  * for a person to type in the admin.
@@ -8,7 +8,7 @@
8
8
  * the device (configured, typed or scanned). Reading one back forgives case, dashes, spaces and the
9
9
  * letters Crockford maps to digits (O → 0, I and L → 1).
10
10
  *
11
- * Pairing URI: `nestor+http://nestor.local:7860/?code=K7QF2M9X`, the core's base URL prefixed with
11
+ * Pairing URI: `nestor+http://nestor.local:8471/?code=K7QF2M9X`, the core's base URL prefixed with
12
12
  * `nestor+`, and the enrollment code.
13
13
  */
14
14
  /** Crockford's base32: no I, L, O, U. */
@@ -20,7 +20,7 @@ export declare function normalizeEnrollmentCode(text: string): string | null;
20
20
  /** How an enrollment code is shown to people: `K7QF-2M9X`. */
21
21
  export declare function groupEnrollmentCode(code: string): string;
22
22
  export interface PairingUri {
23
- /** The core's base URL, e.g. `http://nestor.local:7860`. */
23
+ /** The core's base URL, e.g. `http://nestor.local:8471`. */
24
24
  readonly core: string;
25
25
  /** The enrollment code, canonical form. */
26
26
  readonly code: string;
package/dist/codes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The codes of `nestor.satellite/2` pairing, and the pairing URI that carries an enrollment code.
2
+ * The codes of `nestor.satellite/1` pairing, and the pairing URI that carries an enrollment code.
3
3
  *
4
4
  * Device code: 6 decimal digits the core gives the device, which presents them (screen, voice, log)
5
5
  * for a person to type in the admin.
@@ -8,7 +8,7 @@
8
8
  * the device (configured, typed or scanned). Reading one back forgives case, dashes, spaces and the
9
9
  * letters Crockford maps to digits (O → 0, I and L → 1).
10
10
  *
11
- * Pairing URI: `nestor+http://nestor.local:7860/?code=K7QF2M9X`, the core's base URL prefixed with
11
+ * Pairing URI: `nestor+http://nestor.local:8471/?code=K7QF2M9X`, the core's base URL prefixed with
12
12
  * `nestor+`, and the enrollment code.
13
13
  */
14
14
  import { ProtocolError } from "./protocol.js";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Write a Nestor satellite in TypeScript: pair with the core, stream audio over WebRTC, carry out
3
- * its intents and report observations, following the `nestor.satellite/2` protocol.
3
+ * its intents and report observations, following the `nestor.satellite/1` protocol.
4
4
  *
5
5
  * This entry point runs anywhere (browsers, Node, workers): it touches no platform API until a
6
6
  * `WebRtc` adapter does. Node's adapter, audio and token file live in `@nestor-home/satellite/node`.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Write a Nestor satellite in TypeScript: pair with the core, stream audio over WebRTC, carry out
3
- * its intents and report observations, following the `nestor.satellite/2` protocol.
3
+ * its intents and report observations, following the `nestor.satellite/1` protocol.
4
4
  *
5
5
  * This entry point runs anywhere (browsers, Node, workers): it touches no platform API until a
6
6
  * `WebRtc` adapter does. Node's adapter, audio and token file live in `@nestor-home/satellite/node`.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * `nestor-satellite run`: this machine's microphone and speaker as a satellite of a Nestor core.
3
3
  *
4
- * nestor-satellite run --core http://nestor.local:7860 --room salon
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X nestor-satellite run --room salon
4
+ * nestor-satellite run --core http://nestor.local:8471 --room salon
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X nestor-satellite run --room salon
6
6
  *
7
7
  * With an enrollment code (`--pairing-uri`, `--pairing-code`, or the same in `NESTOR_PAIRING_URI`,
8
8
  * `NESTOR_PAIRING_CODE`), the first run pairs at once; without one, it says a device code to type in
package/dist/node/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * `nestor-satellite run`: this machine's microphone and speaker as a satellite of a Nestor core.
3
3
  *
4
- * nestor-satellite run --core http://nestor.local:7860 --room salon
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X nestor-satellite run --room salon
4
+ * nestor-satellite run --core http://nestor.local:8471 --room salon
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X nestor-satellite run --room salon
6
6
  *
7
7
  * With an enrollment code (`--pairing-uri`, `--pairing-code`, or the same in `NESTOR_PAIRING_URI`,
8
8
  * `NESTOR_PAIRING_CODE`), the first run pairs at once; without one, it says a device code to type in
@@ -27,7 +27,7 @@ const USAGE = `Usage: nestor-satellite run --core <url> --room <room> [options]
27
27
  Run this machine's microphone and speaker as a Nestor satellite.
28
28
 
29
29
  Options:
30
- --core <url> the core's voice server, e.g. http://nestor.local:7860
30
+ --core <url> the core's voice server, e.g. http://nestor.local:8471
31
31
  (required unless a pairing URI gives it)
32
32
  --room <slug> the room the satellite is in: salon, cuisine… (required)
33
33
  --pairing-uri <uri> pair with this pairing URI, made in Nestor when adding a satellite:
@@ -2,7 +2,7 @@
2
2
  * What a headless device reads from its environment (P1): the pairing URI or the enrollment code a
3
3
  * person configured, and the language to speak to people in.
4
4
  *
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X the core and the code
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X the core and the code
6
6
  * NESTOR_PAIRING_CODE=K7QF-2M9X the code (the core given apart)
7
7
  */
8
8
  export declare const PAIRING_URI_ENV = "NESTOR_PAIRING_URI";
package/dist/node/env.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * What a headless device reads from its environment (P1): the pairing URI or the enrollment code a
3
3
  * person configured, and the language to speak to people in.
4
4
  *
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X the core and the code
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X the core and the code
6
6
  * NESTOR_PAIRING_CODE=K7QF-2M9X the code (the core given apart)
7
7
  */
8
8
  import { normalizeEnrollmentCode, parsePairingUri } from "../codes.js";
@@ -44,7 +44,7 @@ export class FileTokenStore {
44
44
  }
45
45
  await mkdir(dirname(this.path), { recursive: true, mode: 0o700 });
46
46
  await writeFile(this.path, text, { mode: 0o600 });
47
- await chmod(this.path, 0o600); // an older file may have been more open
47
+ await chmod(this.path, 0o600); // whoever made the file, only its owner reads it
48
48
  }
49
49
  }
50
50
  //# sourceMappingURL=tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/node/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/node/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAoB,SAAS,EAAqB,SAAS,EAAmB,UAAU,EAAE,MAAM,cAAc,CAAC;AAGtH;;;GAGG;AACH,MAAM,OAAO,cAAc;IAChB,IAAI,CAAS;IAEtB,YAAY,IAAY;QACtB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,QAAgB;QACvC,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAa;QACtD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,QAAgB;QAC1C,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,QAAgB,EAAE,IAAY,EAAE,MAAqB;QAC9E,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9G,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,QAAgB,EAAE,MAA2C;QAC9F,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,IAAmB;QACrC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,iDAAiD;IAClF,CAAC;CACF"}
package/dist/pairing.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pairing (`nestor.satellite/2`, rules P1 to P7): get a token from the core with either proof.
2
+ * Pairing (`nestor.satellite/1`, rules P1 to P7): get a token from the core with either proof.
3
3
  *
4
4
  * POST /satellites/pairings manifest [+ enrollment code] → ticket
5
5
  * POST /satellites/pairings/{pairing_id}/enrollment enrollment code → state
@@ -84,7 +84,7 @@ export type EnrollOutcome =
84
84
  readonly status: "invalid";
85
85
  };
86
86
  export interface PairingOptions {
87
- /** The core's base URL, e.g. `http://nestor.local:7860`. */
87
+ /** The core's base URL, e.g. `http://nestor.local:8471`. */
88
88
  readonly core: string;
89
89
  /** Sent with each request; its `pairing_methods` must match what this pairing can do. */
90
90
  readonly manifest: Manifest;
package/dist/pairing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pairing (`nestor.satellite/2`, rules P1 to P7): get a token from the core with either proof.
2
+ * Pairing (`nestor.satellite/1`, rules P1 to P7): get a token from the core with either proof.
3
3
  *
4
4
  * POST /satellites/pairings manifest [+ enrollment code] → ticket
5
5
  * POST /satellites/pairings/{pairing_id}/enrollment enrollment code → state
@@ -1,9 +1,9 @@
1
1
  /**
2
- * The values of the satellite protocol `nestor.satellite/2`: a device, what it can do, how it can
2
+ * The values of the satellite protocol `nestor.satellite/1`: a device, what it can do, how it can
3
3
  * be paired, and the intents it receives. They mirror the JSON Schemas shipped in `schemas/`,
4
4
  * published by the server.
5
5
  */
6
- export declare const PROTOCOL = "nestor.satellite/2";
6
+ export declare const PROTOCOL = "nestor.satellite/1";
7
7
  export declare const AUDIO_CAPTURE = "audio.capture";
8
8
  export declare const AUDIO_PLAYBACK = "audio.playback";
9
9
  export declare const EXPRESSION = "expression.emotion";
@@ -29,7 +29,7 @@ export type PairingMethod = (typeof PAIRING_METHODS)[number];
29
29
  /** The methods that bring an enrollment code to the device. */
30
30
  export declare const ENROLLMENT_METHODS: readonly ["enrollment.input", "enrollment.provisioning", "enrollment.qr"];
31
31
  export type EnrollmentMethod = (typeof ENROLLMENT_METHODS)[number];
32
- /** Something that does not follow `nestor.satellite/2`. */
32
+ /** Something that does not follow `nestor.satellite/1`. */
33
33
  export declare class ProtocolError extends Error {
34
34
  name: string;
35
35
  }
package/dist/protocol.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
- * The values of the satellite protocol `nestor.satellite/2`: a device, what it can do, how it can
2
+ * The values of the satellite protocol `nestor.satellite/1`: a device, what it can do, how it can
3
3
  * be paired, and the intents it receives. They mirror the JSON Schemas shipped in `schemas/`,
4
4
  * published by the server.
5
5
  */
6
6
  import { SDK_NAME, SDK_VERSION } from "./version.js";
7
- export const PROTOCOL = "nestor.satellite/2";
7
+ export const PROTOCOL = "nestor.satellite/1";
8
8
  // Capabilities the core knows today; a driver may declare others (`family.feature`).
9
9
  export const AUDIO_CAPTURE = "audio.capture";
10
10
  export const AUDIO_PLAYBACK = "audio.playback";
@@ -36,7 +36,7 @@ export const PAIRING_METHODS = [
36
36
  ];
37
37
  /** The methods that bring an enrollment code to the device. */
38
38
  export const ENROLLMENT_METHODS = ["enrollment.input", "enrollment.provisioning", "enrollment.qr"];
39
- /** Something that does not follow `nestor.satellite/2`. */
39
+ /** Something that does not follow `nestor.satellite/1`. */
40
40
  export class ProtocolError extends Error {
41
41
  name = "ProtocolError";
42
42
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * A satellite's life: pair once, then stay connected to the core, reconnecting when the link drops.
3
3
  *
4
- * const satellite = new Satellite({ core: "http://nestor.local:7860", manifest, tokens, webrtc, body });
4
+ * const satellite = new Satellite({ core: "http://nestor.local:8471", manifest, tokens, webrtc, body });
5
5
  * await satellite.run(signal); // until the signal aborts
6
6
  *
7
7
  * Pairing (`./pairing.ts`) uses the enrollment code it was configured with, else presents its device
@@ -61,7 +61,7 @@ export interface PairingSetup extends Omit<PairingOutputs, "voice"> {
61
61
  readonly pollMs?: number;
62
62
  }
63
63
  export interface SatelliteOptions {
64
- /** The core's voice server, e.g. `http://nestor.local:7860`. */
64
+ /** The core's voice server, e.g. `http://nestor.local:8471`. */
65
65
  readonly core: string;
66
66
  /** What the device is and can do; its `pairing_methods` are set from `pairing`. */
67
67
  readonly manifest: Manifest;
package/dist/satellite.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * A satellite's life: pair once, then stay connected to the core, reconnecting when the link drops.
3
3
  *
4
- * const satellite = new Satellite({ core: "http://nestor.local:7860", manifest, tokens, webrtc, body });
4
+ * const satellite = new Satellite({ core: "http://nestor.local:8471", manifest, tokens, webrtc, body });
5
5
  * await satellite.run(signal); // until the signal aborts
6
6
  *
7
7
  * Pairing (`./pairing.ts`) uses the enrollment code it was configured with, else presents its device
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /** Sent in the manifest (`sdk`). release-please keeps the version equal to `package.json`. */
2
2
  export declare const SDK_NAME = "@nestor-home/satellite";
3
- export declare const SDK_VERSION = "0.1.0";
3
+ export declare const SDK_VERSION = "0.3.0";
4
4
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  /** Sent in the manifest (`sdk`). release-please keeps the version equal to `package.json`. */
2
2
  export const SDK_NAME = "@nestor-home/satellite";
3
- export const SDK_VERSION = "0.1.0"; // x-release-please-version
3
+ export const SDK_VERSION = "0.3.0"; // x-release-please-version
4
4
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestor-home/satellite",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript SDK to write Nestor satellites, in browsers and in Node: pairing, WebRTC audio and the nestor data channel.",
5
5
  "keywords": [
6
6
  "nestor",
@@ -9,7 +9,7 @@
9
9
  "webrtc",
10
10
  "home automation"
11
11
  ],
12
- "homepage": "https://nestor.mathislambert.fr",
12
+ "homepage": "https://nestorhome.dev",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git+https://github.com/nestor-home/nestor-satellite-typescript.git"
@@ -41,7 +41,7 @@
41
41
  "./package.json": "./package.json"
42
42
  },
43
43
  "bin": {
44
- "nestor-satellite": "./dist/node/bin.js"
44
+ "nestor-satellite": "dist/node/bin.js"
45
45
  },
46
46
  "files": [
47
47
  "dist",
package/schemas/ack.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/ack.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/ack.json",
4
4
  "title": "The intent `of` was received (carrying it out is the device's business).",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_core",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/hello.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/hello.json",
4
4
  "title": "First message of a connection: the device's manifest (its id must be the paired one).",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_core",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/intent.beat.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/intent.beat.json",
4
4
  "title": "A word is being played: a light speech accent.",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_satellite",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/intent.behavior.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/intent.behavior.json",
4
4
  "title": "The assistant's attitude changed: show it until the next one.",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_satellite",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/intent.expression.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/intent.expression.json",
4
4
  "title": "An expression, sent as the matching audio is played (a laugh when the laugh is heard).",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_satellite",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/intent.identify.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/intent.identify.json",
4
4
  "title": "A person asks the device to make itself noticed for a few seconds (blink, wiggle, chime).",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_satellite",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/manifest.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/manifest.json",
4
4
  "title": "Satellite manifest",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "protocol": {
9
- "const": "nestor.satellite/2"
9
+ "const": "nestor.satellite/1"
10
10
  },
11
11
  "device": {
12
12
  "type": "object",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/observation.person.detected.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/observation.person.detected.json",
4
4
  "title": "People seen by the device's own detector, now (no image leaves the device).",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_core",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/observation.speech.activity.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/observation.speech.activity.json",
4
4
  "title": "Voice activity detected on the device started (`active`) or stopped.",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_core",
7
7
  "type": "object",
8
8
  "properties": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/pairing.enrollment.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/pairing.enrollment.json",
4
4
  "title": "POST /satellites/pairings/{pairing_id}/enrollment: a pending device's code",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "enrollment_code": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/pairing.error.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/pairing.error.json",
4
4
  "title": "Error answer of the pairing endpoints",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "error": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/pairing.request.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/pairing.request.json",
4
4
  "title": "POST /satellites/pairings: a device asks to pair",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "manifest": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/pairing.state.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/pairing.state.json",
4
4
  "title": "GET /satellites/pairings/{pairing_id}: where a pairing stands",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "status": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/pairing.ticket.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/pairing.ticket.json",
4
4
  "title": "201 answer to a pairing request",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "type": "object",
7
7
  "properties": {
8
8
  "pairing_id": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://nestor.mathislambert.fr/schemas/satellite/2/welcome.json",
3
+ "$id": "https://nestorhome.dev/schemas/satellite/1/welcome.json",
4
4
  "title": "Answer to `hello`: where the device is and what it was allowed to do.",
5
- "x-protocol": "nestor.satellite/2",
5
+ "x-protocol": "nestor.satellite/1",
6
6
  "x-direction": "to_satellite",
7
7
  "type": "object",
8
8
  "properties": {
package/src/codes.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The codes of `nestor.satellite/2` pairing, and the pairing URI that carries an enrollment code.
2
+ * The codes of `nestor.satellite/1` pairing, and the pairing URI that carries an enrollment code.
3
3
  *
4
4
  * Device code: 6 decimal digits the core gives the device, which presents them (screen, voice, log)
5
5
  * for a person to type in the admin.
@@ -8,7 +8,7 @@
8
8
  * the device (configured, typed or scanned). Reading one back forgives case, dashes, spaces and the
9
9
  * letters Crockford maps to digits (O → 0, I and L → 1).
10
10
  *
11
- * Pairing URI: `nestor+http://nestor.local:7860/?code=K7QF2M9X`, the core's base URL prefixed with
11
+ * Pairing URI: `nestor+http://nestor.local:8471/?code=K7QF2M9X`, the core's base URL prefixed with
12
12
  * `nestor+`, and the enrollment code.
13
13
  */
14
14
 
@@ -37,7 +37,7 @@ export function groupEnrollmentCode(code: string): string {
37
37
  }
38
38
 
39
39
  export interface PairingUri {
40
- /** The core's base URL, e.g. `http://nestor.local:7860`. */
40
+ /** The core's base URL, e.g. `http://nestor.local:8471`. */
41
41
  readonly core: string;
42
42
  /** The enrollment code, canonical form. */
43
43
  readonly code: string;
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Write a Nestor satellite in TypeScript: pair with the core, stream audio over WebRTC, carry out
3
- * its intents and report observations, following the `nestor.satellite/2` protocol.
3
+ * its intents and report observations, following the `nestor.satellite/1` protocol.
4
4
  *
5
5
  * This entry point runs anywhere (browsers, Node, workers): it touches no platform API until a
6
6
  * `WebRtc` adapter does. Node's adapter, audio and token file live in `@nestor-home/satellite/node`.
package/src/node/cli.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * `nestor-satellite run`: this machine's microphone and speaker as a satellite of a Nestor core.
3
3
  *
4
- * nestor-satellite run --core http://nestor.local:7860 --room salon
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X nestor-satellite run --room salon
4
+ * nestor-satellite run --core http://nestor.local:8471 --room salon
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X nestor-satellite run --room salon
6
6
  *
7
7
  * With an enrollment code (`--pairing-uri`, `--pairing-code`, or the same in `NESTOR_PAIRING_URI`,
8
8
  * `NESTOR_PAIRING_CODE`), the first run pairs at once; without one, it says a device code to type in
@@ -33,7 +33,7 @@ const USAGE = `Usage: nestor-satellite run --core <url> --room <room> [options]
33
33
  Run this machine's microphone and speaker as a Nestor satellite.
34
34
 
35
35
  Options:
36
- --core <url> the core's voice server, e.g. http://nestor.local:7860
36
+ --core <url> the core's voice server, e.g. http://nestor.local:8471
37
37
  (required unless a pairing URI gives it)
38
38
  --room <slug> the room the satellite is in: salon, cuisine… (required)
39
39
  --pairing-uri <uri> pair with this pairing URI, made in Nestor when adding a satellite:
package/src/node/env.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * What a headless device reads from its environment (P1): the pairing URI or the enrollment code a
3
3
  * person configured, and the language to speak to people in.
4
4
  *
5
- * NESTOR_PAIRING_URI=nestor+http://nestor.local:7860/?code=K7QF2M9X the core and the code
5
+ * NESTOR_PAIRING_URI=nestor+http://nestor.local:8471/?code=K7QF2M9X the core and the code
6
6
  * NESTOR_PAIRING_CODE=K7QF-2M9X the code (the core given apart)
7
7
  */
8
8
 
@@ -54,6 +54,6 @@ export class FileTokenStore implements TokenStore {
54
54
  }
55
55
  await mkdir(dirname(this.path), { recursive: true, mode: 0o700 });
56
56
  await writeFile(this.path, text, { mode: 0o600 });
57
- await chmod(this.path, 0o600); // an older file may have been more open
57
+ await chmod(this.path, 0o600); // whoever made the file, only its owner reads it
58
58
  }
59
59
  }
package/src/pairing.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pairing (`nestor.satellite/2`, rules P1 to P7): get a token from the core with either proof.
2
+ * Pairing (`nestor.satellite/1`, rules P1 to P7): get a token from the core with either proof.
3
3
  *
4
4
  * POST /satellites/pairings manifest [+ enrollment code] → ticket
5
5
  * POST /satellites/pairings/{pairing_id}/enrollment enrollment code → state
@@ -102,7 +102,7 @@ export type EnrollOutcome =
102
102
  | { readonly status: "invalid" };
103
103
 
104
104
  export interface PairingOptions {
105
- /** The core's base URL, e.g. `http://nestor.local:7860`. */
105
+ /** The core's base URL, e.g. `http://nestor.local:8471`. */
106
106
  readonly core: string;
107
107
  /** Sent with each request; its `pairing_methods` must match what this pairing can do. */
108
108
  readonly manifest: Manifest;
package/src/protocol.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
- * The values of the satellite protocol `nestor.satellite/2`: a device, what it can do, how it can
2
+ * The values of the satellite protocol `nestor.satellite/1`: a device, what it can do, how it can
3
3
  * be paired, and the intents it receives. They mirror the JSON Schemas shipped in `schemas/`,
4
4
  * published by the server.
5
5
  */
6
6
 
7
7
  import { SDK_NAME, SDK_VERSION } from "./version.js";
8
8
 
9
- export const PROTOCOL = "nestor.satellite/2";
9
+ export const PROTOCOL = "nestor.satellite/1";
10
10
 
11
11
  // Capabilities the core knows today; a driver may declare others (`family.feature`).
12
12
  export const AUDIO_CAPTURE = "audio.capture";
@@ -49,7 +49,7 @@ export type PairingMethod = (typeof PAIRING_METHODS)[number];
49
49
  export const ENROLLMENT_METHODS = ["enrollment.input", "enrollment.provisioning", "enrollment.qr"] as const;
50
50
  export type EnrollmentMethod = (typeof ENROLLMENT_METHODS)[number];
51
51
 
52
- /** Something that does not follow `nestor.satellite/2`. */
52
+ /** Something that does not follow `nestor.satellite/1`. */
53
53
  export class ProtocolError extends Error {
54
54
  override name = "ProtocolError";
55
55
  }
package/src/satellite.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * A satellite's life: pair once, then stay connected to the core, reconnecting when the link drops.
3
3
  *
4
- * const satellite = new Satellite({ core: "http://nestor.local:7860", manifest, tokens, webrtc, body });
4
+ * const satellite = new Satellite({ core: "http://nestor.local:8471", manifest, tokens, webrtc, body });
5
5
  * await satellite.run(signal); // until the signal aborts
6
6
  *
7
7
  * Pairing (`./pairing.ts`) uses the enrollment code it was configured with, else presents its device
@@ -91,7 +91,7 @@ export interface PairingSetup extends Omit<PairingOutputs, "voice"> {
91
91
  }
92
92
 
93
93
  export interface SatelliteOptions {
94
- /** The core's voice server, e.g. `http://nestor.local:7860`. */
94
+ /** The core's voice server, e.g. `http://nestor.local:8471`. */
95
95
  readonly core: string;
96
96
  /** What the device is and can do; its `pairing_methods` are set from `pairing`. */
97
97
  readonly manifest: Manifest;
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Sent in the manifest (`sdk`). release-please keeps the version equal to `package.json`. */
2
2
  export const SDK_NAME = "@nestor-home/satellite";
3
- export const SDK_VERSION = "0.1.0"; // x-release-please-version
3
+ export const SDK_VERSION = "0.3.0"; // x-release-please-version