@bridgething/lib 0.1.2
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/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/bindings/client.d.ts +1904 -0
- package/dist/bindings/client.d.ts.map +1 -0
- package/dist/bindings/client.js +2 -0
- package/dist/bindings/client.js.map +1 -0
- package/dist/bindings/gateway.d.ts +1508 -0
- package/dist/bindings/gateway.d.ts.map +1 -0
- package/dist/bindings/gateway.js +2 -0
- package/dist/bindings/gateway.js.map +1 -0
- package/dist/bindings/shared.d.ts +1485 -0
- package/dist/bindings/shared.d.ts.map +1 -0
- package/dist/bindings/shared.js +3 -0
- package/dist/bindings/shared.js.map +1 -0
- package/dist/bindings/stock.d.ts +14 -0
- package/dist/bindings/stock.d.ts.map +1 -0
- package/dist/bindings/stock.js +3 -0
- package/dist/bindings/stock.js.map +1 -0
- package/dist/bindings/wire.d.ts +47 -0
- package/dist/bindings/wire.d.ts.map +1 -0
- package/dist/bindings/wire.js +3 -0
- package/dist/bindings/wire.js.map +1 -0
- package/dist/codec.d.ts +66 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +180 -0
- package/dist/codec.js.map +1 -0
- package/dist/framing.d.ts +34 -0
- package/dist/framing.d.ts.map +1 -0
- package/dist/framing.js +69 -0
- package/dist/framing.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +21 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +23 -0
- package/dist/logger.js.map +1 -0
- package/dist/uuid-fields.generated.d.ts +7 -0
- package/dist/uuid-fields.generated.d.ts.map +1 -0
- package/dist/uuid-fields.generated.js +15 -0
- package/dist/uuid-fields.generated.js.map +1 -0
- package/dist/uuid.d.ts +6 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +20 -0
- package/dist/uuid.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,1485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direction the accessory wants iOS to take when answering an incoming
|
|
3
|
+
* call while another call is active.
|
|
4
|
+
*/
|
|
5
|
+
export type AcceptCallAction = 'accept' | 'endAndAccept';
|
|
6
|
+
/**
|
|
7
|
+
* An album reference.
|
|
8
|
+
*/
|
|
9
|
+
export type Album = {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
/**
|
|
13
|
+
* Opaque artwork asset id (`asset.get`), when known.
|
|
14
|
+
*/
|
|
15
|
+
artwork_id: string | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Daemon-observed state of the ANCS GATT-client session against the
|
|
19
|
+
* connected iPhone. iOS-only; emitted on transitions so the companion
|
|
20
|
+
* app can confirm the LE-pair + ANCS authorization handshake completed.
|
|
21
|
+
*
|
|
22
|
+
* State machine:
|
|
23
|
+
* - `Unknown`: pre-boot only (no iAP2 has ever attached this session).
|
|
24
|
+
* - `Probing`: a session task is running but no determination yet,
|
|
25
|
+
* OR iAP2 just detached and we expect to re-probe on reconnect.
|
|
26
|
+
* - `Authorized`: ANCS attribute fetches are succeeding.
|
|
27
|
+
* - `Unauthorized`: ANCS service hidden, or auth-gate detected.
|
|
28
|
+
*/
|
|
29
|
+
export type AncsAuthState = 'unknown' | 'probing' | 'authorized' | 'unauthorized';
|
|
30
|
+
/**
|
|
31
|
+
* Art render sizes a webapp declares so the companion warms exactly the
|
|
32
|
+
* pixels it renders: hero (now-playing / detail views) and thumb (queue /
|
|
33
|
+
* grid). Omitted in a manifest falls back to the canonical `{248, 96}`,
|
|
34
|
+
* which is also the stock webapp's profile.
|
|
35
|
+
*/
|
|
36
|
+
export type ArtProfile = {
|
|
37
|
+
heroPx: number;
|
|
38
|
+
thumbPx: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* An artist reference.
|
|
42
|
+
*/
|
|
43
|
+
export type Artist = {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
/**
|
|
47
|
+
* Opaque artwork asset id (`asset.get`), when known.
|
|
48
|
+
*/
|
|
49
|
+
artwork_id: string | null;
|
|
50
|
+
};
|
|
51
|
+
export type AssetRetention = {
|
|
52
|
+
type: 'lru';
|
|
53
|
+
} | {
|
|
54
|
+
type: 'pinned';
|
|
55
|
+
} | {
|
|
56
|
+
type: 'ttl';
|
|
57
|
+
data: TtlRetention;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'persistent';
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* What the gateway-side audio backend supports. `earcons` are short
|
|
63
|
+
* named sounds the companion can play; `voices` are TTS voices.
|
|
64
|
+
*/
|
|
65
|
+
export type AudioCapabilities = {
|
|
66
|
+
earcons: Array<string>;
|
|
67
|
+
voices: Array<VoiceDescriptor>;
|
|
68
|
+
};
|
|
69
|
+
export type BoolField = {
|
|
70
|
+
key: string;
|
|
71
|
+
label: string;
|
|
72
|
+
default: boolean | null;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Bridge-side identity announce. Daemon sends one of these to every
|
|
76
|
+
* gateway on connect so the companion knows what daemon it's talking to
|
|
77
|
+
* and can opt out of unsupported surfaces.
|
|
78
|
+
*/
|
|
79
|
+
export type BridgeThingMeta = {
|
|
80
|
+
bridgethingVersion: string;
|
|
81
|
+
libbridgethingVersion: string;
|
|
82
|
+
appName: string;
|
|
83
|
+
/**
|
|
84
|
+
* User-set display name for this device. None when the user hasn't
|
|
85
|
+
* set one yet; consumers fall back to `model_name` / `serial_number`.
|
|
86
|
+
* Set via the gateway-side `system.device.setNickname` surface.
|
|
87
|
+
*/
|
|
88
|
+
nickname: string | null;
|
|
89
|
+
/**
|
|
90
|
+
* Daemon semver (no leading `v`), e.g. `0.8.4`. Compared directly to
|
|
91
|
+
* the manifest's daemon-component version for OTA hot-swap decisions.
|
|
92
|
+
*/
|
|
93
|
+
appVersion: string;
|
|
94
|
+
osName: string;
|
|
95
|
+
osVersion: string;
|
|
96
|
+
osDescription: string;
|
|
97
|
+
btMac: string;
|
|
98
|
+
serialNumber: string;
|
|
99
|
+
fccId: string;
|
|
100
|
+
icId: string;
|
|
101
|
+
modelName: string;
|
|
102
|
+
/**
|
|
103
|
+
* OTA channel the running image was cut on, e.g. `stable` or `dev`.
|
|
104
|
+
* The companion's poll loop only auto-pushes when its configured
|
|
105
|
+
* channel matches; a mismatch surfaces a "channel switch needs full
|
|
106
|
+
* flash" event rather than swapping channels in-band.
|
|
107
|
+
*/
|
|
108
|
+
channel: string;
|
|
109
|
+
/**
|
|
110
|
+
* Image variant the running image was cut as, e.g. `prod` or `dev`.
|
|
111
|
+
* Maps to the yocto image recipe name `bridgething-<variant>-image`,
|
|
112
|
+
* which is what the companion uses to construct the OTA artifact URL
|
|
113
|
+
* `images/<channel>/<image_version>/bridgething-<variant>-image.{swu,zck}`.
|
|
114
|
+
*/
|
|
115
|
+
imageVariant: string;
|
|
116
|
+
/**
|
|
117
|
+
* Canonical image version (CalVer, e.g. `2026.05.0`). What the
|
|
118
|
+
* companion compares to the manifest's image-component version.
|
|
119
|
+
*/
|
|
120
|
+
imageVersion: string;
|
|
121
|
+
imageBuildId: string;
|
|
122
|
+
imageBuildDate: string;
|
|
123
|
+
imageDistro: string;
|
|
124
|
+
imageMachine: string;
|
|
125
|
+
discord: string;
|
|
126
|
+
credits: string;
|
|
127
|
+
};
|
|
128
|
+
export type BrightnessMode = 'auto' | 'manual';
|
|
129
|
+
/**
|
|
130
|
+
* Backlight state. `level` is the user-set value (only respected in
|
|
131
|
+
* `Manual`); `effective_level` is what's actually on the panel - equal
|
|
132
|
+
* to `level` in `Manual`, ALS-derived in `Auto`.
|
|
133
|
+
*/
|
|
134
|
+
export type BrightnessState = {
|
|
135
|
+
mode: BrightnessMode;
|
|
136
|
+
level: number;
|
|
137
|
+
effectiveLevel: number;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* One row in a `BrowseResult`: either a folder (drilldown) or a leaf
|
|
141
|
+
* item the user can play / queue / favorite.
|
|
142
|
+
*/
|
|
143
|
+
export type BrowseEntry = {
|
|
144
|
+
type: 'folder';
|
|
145
|
+
data: BrowseFolder;
|
|
146
|
+
} | {
|
|
147
|
+
type: 'item';
|
|
148
|
+
data: LibraryItem;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* A drilldown node. `node_id` is opaque and gateway-defined; webapps
|
|
152
|
+
* pass it back as the next `browse({ node_id })` to descend. `total` is
|
|
153
|
+
* the count of children behind this folder when the gateway can cheaply
|
|
154
|
+
* expose it. `preview_children` is an inline first-N slice of those
|
|
155
|
+
* children so home-shelf shapes don't need a separate drill round-trip;
|
|
156
|
+
* gateways populate it when cheap (Spotify Web API home shelves include
|
|
157
|
+
* previews; Apple Music curated rails do too) and leave it `None`
|
|
158
|
+
* otherwise.
|
|
159
|
+
*/
|
|
160
|
+
export type BrowseFolder = {
|
|
161
|
+
nodeId: string;
|
|
162
|
+
title: string;
|
|
163
|
+
subtitle: string | null;
|
|
164
|
+
artworkId: string | null;
|
|
165
|
+
total: number | null;
|
|
166
|
+
previewChildren: Array<BrowseEntry> | null;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Page of browse results. `total` is the count of items in the
|
|
170
|
+
* underlying collection when the gateway can cheaply expose it (None
|
|
171
|
+
* means indeterminate). `has_more` is the authoritative end-of-data
|
|
172
|
+
* signal - webapps paginate by raising `offset` until `has_more` is
|
|
173
|
+
* false rather than relying on `total`.
|
|
174
|
+
*/
|
|
175
|
+
export type BrowseResult = {
|
|
176
|
+
entries: Array<BrowseEntry>;
|
|
177
|
+
total: number | null;
|
|
178
|
+
hasMore: boolean;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Why a call ended, surfaced on `onPhoneCallEnded`. `Failed` carries a
|
|
182
|
+
* platform-defined reason (network, busy, etc.).
|
|
183
|
+
*/
|
|
184
|
+
export type CallEndReason = {
|
|
185
|
+
type: 'local';
|
|
186
|
+
} | {
|
|
187
|
+
type: 'remote';
|
|
188
|
+
} | {
|
|
189
|
+
type: 'missed';
|
|
190
|
+
} | {
|
|
191
|
+
type: 'declined';
|
|
192
|
+
} | {
|
|
193
|
+
type: 'failed';
|
|
194
|
+
data: {
|
|
195
|
+
reason: string;
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* What the daemon advertises to webapps. `gateway: None` means no
|
|
200
|
+
* companion is connected; webapps that depend on companion-routed
|
|
201
|
+
* surfaces (Library, Net, Notifications, etc.) should branch on this.
|
|
202
|
+
* `authority` is the live set of scopes the companion currently claims.
|
|
203
|
+
*/
|
|
204
|
+
export type Capabilities = {
|
|
205
|
+
gateway: GatewayInfo | null;
|
|
206
|
+
available: SurfaceAvailability;
|
|
207
|
+
authority: Array<CompanionAuthorityScope>;
|
|
208
|
+
uriSchemes: Array<string>;
|
|
209
|
+
network: NetworkInfo;
|
|
210
|
+
audio: AudioCapabilities;
|
|
211
|
+
musicProvider: MusicProvider;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* What call-control verbs are currently legal. Webapps must gate UI on
|
|
215
|
+
* these flags; sending an unavailable verb is a protocol violation, not
|
|
216
|
+
* a no-op. All `None` = no signal received yet, treat as conservatively
|
|
217
|
+
* unavailable.
|
|
218
|
+
*/
|
|
219
|
+
export type CommunicationsState = {
|
|
220
|
+
signalStrength: number | null;
|
|
221
|
+
registrationStatus: RegistrationStatus | null;
|
|
222
|
+
airplaneMode: boolean | null;
|
|
223
|
+
carrierName: string | null;
|
|
224
|
+
cellularSupported: boolean | null;
|
|
225
|
+
telephonyEnabled: boolean | null;
|
|
226
|
+
faceTimeAudioEnabled: boolean | null;
|
|
227
|
+
faceTimeVideoEnabled: boolean | null;
|
|
228
|
+
muteStatus: boolean | null;
|
|
229
|
+
currentCallCount: number | null;
|
|
230
|
+
newVoicemailCount: number | null;
|
|
231
|
+
initiateCallAvailable: boolean | null;
|
|
232
|
+
endAndAcceptAvailable: boolean | null;
|
|
233
|
+
holdAndAcceptAvailable: boolean | null;
|
|
234
|
+
swapAvailable: boolean | null;
|
|
235
|
+
mergeAvailable: boolean | null;
|
|
236
|
+
holdAvailable: boolean | null;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* One axis the companion can declare authority over. Each scope has a
|
|
240
|
+
* fallback source the daemon merges with when no claim is active or
|
|
241
|
+
* the claim has gone stale. Unknown scopes arriving at an older daemon
|
|
242
|
+
* are stored opaquely and ignored.
|
|
243
|
+
*/
|
|
244
|
+
export type CompanionAuthorityScope = 'nowPlayingMetadata' | 'nowPlayingPlayback' | 'volume';
|
|
245
|
+
/**
|
|
246
|
+
* One key/value pair as exposed by config read APIs. `value` is always a
|
|
247
|
+
* string; consumers parse per the field's declared kind (number -> parseFloat,
|
|
248
|
+
* boolean -> "true"/"false", string/enum/secret -> as-is).
|
|
249
|
+
*/
|
|
250
|
+
export type ConfigEntry = {
|
|
251
|
+
key: string;
|
|
252
|
+
value: string;
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* One declared user-tunable setting. Adjacent-tagged on the wire to
|
|
256
|
+
* stay typeshare-compatible: `{"type":"string","data":{"key":"zip",...}}`.
|
|
257
|
+
*/
|
|
258
|
+
export type ConfigField = {
|
|
259
|
+
type: 'string';
|
|
260
|
+
data: StringField;
|
|
261
|
+
} | {
|
|
262
|
+
type: 'number';
|
|
263
|
+
data: NumberField;
|
|
264
|
+
} | {
|
|
265
|
+
type: 'boolean';
|
|
266
|
+
data: BoolField;
|
|
267
|
+
} | {
|
|
268
|
+
type: 'enum';
|
|
269
|
+
data: EnumField;
|
|
270
|
+
} | {
|
|
271
|
+
type: 'secret';
|
|
272
|
+
data: StringField;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* The foreground app driving playback, surfaced on iOS over iAP2.
|
|
276
|
+
*/
|
|
277
|
+
export type CurrentlyActiveApplication = {
|
|
278
|
+
/**
|
|
279
|
+
* Bundle identifier, e.g. `com.spotify.client`.
|
|
280
|
+
*/
|
|
281
|
+
id: string;
|
|
282
|
+
name: string;
|
|
283
|
+
};
|
|
284
|
+
export type Device = {
|
|
285
|
+
name: string;
|
|
286
|
+
type: DeviceType;
|
|
287
|
+
mac: string;
|
|
288
|
+
default: boolean;
|
|
289
|
+
};
|
|
290
|
+
export type DeviceType = 'android' | 'iOS' | 'windows' | 'macOS' | 'linux' | 'unknown';
|
|
291
|
+
/**
|
|
292
|
+
* Daemon health snapshot. `load_avg` is the unix 1/5/15-minute load.
|
|
293
|
+
* `soc_temp_c` may be `None` on builds where the SoC thermal probe is
|
|
294
|
+
* not exposed by the kernel.
|
|
295
|
+
*/
|
|
296
|
+
export type Diagnostics = {
|
|
297
|
+
diskUsedBytes: number;
|
|
298
|
+
diskFreeBytes: number;
|
|
299
|
+
memUsedBytes: number;
|
|
300
|
+
memAvailBytes: number;
|
|
301
|
+
uptimeS: number;
|
|
302
|
+
socTempC: number | null;
|
|
303
|
+
loadAvg: [number, number, number];
|
|
304
|
+
daemonVersion: string;
|
|
305
|
+
kernelVersion: string;
|
|
306
|
+
bootId: string;
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Why a notification went away. `Acted` covers both positive and
|
|
310
|
+
* negative invokes; gateways that distinguish dismiss-vs-acted may
|
|
311
|
+
* surface both as `Acted`.
|
|
312
|
+
*/
|
|
313
|
+
export type DismissReason = 'userDismissed' | 'acted' | 'remoteDismissed';
|
|
314
|
+
/**
|
|
315
|
+
* DTMF tones the accessory can play during an active call.
|
|
316
|
+
*/
|
|
317
|
+
export type DtmfTone = 'd0' | 'd1' | 'd2' | 'd3' | 'd4' | 'd5' | 'd6' | 'd7' | 'd8' | 'd9' | 'star' | 'hash';
|
|
318
|
+
/**
|
|
319
|
+
* Direction the accessory wants iOS to take when ending a call.
|
|
320
|
+
*/
|
|
321
|
+
export type EndCallAction = 'end' | 'endAll';
|
|
322
|
+
export type EnumField = {
|
|
323
|
+
key: string;
|
|
324
|
+
label: string;
|
|
325
|
+
choices: Array<string>;
|
|
326
|
+
default: string | null;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Page of the user's favorited / liked / saved library items. Mixed-kind
|
|
330
|
+
* because most platforms expose one "Saved" surface across kinds.
|
|
331
|
+
*/
|
|
332
|
+
export type FavoritesPage = {
|
|
333
|
+
items: Array<LibraryItem>;
|
|
334
|
+
total: number | null;
|
|
335
|
+
hasMore: boolean;
|
|
336
|
+
};
|
|
337
|
+
export type ForwardMessage = {
|
|
338
|
+
encoding: 'text';
|
|
339
|
+
data: string;
|
|
340
|
+
} | {
|
|
341
|
+
encoding: 'json';
|
|
342
|
+
data: unknown;
|
|
343
|
+
} | {
|
|
344
|
+
encoding: 'binary';
|
|
345
|
+
data: Uint8Array;
|
|
346
|
+
};
|
|
347
|
+
/**
|
|
348
|
+
* What a connected companion advertises about itself. Sent on every
|
|
349
|
+
* session-up via `GatewayToBridgeCapabilitiesMsg::Announce`, and re-sent
|
|
350
|
+
* on any change. The daemon caches the latest snapshot per peer and
|
|
351
|
+
* derives the webapp-facing `Capabilities` from it.
|
|
352
|
+
*/
|
|
353
|
+
export type GatewayCapabilities = {
|
|
354
|
+
gateway: GatewayInfo;
|
|
355
|
+
uriSchemes: Array<string>;
|
|
356
|
+
network: NetworkInfo;
|
|
357
|
+
available: SurfaceAvailability;
|
|
358
|
+
audio: AudioCapabilities;
|
|
359
|
+
musicProvider: MusicProvider;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Identity payload describing the companion peer the daemon is talking
|
|
363
|
+
* to. Address is the BT MAC the companion advertises; on transports without
|
|
364
|
+
* a stable MAC (the network gateway's `0xfe:fe:...` synthetic addrs) it
|
|
365
|
+
* is the synthetic address as a string.
|
|
366
|
+
*/
|
|
367
|
+
export type GatewayInfo = {
|
|
368
|
+
address: string;
|
|
369
|
+
name: string;
|
|
370
|
+
osName: string;
|
|
371
|
+
appName: string;
|
|
372
|
+
appVersion: string;
|
|
373
|
+
adapterVersion: string;
|
|
374
|
+
libVersion: string;
|
|
375
|
+
libbridgethingVersion: string;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Subscriber's accuracy preference. `Coarse` opts into the lower-power
|
|
379
|
+
* city-block-grade fix on platforms that distinguish (iOS reduced
|
|
380
|
+
* accuracy, Android `PRIORITY_BALANCED_POWER_ACCURACY`). The daemon
|
|
381
|
+
* aggregates across subscribers and forwards the most-demanding to the
|
|
382
|
+
* companion.
|
|
383
|
+
*/
|
|
384
|
+
export type GeoAccuracy = 'coarse' | 'fine';
|
|
385
|
+
export type GeoError = 'permissionDenied' | 'unavailable' | 'unknownToken';
|
|
386
|
+
export type HardwareError = 'levelOutOfRange' | 'modeMismatch';
|
|
387
|
+
/**
|
|
388
|
+
* Snapshot of the device's hardware-controlled surfaces. Sent on
|
|
389
|
+
* `hardware.state.get` and re-broadcast on any change. `ambient_level`
|
|
390
|
+
* is the 0-255 ambient light reading.
|
|
391
|
+
*/
|
|
392
|
+
export type HardwareState = {
|
|
393
|
+
brightness: BrightnessState;
|
|
394
|
+
ambientLevel: number;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* One header on an HTTP request or response. Key order is preserved
|
|
398
|
+
* across serialize/deserialize.
|
|
399
|
+
*/
|
|
400
|
+
export type HttpHeader = {
|
|
401
|
+
name: string;
|
|
402
|
+
value: string;
|
|
403
|
+
};
|
|
404
|
+
export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';
|
|
405
|
+
/**
|
|
406
|
+
* An image delivered either as an opaque asset id (fetch via `asset.get`)
|
|
407
|
+
* or as inline bytes.
|
|
408
|
+
*/
|
|
409
|
+
export type Image = {
|
|
410
|
+
type: 'id';
|
|
411
|
+
data: string;
|
|
412
|
+
} | {
|
|
413
|
+
type: 'bytes';
|
|
414
|
+
data: Uint8Array;
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* What kind of outbound call the accessory wants placed.
|
|
418
|
+
*/
|
|
419
|
+
export type InitiateCallType = 'destination' | 'voicemail' | 'redial';
|
|
420
|
+
/**
|
|
421
|
+
* Coarse type tag a webapp uses to filter or branch. Mirrors the variant
|
|
422
|
+
* names of `LibraryItem`; kept separate so search/recommendations can
|
|
423
|
+
* constrain by kind without having to construct a sample item.
|
|
424
|
+
*/
|
|
425
|
+
export type ItemKind = 'track' | 'album' | 'playlist' | 'podcastEpisode' | 'show' | 'artist' | 'station';
|
|
426
|
+
/**
|
|
427
|
+
* Stable URI + kind a webapp passes back to act on a library item
|
|
428
|
+
* (e.g. `player.play({ uri })`, `library.favorites.toggle({ item })`).
|
|
429
|
+
* `persistent_id` is the platform-stable id when the gateway has one;
|
|
430
|
+
* webapps treat it as opaque.
|
|
431
|
+
*/
|
|
432
|
+
export type ItemRef = {
|
|
433
|
+
uri: string;
|
|
434
|
+
kind: ItemKind;
|
|
435
|
+
persistentId: string | null;
|
|
436
|
+
};
|
|
437
|
+
export type LibraryError = {
|
|
438
|
+
type: 'notFound';
|
|
439
|
+
data: {
|
|
440
|
+
uri: string;
|
|
441
|
+
};
|
|
442
|
+
} | {
|
|
443
|
+
type: 'notSupported';
|
|
444
|
+
data: {
|
|
445
|
+
reason: string;
|
|
446
|
+
};
|
|
447
|
+
} | {
|
|
448
|
+
type: 'unauthorized';
|
|
449
|
+
} | {
|
|
450
|
+
type: 'noGateway';
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* One playable / browsable item from the library. Lean per-variant
|
|
454
|
+
* payload - gateways translate platform-specific extras down to these
|
|
455
|
+
* fields, rare per-platform fields just don't surface. Forward-compat:
|
|
456
|
+
* adding new variants or fields is an additive change webapps can
|
|
457
|
+
* branch on.
|
|
458
|
+
*/
|
|
459
|
+
export type LibraryItem = {
|
|
460
|
+
type: 'track';
|
|
461
|
+
data: Track;
|
|
462
|
+
} | {
|
|
463
|
+
type: 'album';
|
|
464
|
+
data: Album;
|
|
465
|
+
} | {
|
|
466
|
+
type: 'playlist';
|
|
467
|
+
data: Playlist;
|
|
468
|
+
} | {
|
|
469
|
+
type: 'podcastEpisode';
|
|
470
|
+
data: PodcastEpisode;
|
|
471
|
+
} | {
|
|
472
|
+
type: 'show';
|
|
473
|
+
data: Show;
|
|
474
|
+
} | {
|
|
475
|
+
type: 'artist';
|
|
476
|
+
data: Artist;
|
|
477
|
+
} | {
|
|
478
|
+
type: 'station';
|
|
479
|
+
data: Station;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* One log record. `ts_unix_s` is unix-epoch seconds. `target` is the
|
|
483
|
+
* tracing target / unit name; `message` is the rendered single-line
|
|
484
|
+
* body. Pre-filtered at subscription time so wire-bloating trace
|
|
485
|
+
* events don't reach webapps.
|
|
486
|
+
*/
|
|
487
|
+
export type LogEntry = {
|
|
488
|
+
tsUnixS: number;
|
|
489
|
+
level: LogLevel;
|
|
490
|
+
target: string;
|
|
491
|
+
message: string;
|
|
492
|
+
};
|
|
493
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
494
|
+
/**
|
|
495
|
+
* What stream of log records a subscription pulls from. `Daemon` is the
|
|
496
|
+
* bridgething tracing subscriber; `System` is the `journald` view; `All`
|
|
497
|
+
* merges both in arrival order.
|
|
498
|
+
*/
|
|
499
|
+
export type LogSource = 'daemon' | 'system' | 'all';
|
|
500
|
+
/**
|
|
501
|
+
* Currently-playing track, populated to the extent the gateway/iAP2
|
|
502
|
+
* stream has surfaced. All fields are optional because each one arrives
|
|
503
|
+
* as a separate attribute fetch on iAP2; the daemon accumulates and the
|
|
504
|
+
* snapshot reflects whatever's known so far.
|
|
505
|
+
*/
|
|
506
|
+
export type MediaItem = {
|
|
507
|
+
uri: string | null;
|
|
508
|
+
persistentId: string | null;
|
|
509
|
+
title: string | null;
|
|
510
|
+
album: string | null;
|
|
511
|
+
albumUri: string | null;
|
|
512
|
+
albumArtist: string | null;
|
|
513
|
+
artist: string | null;
|
|
514
|
+
artistUri: string | null;
|
|
515
|
+
liked: boolean | null;
|
|
516
|
+
artworkId: string | null;
|
|
517
|
+
durationMs: number | null;
|
|
518
|
+
mediaTypes: Array<MediaType> | null;
|
|
519
|
+
trackNumber: number | null;
|
|
520
|
+
trackCount: number | null;
|
|
521
|
+
isLikeSupported: boolean | null;
|
|
522
|
+
isBanSupported: boolean | null;
|
|
523
|
+
isBanned: boolean | null;
|
|
524
|
+
chapterCount: number | null;
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Per-track attributes that vary per song. `persistent_id` is a stable
|
|
528
|
+
* per-platform identifier (iAP2 sends u64; we hex-encode it on the
|
|
529
|
+
* wire). `artwork_id` is an opaque asset id - webapps pass this value
|
|
530
|
+
* to `ClientToBridgeAssetMsg::Get` to retrieve the bytes. The id namespace
|
|
531
|
+
* is producer-defined: iAP2 emits `iap2/art/<persistent_hex>/<n>`, the
|
|
532
|
+
* companion picks whatever shape it wants (e.g. `spotify/track/<id>/image`).
|
|
533
|
+
* Webapps treat the value as opaque.
|
|
534
|
+
*/
|
|
535
|
+
export type MediaItemUpdate = {
|
|
536
|
+
persistentId: string | null;
|
|
537
|
+
title: string | null;
|
|
538
|
+
album: string | null;
|
|
539
|
+
albumUri: string | null;
|
|
540
|
+
albumArtist: string | null;
|
|
541
|
+
artist: string | null;
|
|
542
|
+
artistUri: string | null;
|
|
543
|
+
liked: boolean | null;
|
|
544
|
+
artworkId: string | null;
|
|
545
|
+
durationMs: number | null;
|
|
546
|
+
mediaTypes: Array<MediaType> | null;
|
|
547
|
+
trackNumber: number | null;
|
|
548
|
+
trackCount: number | null;
|
|
549
|
+
isLikeSupported: boolean | null;
|
|
550
|
+
isBanSupported: boolean | null;
|
|
551
|
+
isBanned: boolean | null;
|
|
552
|
+
isResidentOnDevice: boolean | null;
|
|
553
|
+
chapterCount: number | null;
|
|
554
|
+
};
|
|
555
|
+
/**
|
|
556
|
+
* The kind of media currently playing. Multi-typed: an item can be
|
|
557
|
+
* e.g. both `Podcast` and `AudioBook` (rare). Drives webapp UI choices
|
|
558
|
+
* like skip-15s-vs-skip-track and chapter UI.
|
|
559
|
+
*/
|
|
560
|
+
export type MediaType = 'music' | 'podcast' | 'audioBook';
|
|
561
|
+
/**
|
|
562
|
+
* Which music service the companion is currently logged into and
|
|
563
|
+
* driving on behalf of the user. `None` when no glue is attached.
|
|
564
|
+
*/
|
|
565
|
+
export type MusicProvider = 'none' | 'spotify' | 'appleMusic' | 'tidal';
|
|
566
|
+
export type NetError = {
|
|
567
|
+
type: 'requestFailed';
|
|
568
|
+
data: {
|
|
569
|
+
reason: string;
|
|
570
|
+
};
|
|
571
|
+
} | {
|
|
572
|
+
type: 'timeout';
|
|
573
|
+
} | {
|
|
574
|
+
type: 'unavailable';
|
|
575
|
+
} | {
|
|
576
|
+
type: 'noGateway';
|
|
577
|
+
};
|
|
578
|
+
export type NetFetchRequest = {
|
|
579
|
+
url: string;
|
|
580
|
+
method: HttpMethod;
|
|
581
|
+
headers: Array<HttpHeader>;
|
|
582
|
+
body?: Uint8Array | null;
|
|
583
|
+
timeoutMs: number | null;
|
|
584
|
+
redirect: RedirectPolicy;
|
|
585
|
+
};
|
|
586
|
+
export type NetFetchResponse = {
|
|
587
|
+
status: number;
|
|
588
|
+
headers: Array<HttpHeader>;
|
|
589
|
+
body: Uint8Array;
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* What kind of network the companion's host is currently using. `metered`
|
|
593
|
+
* is the OS-reported metered flag; webapps should treat it as a hint
|
|
594
|
+
* (e.g. defer non-essential fetches) rather than a hard ban.
|
|
595
|
+
*/
|
|
596
|
+
export type NetworkInfo = {
|
|
597
|
+
kind: NetworkKind;
|
|
598
|
+
metered: boolean;
|
|
599
|
+
};
|
|
600
|
+
export type NetworkKind = 'unknown' | 'wifi' | 'cellular' | 'ethernet';
|
|
601
|
+
/**
|
|
602
|
+
* One alternate interpretation the LLM surfaced alongside the primary.
|
|
603
|
+
* Populated when the LLM returns `ambiguous_alternates` in its
|
|
604
|
+
* json_schema output; consumed by the companion's CLARIFY UI so the
|
|
605
|
+
* user can pick.
|
|
606
|
+
*/
|
|
607
|
+
export type NluAlternate = {
|
|
608
|
+
intent: string;
|
|
609
|
+
slots: NluSlots | null;
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Confidence the companion-side NLU pipeline attaches to a resolved
|
|
613
|
+
* intent: a coarse "low" | "medium" | "high" level per channel, one for
|
|
614
|
+
* the intent match and one for the extracted slots.
|
|
615
|
+
*/
|
|
616
|
+
export type NluConfidence = {
|
|
617
|
+
/**
|
|
618
|
+
* "low" | "medium" | "high". The LLM emits one of these per channel.
|
|
619
|
+
*/
|
|
620
|
+
intent: string;
|
|
621
|
+
slots: string | null;
|
|
622
|
+
};
|
|
623
|
+
/**
|
|
624
|
+
* What the companion-side NLU resolved an utterance to, sent across
|
|
625
|
+
* the gateway link for the daemon to dispatch. This is the bridgething-
|
|
626
|
+
* native shape; the daemon's stock-compat layer wraps it into the
|
|
627
|
+
* SLIMO `NluMessage` envelope when the active webapp is stock.
|
|
628
|
+
*
|
|
629
|
+
* `transcript` is the ASR output the NLU ran on; carried so the daemon
|
|
630
|
+
* can echo it for telemetry and so SHOW+UNKNOWN+query="DJ"-style
|
|
631
|
+
* stock-compat fallbacks have the raw query available.
|
|
632
|
+
*/
|
|
633
|
+
export type NluResolvedIntent = {
|
|
634
|
+
intent: string;
|
|
635
|
+
slots: NluSlots;
|
|
636
|
+
transcript: string;
|
|
637
|
+
confidence: NluConfidence | null;
|
|
638
|
+
alternates: Array<NluAlternate> | null;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* Slot catalog. Every intent projects through this flat shape;
|
|
642
|
+
* per-intent slot allowlists are enforced by the json_schema grammar at
|
|
643
|
+
* decode time, not by this struct. The wire payload omits absent slots,
|
|
644
|
+
* so a PLAY-with-artist row is just `{ "artist": "..." }` on the wire.
|
|
645
|
+
*
|
|
646
|
+
* String values are passed through verbatim from the user's transcript
|
|
647
|
+
* (no normalization at this layer); the SpotifyResolver may decorate
|
|
648
|
+
* the slots with a `uri` after catalog lookup.
|
|
649
|
+
*/
|
|
650
|
+
export type NluSlots = {
|
|
651
|
+
artist: string | null;
|
|
652
|
+
track: string | null;
|
|
653
|
+
album: string | null;
|
|
654
|
+
playlist: string | null;
|
|
655
|
+
podcast: string | null;
|
|
656
|
+
episode: string | null;
|
|
657
|
+
mood: string | null;
|
|
658
|
+
genre: string | null;
|
|
659
|
+
era: string | null;
|
|
660
|
+
popularityFilter: string | null;
|
|
661
|
+
entityType: string | null;
|
|
662
|
+
query: string | null;
|
|
663
|
+
/**
|
|
664
|
+
* WEBAPP_INTENT only: the filler-stripped natural-language command
|
|
665
|
+
* the active webapp's voice grammar handler will parse.
|
|
666
|
+
*/
|
|
667
|
+
rawQuery: string | null;
|
|
668
|
+
/**
|
|
669
|
+
* WEBAPP_INTENT / OPEN_WEBAPP only.
|
|
670
|
+
*/
|
|
671
|
+
webappId: string | null;
|
|
672
|
+
webappName: string | null;
|
|
673
|
+
/**
|
|
674
|
+
* PLAY_PRESET / SAVE_TO_PRESET only. String because users say "two"
|
|
675
|
+
* but stock SLIMO expects an Array<string> envelope - the stock
|
|
676
|
+
* translation wraps as needed.
|
|
677
|
+
*/
|
|
678
|
+
preset: string | null;
|
|
679
|
+
/**
|
|
680
|
+
* VOLUME_UP / VOLUME_DOWN. "small" | "large" | numeric step.
|
|
681
|
+
*/
|
|
682
|
+
amount: string | null;
|
|
683
|
+
/**
|
|
684
|
+
* VOLUME_ABSOLUTE. 0-100.
|
|
685
|
+
*/
|
|
686
|
+
level: number | null;
|
|
687
|
+
/**
|
|
688
|
+
* Post-resolution Spotify URI. Populated by the companion's
|
|
689
|
+
* SpotifyResolver after the NLU stage; daemon dispatches directly
|
|
690
|
+
* to playback when set.
|
|
691
|
+
*/
|
|
692
|
+
uri: string | null;
|
|
693
|
+
};
|
|
694
|
+
/**
|
|
695
|
+
* One notification surfaced from the connected companion's notification
|
|
696
|
+
* center. `id` is companion-stable for the lifetime of the notification
|
|
697
|
+
* - webapps pass it to `invokePositive`/`invokeNegative` and listen for
|
|
698
|
+
* `onNotificationRemoved`. Bodies (`title`/`subtitle`/`message`) are all
|
|
699
|
+
* optional because ANCS treats them as separate attribute fetches.
|
|
700
|
+
*/
|
|
701
|
+
export type Notification = {
|
|
702
|
+
id: string;
|
|
703
|
+
app: NotificationApp;
|
|
704
|
+
category: NotificationCategory;
|
|
705
|
+
title: string | null;
|
|
706
|
+
subtitle: string | null;
|
|
707
|
+
message: string | null;
|
|
708
|
+
timestampUnixS: number | null;
|
|
709
|
+
flags: NotificationFlags;
|
|
710
|
+
positiveAction: NotificationAction | null;
|
|
711
|
+
negativeAction: NotificationAction | null;
|
|
712
|
+
};
|
|
713
|
+
/**
|
|
714
|
+
* One ANCS-style action slot. `label` is the gateway-localized prompt
|
|
715
|
+
* the webapp renders on the action button.
|
|
716
|
+
*/
|
|
717
|
+
export type NotificationAction = {
|
|
718
|
+
label: string;
|
|
719
|
+
};
|
|
720
|
+
/**
|
|
721
|
+
* Originating app metadata. `bundle_id` is platform-stable
|
|
722
|
+
* (`com.apple.MobileSMS`, `com.spotify.client`, etc.); `display_name`
|
|
723
|
+
* and `icon_asset_id` are best-effort and may be missing on Android
|
|
724
|
+
* gateways that don't surface them cheaply.
|
|
725
|
+
*/
|
|
726
|
+
export type NotificationApp = {
|
|
727
|
+
bundleId: string;
|
|
728
|
+
displayName: string | null;
|
|
729
|
+
iconAssetId: string | null;
|
|
730
|
+
};
|
|
731
|
+
export type NotificationCategory = 'other' | 'incomingCall' | 'missedCall' | 'voicemail' | 'social' | 'schedule' | 'email' | 'news' | 'healthAndFitness' | 'businessAndFinance' | 'location' | 'entertainment';
|
|
732
|
+
/**
|
|
733
|
+
* ANCS-shaped flags. `silent` mirrors the iOS "do not surface
|
|
734
|
+
* audibly" hint, `important` is the high-importance flag, and
|
|
735
|
+
* `pre_existing` is true for notifications that arrived before the
|
|
736
|
+
* daemon connected (replayed by the companion on first sync).
|
|
737
|
+
*/
|
|
738
|
+
export type NotificationFlags = {
|
|
739
|
+
silent: boolean;
|
|
740
|
+
important: boolean;
|
|
741
|
+
preExisting: boolean;
|
|
742
|
+
};
|
|
743
|
+
/**
|
|
744
|
+
* Delta event the companion or iAP2 stream emits whenever a player
|
|
745
|
+
* attribute changes. Every field is optional: producers send partial
|
|
746
|
+
* updates populating only what changed, and fields left unset keep
|
|
747
|
+
* their prior value.
|
|
748
|
+
*/
|
|
749
|
+
export type NowPlayingUpdate = {
|
|
750
|
+
mediaItem: MediaItemUpdate | null;
|
|
751
|
+
playback: PlaybackUpdate | null;
|
|
752
|
+
};
|
|
753
|
+
export type NumberField = {
|
|
754
|
+
key: string;
|
|
755
|
+
label: string;
|
|
756
|
+
min: number | null;
|
|
757
|
+
max: number | null;
|
|
758
|
+
step: number | null;
|
|
759
|
+
default: number | null;
|
|
760
|
+
};
|
|
761
|
+
export type OtaError = {
|
|
762
|
+
code: OtaErrorCode;
|
|
763
|
+
msg: string;
|
|
764
|
+
};
|
|
765
|
+
/**
|
|
766
|
+
* Terminal error from the OTA orchestrator. After an `OtaError` the
|
|
767
|
+
* orchestrator is back to idle and a fresh `OtaBegin` may be sent.
|
|
768
|
+
*/
|
|
769
|
+
export type OtaErrorCode = 'unknownUpdate' | 'offsetMismatch' | 'hashMismatch' | 'sizeMismatch' | 'cancelled' | 'writeFailed' | 'confirmFailed' | 'internal';
|
|
770
|
+
/**
|
|
771
|
+
* What the streamed bytes are going to be applied as.
|
|
772
|
+
*
|
|
773
|
+
* `Image` streams a `.swu` through libswupdate + slot flip + reboot.
|
|
774
|
+
* `Daemon` streams a fresh aarch64 daemon binary, atomic-rotates on
|
|
775
|
+
* the bandaid bind-mount, restarts the service. `BuiltinWebapp`
|
|
776
|
+
* streams a zip bundle of hub or stock, validates the manifest id is
|
|
777
|
+
* one of the reserved built-ins, atomic-rotates the bundle dir on the
|
|
778
|
+
* bandaid bind-mount, restarts the service. `InstalledWebapp` streams
|
|
779
|
+
* a zip bundle of a third-party (non-reserved) webapp and installs it
|
|
780
|
+
* into the writable registry; it neither stages on the bandaid nor
|
|
781
|
+
* restarts, and is never part of an `OtaActivate` batch.
|
|
782
|
+
*
|
|
783
|
+
* Companions key reboot expectations off this: image means the device
|
|
784
|
+
* power-cycles; daemon and builtin-webapp mean the daemon process
|
|
785
|
+
* restarts and the gateway link drops and reconnects; installed-webapp
|
|
786
|
+
* applies in place with no restart, and the terminal signal is the
|
|
787
|
+
* `WebappInstalled` event (or an `OtaError`).
|
|
788
|
+
*/
|
|
789
|
+
export type OtaKind = 'image' | 'daemon' | 'builtinWebapp' | 'installedWebapp';
|
|
790
|
+
/**
|
|
791
|
+
* Stage of the OTA orchestrator. The phase set is shared between
|
|
792
|
+
* kinds, with non-image kinds emitting a subset.
|
|
793
|
+
*
|
|
794
|
+
* Image: `Streaming` -> `Verifying` -> `Writing` (libswupdate to slot)
|
|
795
|
+
* -> `Confirming` (try-counter reset) -> `Reboot`.
|
|
796
|
+
*
|
|
797
|
+
* Daemon and BuiltinWebapp: `Streaming` -> `Verifying` -> `Writing`,
|
|
798
|
+
* where `Writing`/100 means the piece is validated and staged on the
|
|
799
|
+
* bandaid (not yet live). The atomic rotate and the single `systemctl
|
|
800
|
+
* restart` happen later, on `OtaActivate`, which emits the terminal
|
|
801
|
+
* `Reboot` for the whole batch. `Confirming` is image-only.
|
|
802
|
+
*
|
|
803
|
+
* InstalledWebapp: `Streaming` -> `Verifying` -> `Writing`/0 while the
|
|
804
|
+
* bundle installs into the writable registry. There is no `Writing`/100,
|
|
805
|
+
* no `Confirming`, and no `Reboot`; the terminal signal is the
|
|
806
|
+
* `WebappInstalled` event (or an `OtaError`).
|
|
807
|
+
*/
|
|
808
|
+
export type OtaPhase = 'streaming' | 'verifying' | 'writing' | 'confirming' | 'reboot';
|
|
809
|
+
/**
|
|
810
|
+
* Per-phase progress tick. `percent` is 0-100 within the current
|
|
811
|
+
* phase, not the overall flow. `eta_ms` is best-effort remaining time
|
|
812
|
+
* for the phase when the orchestrator can compute it.
|
|
813
|
+
*/
|
|
814
|
+
export type OtaProgress = {
|
|
815
|
+
phase: OtaPhase;
|
|
816
|
+
percent: number;
|
|
817
|
+
etaMs: number | null;
|
|
818
|
+
};
|
|
819
|
+
export type Peer = {
|
|
820
|
+
device: Device;
|
|
821
|
+
paired: boolean;
|
|
822
|
+
iap2: PeerIap2Status;
|
|
823
|
+
companion: PeerCompanionStatus;
|
|
824
|
+
displayName: string | null;
|
|
825
|
+
language: string | null;
|
|
826
|
+
uuid: string | null;
|
|
827
|
+
};
|
|
828
|
+
export type PeerCompanionStatus = {
|
|
829
|
+
type: 'none';
|
|
830
|
+
} | {
|
|
831
|
+
type: 'pending';
|
|
832
|
+
} | {
|
|
833
|
+
type: 'connected';
|
|
834
|
+
data: GatewayInfo;
|
|
835
|
+
};
|
|
836
|
+
export type PeerIap2Status = 'none' | 'linkUp' | 'authenticated' | 'identified';
|
|
837
|
+
/**
|
|
838
|
+
* One telephony call. `call_id` is companion-stable for the call's
|
|
839
|
+
* lifetime; webapps pass it back to `answer`/`decline`/`end`/`hold`.
|
|
840
|
+
* `remote_id` is the raw E.164 (or platform raw); `display_name` is the
|
|
841
|
+
* gateway's resolved contact name when available.
|
|
842
|
+
*/
|
|
843
|
+
export type PhoneCall = {
|
|
844
|
+
callId: string;
|
|
845
|
+
remoteId: string;
|
|
846
|
+
displayName: string;
|
|
847
|
+
status: PhoneCallStatus;
|
|
848
|
+
direction: PhoneCallDirection;
|
|
849
|
+
startedAtUnixS: number | null;
|
|
850
|
+
label: string | null;
|
|
851
|
+
addressBookId: string | null;
|
|
852
|
+
service: PhoneCallService | null;
|
|
853
|
+
isConferenced: boolean | null;
|
|
854
|
+
conferenceGroup: number | null;
|
|
855
|
+
};
|
|
856
|
+
export type PhoneCallDirection = 'incoming' | 'outgoing';
|
|
857
|
+
/**
|
|
858
|
+
* Call bearer / service kind. iAP2's `CallStateUpdateService` enum
|
|
859
|
+
* values, projected to our wire surface. Companion gateways that don't
|
|
860
|
+
* distinguish bearers project all calls to `Telephony`.
|
|
861
|
+
*/
|
|
862
|
+
export type PhoneCallService = 'unknown' | 'telephony' | 'faceTimeAudio' | 'faceTimeVideo';
|
|
863
|
+
export type PhoneCallStatus = 'disconnected' | 'sending' | 'ringing' | 'connecting' | 'active' | 'held' | 'disconnecting';
|
|
864
|
+
export type PhoneError = {
|
|
865
|
+
type: 'callNotFound';
|
|
866
|
+
data: {
|
|
867
|
+
call_id: string;
|
|
868
|
+
};
|
|
869
|
+
} | {
|
|
870
|
+
type: 'actionRejected';
|
|
871
|
+
data: {
|
|
872
|
+
reason: string;
|
|
873
|
+
};
|
|
874
|
+
} | {
|
|
875
|
+
type: 'noTarget';
|
|
876
|
+
} | {
|
|
877
|
+
type: 'unavailable';
|
|
878
|
+
data: {
|
|
879
|
+
verb: string;
|
|
880
|
+
};
|
|
881
|
+
};
|
|
882
|
+
/**
|
|
883
|
+
* Snapshot of every active call known to the gateway. Multi-call is
|
|
884
|
+
* possible (call-waiting, conference) - webapps rendering only one
|
|
885
|
+
* active call typically pick the first non-Held entry.
|
|
886
|
+
*/
|
|
887
|
+
export type PhoneState = {
|
|
888
|
+
activeCalls: Array<PhoneCall>;
|
|
889
|
+
};
|
|
890
|
+
/**
|
|
891
|
+
* Optional context for `play({ uri })`. `context_uri` is the album /
|
|
892
|
+
* playlist / show URI the track is being played from; gateways with
|
|
893
|
+
* playlist support honor it for skip-next semantics. `position` is the
|
|
894
|
+
* 0-based index inside the context.
|
|
895
|
+
*/
|
|
896
|
+
export type PlayContext = {
|
|
897
|
+
contextUri: string;
|
|
898
|
+
position: number | null;
|
|
899
|
+
};
|
|
900
|
+
/**
|
|
901
|
+
* Per-session playback snapshot: where in the song we are, what mode is
|
|
902
|
+
* engaged. `position_ms` is the live playhead at snapshot time; webapps
|
|
903
|
+
* extrapolate forward locally while `state == Playing`.
|
|
904
|
+
*
|
|
905
|
+
* `set_elapsed_time_available` gates scrub UI: when false, the foreground
|
|
906
|
+
* app refuses absolute-position seeks and webapps must disable the scrub
|
|
907
|
+
* thumb. `None` means unknown (no signal received yet); webapps treat
|
|
908
|
+
* unknown as "available" for backward compatibility with older gateways.
|
|
909
|
+
*/
|
|
910
|
+
export type Playback = {
|
|
911
|
+
state: PlaybackState;
|
|
912
|
+
positionMs: number;
|
|
913
|
+
positionAgeMs: number | null;
|
|
914
|
+
shuffle: boolean;
|
|
915
|
+
shuffleMode: ShuffleMode | null;
|
|
916
|
+
repeat: RepeatMode;
|
|
917
|
+
queueIndex: number | null;
|
|
918
|
+
queueCount: number | null;
|
|
919
|
+
queueChapterIndex: number | null;
|
|
920
|
+
setElapsedTimeAvailable: boolean | null;
|
|
921
|
+
queueListAvail: boolean | null;
|
|
922
|
+
appleMusicRadioAd: boolean | null;
|
|
923
|
+
};
|
|
924
|
+
/**
|
|
925
|
+
* What the current track is playing from: the playlist / album / show /
|
|
926
|
+
* artist context. Webapps render "playing from <name>"; `uri` lets them
|
|
927
|
+
* drill into it. `name` is `None` until the companion resolves it.
|
|
928
|
+
*/
|
|
929
|
+
export type PlaybackContext = {
|
|
930
|
+
uri: string;
|
|
931
|
+
name: string | null;
|
|
932
|
+
};
|
|
933
|
+
/**
|
|
934
|
+
* Repeat and shuffle toggle state.
|
|
935
|
+
*/
|
|
936
|
+
export type PlaybackOptions = {
|
|
937
|
+
repeat: RepeatMode;
|
|
938
|
+
shuffle: boolean;
|
|
939
|
+
};
|
|
940
|
+
/**
|
|
941
|
+
* A resolved queue: the current track flanked by upcoming and previous tracks.
|
|
942
|
+
*/
|
|
943
|
+
export type PlaybackQueue = {
|
|
944
|
+
next: Array<Track>;
|
|
945
|
+
current: Track;
|
|
946
|
+
previous: Array<Track>;
|
|
947
|
+
};
|
|
948
|
+
/**
|
|
949
|
+
* Which player controls the current source supports; webapps disable the
|
|
950
|
+
* UI for any capability that is `false`.
|
|
951
|
+
*/
|
|
952
|
+
export type PlaybackRestrictions = {
|
|
953
|
+
can_repeat_context: boolean;
|
|
954
|
+
can_repeat_track: boolean;
|
|
955
|
+
can_seek: boolean;
|
|
956
|
+
can_skip_next: boolean;
|
|
957
|
+
can_skip_prev: boolean;
|
|
958
|
+
can_toggle_shuffle: boolean;
|
|
959
|
+
can_like: boolean;
|
|
960
|
+
can_change_volume: boolean;
|
|
961
|
+
can_set_output: boolean;
|
|
962
|
+
};
|
|
963
|
+
/**
|
|
964
|
+
* Three-state playback. `Stopped` is the no-track-loaded resting state;
|
|
965
|
+
* `Paused` is "track is loaded, position is held"; `Playing` is the
|
|
966
|
+
* progressing state.
|
|
967
|
+
*/
|
|
968
|
+
export type PlaybackState = 'stopped' | 'paused' | 'playing';
|
|
969
|
+
/**
|
|
970
|
+
* Per-playback-session attributes that vary regardless of track:
|
|
971
|
+
* playing/paused, position, shuffle/repeat, and the iOS bundle
|
|
972
|
+
* identifier of the app currently driving playback (e.g.
|
|
973
|
+
* `"com.spotify.client"`). `app_bundle` is null on the Android path
|
|
974
|
+
* since it isn't a meaningful surface there.
|
|
975
|
+
*
|
|
976
|
+
* `set_elapsed_time_available` is the gate webapps must honor for
|
|
977
|
+
* scrub UI: when false, scrubbing is unsupported by the foreground
|
|
978
|
+
* app and the seek button must be disabled.
|
|
979
|
+
*/
|
|
980
|
+
export type PlaybackUpdate = {
|
|
981
|
+
playing: boolean | null;
|
|
982
|
+
positionMs: number | null;
|
|
983
|
+
shuffle: boolean | null;
|
|
984
|
+
shuffleMode: ShuffleMode | null;
|
|
985
|
+
repeat: RepeatMode | null;
|
|
986
|
+
appBundle: string | null;
|
|
987
|
+
appDisplayName: string | null;
|
|
988
|
+
queueIndex: number | null;
|
|
989
|
+
queueCount: number | null;
|
|
990
|
+
queueChapterIndex: number | null;
|
|
991
|
+
playbackSpeed: number | null;
|
|
992
|
+
setElapsedTimeAvailable: boolean | null;
|
|
993
|
+
queueListAvail: boolean | null;
|
|
994
|
+
appleMusicRadioAd: boolean | null;
|
|
995
|
+
appleMusicRadioStationName: string | null;
|
|
996
|
+
};
|
|
997
|
+
export type PlayerError = {
|
|
998
|
+
type: 'schemeUnclaimed';
|
|
999
|
+
data: {
|
|
1000
|
+
scheme: string;
|
|
1001
|
+
};
|
|
1002
|
+
} | {
|
|
1003
|
+
type: 'playFailed';
|
|
1004
|
+
data: {
|
|
1005
|
+
reason: string;
|
|
1006
|
+
};
|
|
1007
|
+
} | {
|
|
1008
|
+
type: 'noGateway';
|
|
1009
|
+
} | {
|
|
1010
|
+
type: 'notInQueue';
|
|
1011
|
+
data: {
|
|
1012
|
+
index: number;
|
|
1013
|
+
};
|
|
1014
|
+
};
|
|
1015
|
+
/**
|
|
1016
|
+
* User-tunable knobs that are not "currently playing" state.
|
|
1017
|
+
* `crossfade_ms = None` is "crossfade off"; `Some(0)` is also off but
|
|
1018
|
+
* distinguishes "user explicitly set zero" from "feature unsupported by
|
|
1019
|
+
* gateway".
|
|
1020
|
+
*/
|
|
1021
|
+
export type PlayerOptions = {
|
|
1022
|
+
speed: number;
|
|
1023
|
+
crossfade_ms: number | null;
|
|
1024
|
+
};
|
|
1025
|
+
/**
|
|
1026
|
+
* Full player snapshot the daemon broadcasts to webapps. Initial value
|
|
1027
|
+
* arrives on `BridgeToClientPlayerMsg::StateChange` at connect time;
|
|
1028
|
+
* subsequent changes flow as `NowPlayingUpdate` deltas the client SDK
|
|
1029
|
+
* merges into the cached snapshot.
|
|
1030
|
+
*/
|
|
1031
|
+
export type PlayerState = {
|
|
1032
|
+
track: MediaItem | null;
|
|
1033
|
+
playback: Playback;
|
|
1034
|
+
queue: Array<QueueItem>;
|
|
1035
|
+
options: PlayerOptions;
|
|
1036
|
+
context: PlaybackContext | null;
|
|
1037
|
+
};
|
|
1038
|
+
/**
|
|
1039
|
+
* Lean cross-platform shape for a playlist. `uri` is what `player.play`
|
|
1040
|
+
* would route on; `track_count` is best-effort (some sources don't expose
|
|
1041
|
+
* it cheaply); `owner_name` is whatever the source surfaces (Spotify
|
|
1042
|
+
* owner, Apple Music curator, etc.).
|
|
1043
|
+
*/
|
|
1044
|
+
export type Playlist = {
|
|
1045
|
+
uri: string;
|
|
1046
|
+
name: string;
|
|
1047
|
+
ownerName: string | null;
|
|
1048
|
+
trackCount: number | null;
|
|
1049
|
+
artworkId: string | null;
|
|
1050
|
+
};
|
|
1051
|
+
/**
|
|
1052
|
+
* One episode of a podcast. `show_name` mirrors what the gateway exposes
|
|
1053
|
+
* at episode-level so a webapp can render show + episode without a
|
|
1054
|
+
* separate fetch. `published_at_ms` is best-effort; not every gateway
|
|
1055
|
+
* surfaces it.
|
|
1056
|
+
*/
|
|
1057
|
+
export type PodcastEpisode = {
|
|
1058
|
+
uri: string;
|
|
1059
|
+
name: string;
|
|
1060
|
+
showName: string | null;
|
|
1061
|
+
durationMs: number | null;
|
|
1062
|
+
publishedAtUnixS: number | null;
|
|
1063
|
+
artworkId: string | null;
|
|
1064
|
+
};
|
|
1065
|
+
/**
|
|
1066
|
+
* One position fix from the gateway. `accuracy_m` is the 1-sigma
|
|
1067
|
+
* horizontal radius. `speed_mps` and `heading_deg` are populated when
|
|
1068
|
+
* the underlying source provides them (CLLocation on iOS does for moving
|
|
1069
|
+
* fixes; Android's FusedLocationProvider similar). `ts_ms` is the
|
|
1070
|
+
* gateway-provided fix timestamp, not the wire-arrival time.
|
|
1071
|
+
*/
|
|
1072
|
+
export type Position = {
|
|
1073
|
+
lat: number;
|
|
1074
|
+
lon: number;
|
|
1075
|
+
altM: number | null;
|
|
1076
|
+
accuracyM: number;
|
|
1077
|
+
speedMps: number | null;
|
|
1078
|
+
headingDeg: number | null;
|
|
1079
|
+
tsUnixS: number;
|
|
1080
|
+
};
|
|
1081
|
+
export type Priority = 'normal' | 'bulk' | 'background';
|
|
1082
|
+
/**
|
|
1083
|
+
* One row in the player queue. Lean cross-platform shape - gateways
|
|
1084
|
+
* that have richer per-track data still surface what fields they have.
|
|
1085
|
+
* `uri` is required because every queued item must be addressable for
|
|
1086
|
+
* `skipToIndex`. `persistent_id` is the platform-stable id when
|
|
1087
|
+
* available; webapps treat it as opaque.
|
|
1088
|
+
*/
|
|
1089
|
+
export type QueueItem = {
|
|
1090
|
+
uri: string;
|
|
1091
|
+
title: string | null;
|
|
1092
|
+
artist: string | null;
|
|
1093
|
+
artistUri: string | null;
|
|
1094
|
+
album: string | null;
|
|
1095
|
+
albumUri: string | null;
|
|
1096
|
+
artworkId: string | null;
|
|
1097
|
+
durationMs: number | null;
|
|
1098
|
+
persistentId: string | null;
|
|
1099
|
+
queued: boolean;
|
|
1100
|
+
};
|
|
1101
|
+
/**
|
|
1102
|
+
* Where in the queue a `queue({ uri })` should land. `Append` (default)
|
|
1103
|
+
* goes at the end; `Next` is play-next; `Index` is an explicit position.
|
|
1104
|
+
*/
|
|
1105
|
+
export type QueuePosition = {
|
|
1106
|
+
type: 'append';
|
|
1107
|
+
} | {
|
|
1108
|
+
type: 'next';
|
|
1109
|
+
} | {
|
|
1110
|
+
type: 'index';
|
|
1111
|
+
data: number;
|
|
1112
|
+
};
|
|
1113
|
+
/**
|
|
1114
|
+
* Resolved range the companion is about to serve. `start` and `length`
|
|
1115
|
+
* echo the corresponding `RangeSpec`; the bytes follow in the reply's
|
|
1116
|
+
* `TransferBody`.
|
|
1117
|
+
*/
|
|
1118
|
+
export type RangePart = {
|
|
1119
|
+
start: number;
|
|
1120
|
+
length: number;
|
|
1121
|
+
};
|
|
1122
|
+
/**
|
|
1123
|
+
* Half-open byte range the daemon's range proxy asks the companion
|
|
1124
|
+
* to serve. Mirrors HTTP `Range: bytes=start-end` semantics: `start`
|
|
1125
|
+
* inclusive, `length` bytes. The proxy caps the multi-range count at
|
|
1126
|
+
* the daemon edge (loopback) - companions see whatever swupdate's
|
|
1127
|
+
* delta downloader emits. Offsets are u32 because OTA artifacts are
|
|
1128
|
+
* bounded at 4 GiB end-to-end (matches `OtaBegin.expected_size`).
|
|
1129
|
+
*/
|
|
1130
|
+
export type RangeSpec = {
|
|
1131
|
+
start: number;
|
|
1132
|
+
length: number;
|
|
1133
|
+
};
|
|
1134
|
+
/**
|
|
1135
|
+
* Page of recommendation results. Gateway decides how seed + kind
|
|
1136
|
+
* interact (Spotify uses radio-style seeding, Apple Music uses curated
|
|
1137
|
+
* rails) - the daemon doesn't prescribe.
|
|
1138
|
+
*/
|
|
1139
|
+
export type RecommendationsResult = {
|
|
1140
|
+
items: Array<LibraryItem>;
|
|
1141
|
+
total: number | null;
|
|
1142
|
+
hasMore: boolean;
|
|
1143
|
+
};
|
|
1144
|
+
export type RedirectPolicy = 'follow' | 'manual' | 'error';
|
|
1145
|
+
/**
|
|
1146
|
+
* Cellular registration state - populated from iAP2 `CommunicationsUpdate`
|
|
1147
|
+
* or the companion's equivalent.
|
|
1148
|
+
*/
|
|
1149
|
+
export type RegistrationStatus = 'unknown' | 'notRegistered' | 'searching' | 'denied' | 'registeredHome' | 'registeredRoaming' | 'emergencyCallsOnly';
|
|
1150
|
+
/**
|
|
1151
|
+
* `repeat` is a typed enum (Off/All/One) shared across the player
|
|
1152
|
+
* surface and the iAP2 NowPlaying CSM / MediaSession backends, which
|
|
1153
|
+
* all expose three repeat states.
|
|
1154
|
+
*/
|
|
1155
|
+
export type RepeatMode = 'off' | 'all' | 'one';
|
|
1156
|
+
/**
|
|
1157
|
+
* Page of search results. `kinds` is the constrained kinds the search
|
|
1158
|
+
* honored (echoed back so webapps can detect ignored constraints); items
|
|
1159
|
+
* are ranked best-first.
|
|
1160
|
+
*/
|
|
1161
|
+
export type SearchResult = {
|
|
1162
|
+
items: Array<LibraryItem>;
|
|
1163
|
+
kinds: Array<ItemKind>;
|
|
1164
|
+
total: number | null;
|
|
1165
|
+
hasMore: boolean;
|
|
1166
|
+
};
|
|
1167
|
+
/**
|
|
1168
|
+
* One podcast show (parent of `PodcastEpisode`). `episode_count` is
|
|
1169
|
+
* best-effort.
|
|
1170
|
+
*/
|
|
1171
|
+
export type Show = {
|
|
1172
|
+
uri: string;
|
|
1173
|
+
name: string;
|
|
1174
|
+
publisher: string | null;
|
|
1175
|
+
episodeCount: number | null;
|
|
1176
|
+
artworkId: string | null;
|
|
1177
|
+
};
|
|
1178
|
+
/**
|
|
1179
|
+
* Three-state shuffle. iAP2 and Apple Music distinguish track-level
|
|
1180
|
+
* from album-level shuffle; companion gateways without that distinction
|
|
1181
|
+
* project to `Songs` when on. Webapps that just need an on/off signal
|
|
1182
|
+
* read `shuffle_on` (None when the underlying mode is unknown).
|
|
1183
|
+
*/
|
|
1184
|
+
export type ShuffleMode = 'off' | 'songs' | 'albums';
|
|
1185
|
+
/**
|
|
1186
|
+
* Algorithmic / radio station. `seed` is the URI the station was seeded
|
|
1187
|
+
* from when known (artist, track, etc.).
|
|
1188
|
+
*/
|
|
1189
|
+
export type Station = {
|
|
1190
|
+
uri: string;
|
|
1191
|
+
name: string;
|
|
1192
|
+
seed: string | null;
|
|
1193
|
+
artworkId: string | null;
|
|
1194
|
+
};
|
|
1195
|
+
/**
|
|
1196
|
+
* First event of an open stream. Carries the response status, headers,
|
|
1197
|
+
* and (when known) total payload size so the consumer can preallocate
|
|
1198
|
+
* or display progress. Subsequent `StreamChunk` and `StreamEnd` events
|
|
1199
|
+
* for the same `stream_id` follow.
|
|
1200
|
+
*/
|
|
1201
|
+
export type StreamBegin = {
|
|
1202
|
+
streamId: string;
|
|
1203
|
+
status: number;
|
|
1204
|
+
headers: Array<HttpHeader>;
|
|
1205
|
+
totalSize: number | null;
|
|
1206
|
+
};
|
|
1207
|
+
/**
|
|
1208
|
+
* One body chunk. Chunks arrive in order; `offset` is the byte
|
|
1209
|
+
* position of `bytes[0]` within the full body.
|
|
1210
|
+
*/
|
|
1211
|
+
export type StreamChunk = {
|
|
1212
|
+
streamId: string;
|
|
1213
|
+
offset: number;
|
|
1214
|
+
bytes: Uint8Array;
|
|
1215
|
+
};
|
|
1216
|
+
/**
|
|
1217
|
+
* Terminates a stream. After `End` no further chunks for `stream_id`
|
|
1218
|
+
* are valid and the daemon clears its routing entry.
|
|
1219
|
+
*/
|
|
1220
|
+
export type StreamEnd = {
|
|
1221
|
+
streamId: string;
|
|
1222
|
+
};
|
|
1223
|
+
/**
|
|
1224
|
+
* Stream failed mid-flight (or before the first byte). Terminal - the
|
|
1225
|
+
* daemon clears its routing entry. The `error` shape is shared with
|
|
1226
|
+
* `fetch` since the failure modes are identical.
|
|
1227
|
+
*/
|
|
1228
|
+
export type StreamError = {
|
|
1229
|
+
streamId: string;
|
|
1230
|
+
error: NetError;
|
|
1231
|
+
};
|
|
1232
|
+
export type StringField = {
|
|
1233
|
+
key: string;
|
|
1234
|
+
label: string;
|
|
1235
|
+
pattern: string | null;
|
|
1236
|
+
minLength: number | null;
|
|
1237
|
+
maxLength: number | null;
|
|
1238
|
+
default: string | null;
|
|
1239
|
+
};
|
|
1240
|
+
/**
|
|
1241
|
+
* Bool feature flags the daemon exposes to webapps. Each is true when the
|
|
1242
|
+
* surface has both a backing implementation and (where applicable) a
|
|
1243
|
+
* connected companion claiming to provide it. False = the surface will
|
|
1244
|
+
* respond `Unsupported` or `Unimplemented` to verbs.
|
|
1245
|
+
*/
|
|
1246
|
+
export type SurfaceAvailability = {
|
|
1247
|
+
geo: boolean;
|
|
1248
|
+
notifications: boolean;
|
|
1249
|
+
netFetch: boolean;
|
|
1250
|
+
netWs: boolean;
|
|
1251
|
+
audioTts: boolean;
|
|
1252
|
+
lyrics: boolean;
|
|
1253
|
+
};
|
|
1254
|
+
/**
|
|
1255
|
+
* Wall clock + locale snapshot. `wall_clock_unix_s` is the gateway's
|
|
1256
|
+
* (or iAP2 device's) claimed "now" in unix-epoch seconds - webapps
|
|
1257
|
+
* reading time should use the device clock if any but use this as the
|
|
1258
|
+
* trust anchor on first arrival.
|
|
1259
|
+
*
|
|
1260
|
+
* Two zone-identification paths coexist: companion gateways send
|
|
1261
|
+
* `tz_iana` (an IANA zone identifier like `America/Denver`) while iAP2
|
|
1262
|
+
* `DeviceTimeUpdate` only exposes numeric `utc_offset_minutes` plus a
|
|
1263
|
+
* separate `dst_offset_minutes`. Webapps prefer `tz_iana` when present
|
|
1264
|
+
* and fall back to the offset pair.
|
|
1265
|
+
*/
|
|
1266
|
+
export type TimeInfo = {
|
|
1267
|
+
tzIana: string | null;
|
|
1268
|
+
locale: string | null;
|
|
1269
|
+
wallClockUnixS: number | null;
|
|
1270
|
+
utcOffsetMinutes: number | null;
|
|
1271
|
+
dstOffsetMinutes: number | null;
|
|
1272
|
+
};
|
|
1273
|
+
/**
|
|
1274
|
+
* A track with resolved album/artist metadata, used by library search
|
|
1275
|
+
* and browse results. For live now-playing state see `MediaItem`.
|
|
1276
|
+
*/
|
|
1277
|
+
export type Track = {
|
|
1278
|
+
id: string;
|
|
1279
|
+
name: string;
|
|
1280
|
+
album: Album;
|
|
1281
|
+
/**
|
|
1282
|
+
* Primary credited artist.
|
|
1283
|
+
*/
|
|
1284
|
+
artist: Artist;
|
|
1285
|
+
/**
|
|
1286
|
+
* All credited artists, in order.
|
|
1287
|
+
*/
|
|
1288
|
+
artists: Array<Artist>;
|
|
1289
|
+
duration_ms: number;
|
|
1290
|
+
/**
|
|
1291
|
+
* Opaque artwork asset id; pass to `asset.get` for the bytes.
|
|
1292
|
+
*/
|
|
1293
|
+
image_id: string;
|
|
1294
|
+
/**
|
|
1295
|
+
* Whether the track is saved in the user's library.
|
|
1296
|
+
*/
|
|
1297
|
+
saved: boolean;
|
|
1298
|
+
};
|
|
1299
|
+
export type TtlRetention = {
|
|
1300
|
+
seconds: number;
|
|
1301
|
+
};
|
|
1302
|
+
export type TunnelClosed = {
|
|
1303
|
+
tunnelId: string;
|
|
1304
|
+
reason: string | null;
|
|
1305
|
+
};
|
|
1306
|
+
export type TunnelData = {
|
|
1307
|
+
tunnelId: string;
|
|
1308
|
+
bytes: Uint8Array;
|
|
1309
|
+
};
|
|
1310
|
+
export type TunnelError = {
|
|
1311
|
+
type: 'connectFailed';
|
|
1312
|
+
data: {
|
|
1313
|
+
reason: string;
|
|
1314
|
+
};
|
|
1315
|
+
} | {
|
|
1316
|
+
type: 'permissionDenied';
|
|
1317
|
+
} | {
|
|
1318
|
+
type: 'unavailable';
|
|
1319
|
+
};
|
|
1320
|
+
/**
|
|
1321
|
+
* One TTS voice the companion's audio backend can speak as. `id` is
|
|
1322
|
+
* platform-opaque (Apple/Android voice id); `locale` is BCP-47.
|
|
1323
|
+
*/
|
|
1324
|
+
export type VoiceDescriptor = {
|
|
1325
|
+
id: string;
|
|
1326
|
+
name: string;
|
|
1327
|
+
locale: string;
|
|
1328
|
+
};
|
|
1329
|
+
/**
|
|
1330
|
+
* Why dispatch declined to act on a `VoiceDispatch`. The companion
|
|
1331
|
+
* surfaces these to the user (toast / UI hint); the daemon does not
|
|
1332
|
+
* otherwise retain state about the failure.
|
|
1333
|
+
*/
|
|
1334
|
+
export type VoiceDispatchErrorCode = 'webappNotInstalled' | 'webappNotActive' | 'webappRefused' | 'notDispatchable' | 'playbackFailed' | 'internal';
|
|
1335
|
+
/**
|
|
1336
|
+
* Where the daemon actually routed a successful dispatch. Carried back
|
|
1337
|
+
* to the companion so it can render the right confirmation UI.
|
|
1338
|
+
*/
|
|
1339
|
+
export type VoiceDispatchTarget = 'stockPlayback' | 'activeWebapp' | 'webappSwitch';
|
|
1340
|
+
/**
|
|
1341
|
+
* Domain errors emitted by any webapp surface (gateway- or client-side).
|
|
1342
|
+
* Single catalog: both protocols speak the same variant set.
|
|
1343
|
+
*/
|
|
1344
|
+
export type WebappError = {
|
|
1345
|
+
type: 'webappNotFound';
|
|
1346
|
+
data: {
|
|
1347
|
+
id: string;
|
|
1348
|
+
};
|
|
1349
|
+
} | {
|
|
1350
|
+
type: 'cannotUninstallBuiltin';
|
|
1351
|
+
data: {
|
|
1352
|
+
id: string;
|
|
1353
|
+
};
|
|
1354
|
+
} | {
|
|
1355
|
+
type: 'idReserved';
|
|
1356
|
+
data: {
|
|
1357
|
+
id: string;
|
|
1358
|
+
};
|
|
1359
|
+
} | {
|
|
1360
|
+
type: 'extractedTooLarge';
|
|
1361
|
+
data: {
|
|
1362
|
+
max_bytes: number;
|
|
1363
|
+
};
|
|
1364
|
+
} | {
|
|
1365
|
+
type: 'zipMalformed';
|
|
1366
|
+
data: {
|
|
1367
|
+
reason: string;
|
|
1368
|
+
};
|
|
1369
|
+
} | {
|
|
1370
|
+
type: 'missingIndexHtml';
|
|
1371
|
+
} | {
|
|
1372
|
+
type: 'invalidManifest';
|
|
1373
|
+
data: {
|
|
1374
|
+
reason: string;
|
|
1375
|
+
};
|
|
1376
|
+
} | {
|
|
1377
|
+
type: 'iconNotAvailable';
|
|
1378
|
+
data: {
|
|
1379
|
+
id: string;
|
|
1380
|
+
};
|
|
1381
|
+
} | {
|
|
1382
|
+
type: 'unknownConfigKey';
|
|
1383
|
+
data: {
|
|
1384
|
+
key: string;
|
|
1385
|
+
};
|
|
1386
|
+
} | {
|
|
1387
|
+
type: 'invalidConfigValue';
|
|
1388
|
+
data: {
|
|
1389
|
+
key: string;
|
|
1390
|
+
reason: string;
|
|
1391
|
+
};
|
|
1392
|
+
} | {
|
|
1393
|
+
type: 'internal';
|
|
1394
|
+
data: {
|
|
1395
|
+
reason: string;
|
|
1396
|
+
};
|
|
1397
|
+
};
|
|
1398
|
+
export type WebappInfo = {
|
|
1399
|
+
id: string;
|
|
1400
|
+
name: string;
|
|
1401
|
+
source: WebappSource;
|
|
1402
|
+
role: WebappRole;
|
|
1403
|
+
version: string;
|
|
1404
|
+
description: string | null;
|
|
1405
|
+
iconAvailable: boolean;
|
|
1406
|
+
iconMime: string | null;
|
|
1407
|
+
/**
|
|
1408
|
+
* icon bytes, inlined on the gateway list so the companion never round-trips
|
|
1409
|
+
* a separate fetch per app. omitted on the on-device client list.
|
|
1410
|
+
*/
|
|
1411
|
+
icon?: Uint8Array | null;
|
|
1412
|
+
config: Array<ConfigField>;
|
|
1413
|
+
permissions: Array<string>;
|
|
1414
|
+
/**
|
|
1415
|
+
* Plain-English description of the voice intents the webapp wants
|
|
1416
|
+
* WEBAPP_INTENT routing for. Companion-side NLU folds this into the
|
|
1417
|
+
* "currently active extensions" section of the system prompt at
|
|
1418
|
+
* inference, which is what makes WEBAPP_INTENT emission context-aware.
|
|
1419
|
+
* `None` opts the webapp out of voice integration.
|
|
1420
|
+
*/
|
|
1421
|
+
voiceGrammar: string | null;
|
|
1422
|
+
/**
|
|
1423
|
+
* Declared art render sizes; the companion warms exactly these. `None`
|
|
1424
|
+
* means the canonical `{248, 96}` default applies.
|
|
1425
|
+
*/
|
|
1426
|
+
art: ArtProfile | null;
|
|
1427
|
+
};
|
|
1428
|
+
/**
|
|
1429
|
+
* On-disk `manifest.json` shape. Read from the bundle at install time
|
|
1430
|
+
* and validated; the resulting metadata projects to `WebappInfo` for
|
|
1431
|
+
* the wire.
|
|
1432
|
+
*/
|
|
1433
|
+
export type WebappManifest = {
|
|
1434
|
+
id: string;
|
|
1435
|
+
name: string;
|
|
1436
|
+
version: string;
|
|
1437
|
+
description: string | null;
|
|
1438
|
+
icon: string | null;
|
|
1439
|
+
role: WebappRole;
|
|
1440
|
+
config: Array<ConfigField>;
|
|
1441
|
+
permissions: Array<string>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Optional plain-English description of the voice commands this
|
|
1444
|
+
* webapp wants WEBAPP_INTENT routing for. The companion's NLU folds
|
|
1445
|
+
* the grammars of all installed-and-active webapps into the system
|
|
1446
|
+
* prompt at inference. Webapps that don't declare a grammar opt out
|
|
1447
|
+
* of voice integration.
|
|
1448
|
+
*/
|
|
1449
|
+
voiceGrammar: string | null;
|
|
1450
|
+
/**
|
|
1451
|
+
* Declared art render sizes. Omitted falls back to `{248, 96}`.
|
|
1452
|
+
*/
|
|
1453
|
+
art?: ArtProfile | null;
|
|
1454
|
+
};
|
|
1455
|
+
/**
|
|
1456
|
+
* A webapp's launcher visibility. `Standard` shows up in user-facing
|
|
1457
|
+
* listings (the hub grid, etc); `Launcher` is itself a launcher and is
|
|
1458
|
+
* hidden from those listings. The daemon filters `Launcher` bundles
|
|
1459
|
+
* out of `client.webapp.list`; the gateway list keeps everything.
|
|
1460
|
+
*/
|
|
1461
|
+
export type WebappRole = 'standard' | 'launcher';
|
|
1462
|
+
export type WebappSource = 'builtin' | 'installed';
|
|
1463
|
+
export type WsError = {
|
|
1464
|
+
type: 'connectFailed';
|
|
1465
|
+
data: {
|
|
1466
|
+
reason: string;
|
|
1467
|
+
};
|
|
1468
|
+
} | {
|
|
1469
|
+
type: 'frameTooLarge';
|
|
1470
|
+
} | {
|
|
1471
|
+
type: 'gatewayDisconnected';
|
|
1472
|
+
} | {
|
|
1473
|
+
type: 'protocolError';
|
|
1474
|
+
data: {
|
|
1475
|
+
reason: string;
|
|
1476
|
+
};
|
|
1477
|
+
};
|
|
1478
|
+
export type WsFrame = {
|
|
1479
|
+
type: 'text';
|
|
1480
|
+
data: string;
|
|
1481
|
+
} | {
|
|
1482
|
+
type: 'binary';
|
|
1483
|
+
data: Uint8Array;
|
|
1484
|
+
};
|
|
1485
|
+
//# sourceMappingURL=shared.d.ts.map
|