@nestor-home/satellite 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -108
- package/dist/codes.d.ts +1 -1
- package/dist/codes.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pairing.d.ts +1 -1
- package/dist/pairing.js +1 -1
- package/dist/protocol.d.ts +3 -3
- package/dist/protocol.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/schemas/ack.json +2 -2
- package/schemas/hello.json +2 -2
- package/schemas/intent.beat.json +2 -2
- package/schemas/intent.behavior.json +2 -2
- package/schemas/intent.expression.json +2 -2
- package/schemas/intent.identify.json +2 -2
- package/schemas/manifest.json +3 -3
- package/schemas/observation.person.detected.json +2 -2
- package/schemas/observation.speech.activity.json +2 -2
- package/schemas/pairing.enrollment.json +2 -2
- package/schemas/pairing.error.json +2 -2
- package/schemas/pairing.request.json +2 -2
- package/schemas/pairing.state.json +2 -2
- package/schemas/pairing.ticket.json +2 -2
- package/schemas/welcome.json +2 -2
- package/src/codes.ts +1 -1
- package/src/index.ts +1 -1
- package/src/pairing.ts +1 -1
- package/src/protocol.ts +3 -3
- 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://
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
#
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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:7860/?code=K7QF2M9X' npx nestor-satellite run --room salon
|
|
58
|
+
```
|
|
149
59
|
|
|
150
|
-
|
|
151
|
-
|
|
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;
|
|
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
|
+
* 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.
|
package/dist/codes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The codes of `nestor.satellite/
|
|
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.
|
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/
|
|
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/
|
|
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/pairing.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pairing (`nestor.satellite/
|
|
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
|
package/dist/pairing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pairing (`nestor.satellite/
|
|
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
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The values of the satellite protocol `nestor.satellite/
|
|
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/
|
|
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/
|
|
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
|
+
* 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/
|
|
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/
|
|
39
|
+
/** Something that does not follow `nestor.satellite/1`. */
|
|
40
40
|
export class ProtocolError extends Error {
|
|
41
41
|
name = "ProtocolError";
|
|
42
42
|
}
|
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.
|
|
3
|
+
export declare const SDK_VERSION = "0.2.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.
|
|
3
|
+
export const SDK_VERSION = "0.2.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.
|
|
3
|
+
"version": "0.2.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://
|
|
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"
|
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://
|
|
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/
|
|
5
|
+
"x-protocol": "nestor.satellite/1",
|
|
6
6
|
"x-direction": "to_core",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
package/schemas/hello.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://
|
|
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/
|
|
5
|
+
"x-protocol": "nestor.satellite/1",
|
|
6
6
|
"x-direction": "to_core",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
package/schemas/intent.beat.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
5
|
+
"x-protocol": "nestor.satellite/1",
|
|
6
6
|
"x-direction": "to_satellite",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
package/schemas/manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://nestorhome.dev/schemas/satellite/1/manifest.json",
|
|
4
4
|
"title": "Satellite manifest",
|
|
5
|
-
"x-protocol": "nestor.satellite/
|
|
5
|
+
"x-protocol": "nestor.satellite/1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"protocol": {
|
|
9
|
-
"const": "nestor.satellite/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
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://
|
|
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/
|
|
5
|
+
"x-protocol": "nestor.satellite/1",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"pairing_id": {
|
package/schemas/welcome.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://
|
|
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/
|
|
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
|
+
* 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.
|
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/
|
|
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/pairing.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pairing (`nestor.satellite/
|
|
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
|
package/src/protocol.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The values of the satellite protocol `nestor.satellite/
|
|
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/
|
|
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/
|
|
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/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.
|
|
3
|
+
export const SDK_VERSION = "0.2.0"; // x-release-please-version
|