@deadair/plugin-sdk 0.39.1 → 0.40.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 CHANGED
@@ -27,6 +27,7 @@ A plugin extends deadair by declaring capabilities:
27
27
  | `almanac` | say what happened on a date: a month and a day in, entries out |
28
28
  | `scrobble` | report what the station played to somebody else's service |
29
29
  | `messaging` | talk to people on a chat platform: messages in, messages out |
30
+ | `output` | play the station on a speaker: a mount's URL in, a device plays |
30
31
  | `oauth` | hold operator tokens, obtained through the host's redirect |
31
32
 
32
33
  There is no second axis. `capabilities` is the whole declaration, and the host
@@ -451,6 +452,57 @@ is a heartbeat timer, and a listener that throws is logged rather than allowed t
451
452
  reach the event loop. The socket is the shape ServerKit's Socket Mode and Gateway
452
453
  clients call `SocketLike`, so `connect: url => host.socket(url)` is all either needs.
453
454
 
455
+ ## When your device speaks its own protocol
456
+
457
+ Some devices are neither HTTP nor a WebSocket: a Chromecast is driven over a TLS
458
+ connection to port 8009 carrying its own length-prefixed messages. `host.tls`
459
+ opens one, under the same policy again:
460
+
461
+ ```ts
462
+ const conn = await host.tls('tls://192.168.1.20:8009', { verifyCertificate: false });
463
+ conn.onData(bytes => this.reader.push(bytes)); // bytes, not frames: reassemble your own
464
+ conn.onClose(reason => this.reconnectLater(reason));
465
+ conn.send(frame);
466
+ ```
467
+
468
+ Requires the `tls` permission. The URL is `tls://host:port` and the port is
469
+ required, since `tls:` has no default. The host is checked against
470
+ `permissions.network` as the `https:` URL on the same host and port, and a
471
+ connect costs one token from that host's rate bucket.
472
+
473
+ `verifyCertificate: false` is for a device on the operator's own network that
474
+ presents a certificate no public root signs. It is honoured only for an address
475
+ that came from your settings (a `{ fromConfig }` entry), because that is the
476
+ operator saying "this device is mine". For a host your manifest names, or one
477
+ reached through `network.open`, it is refused with `forbidden`.
478
+
479
+ Like a socket, the connection outlives the call that opened it: a plugin may hold
480
+ only a limited number at once (more than sockets, since a speaker plugin holds one
481
+ per device), and disposing the plugin closes every one without calling your close
482
+ listeners. `send` after a close does nothing, and a listener that throws is logged.
483
+
484
+ ## When you need to find devices on the network
485
+
486
+ A plugin that drives devices on the operator's network can look for them rather
487
+ than asking for every address. `host.discover` runs an mDNS or SSDP query from the
488
+ host, which owns the multicast sockets so no plugin binds those ports itself:
489
+
490
+ ```ts
491
+ const casts = await host.discover({ protocol: 'mdns', service: '_googlecast._tcp' });
492
+ // [{ name, address: '192.168.1.148', port: 8009, txt: { fn: 'Kitchen speaker', md: 'Google Home Mini' } }]
493
+ const renderers = await host.discover({ protocol: 'ssdp', searchTarget: 'urn:schemas-upnp-org:device:MediaRenderer:1' });
494
+ // [{ name: 'uuid:...', address: '192.168.1.176', location: 'http://192.168.1.176:44667/description.xml', server: '...' }]
495
+ ```
496
+
497
+ Each query must be listed exactly in `permissions.discovery`. Every address that
498
+ answers (and the host of an SSDP `location`) is then reachable by `fetch`, `socket`
499
+ and `tls` as though the operator had typed it in, including `verifyCertificate:
500
+ false`, until the plugin is reinitialised.
501
+
502
+ An empty answer is normal: a station in a container on a bridge network cannot see
503
+ multicast at all. Keep working from the addresses you were given, and do not
504
+ report "nothing found" as a fault.
505
+
454
506
  ## When your audio needs a helper to fetch it
455
507
 
456
508
  Almost every provider answers `resolveStreamUrl` out of its own head: it knows a
@@ -896,6 +948,49 @@ takesArgs }`) each time the host starts listening on your plugin, for a platform
896
948
  that lists commands in its own interface; overwrite, don't append. Leave it out
897
949
  and people type the commands as they always could.
898
950
 
951
+ ## Playing the station on a speaker
952
+
953
+ An `output` plugin puts the station on a Chromecast, a Sonos, a BluOS player or
954
+ anything else that can be told a URL and will fetch it. Five methods:
955
+
956
+ ```ts
957
+ async listDevices(): Promise<OutputDevice[]> {
958
+ return this.configured.map(row => ({
959
+ id: row.address.toLowerCase(), name: row.name, address: row.address,
960
+ accepts: ['audio/mpeg', 'audio/aac'], followsMetadata: true,
961
+ }));
962
+ }
963
+
964
+ async play({ deviceId, url, contentType, metadata }: OutputPlayRequest): Promise<void> {
965
+ await this.device(deviceId).load(url, contentType, metadata); // resolves when accepted
966
+ }
967
+ ```
968
+
969
+ `updateMetadata`, `stop` and `status` complete it. Four things are easy to get wrong.
970
+
971
+ **The speaker fetches the stream.** You are handed the mount's URL and its
972
+ content type and pass them on. Never build a station URL and never pick a format:
973
+ the host chooses the mount from what your device `accepts`, so list only what it
974
+ really plays (a Sonos takes MP3 and AAC for a radio URL and nothing else).
975
+
976
+ **The host owns retrying.** It remembers every cast it started, asks `status`
977
+ how each is doing, and plays one again when a device drops it. So `play`
978
+ resolves when the device ACCEPTED the command, not when sound comes out, and
979
+ you never reconnect a stream on your own.
980
+
981
+ **Warming up is not failing.** A live stream takes seconds to start. Report it
982
+ as `opening` or `buffering`, and a device that does not answer as `unreachable`
983
+ from `status` rather than a throw. List a configured device that does not
984
+ answer anyway: the operator asked for it by name.
985
+
986
+ **Stop means stop.** A speaker playing the station is a listener, and one left
987
+ playing holds the station's audience open. `stop` is idempotent: answer it for
988
+ a device that was not playing ours.
989
+
990
+ A device that only speaks a protocol where the sender streams the audio itself
991
+ (AirPlay audio, Bluetooth) cannot be an output: there is no URL to hand it, and
992
+ the station encodes nothing in its own process.
993
+
899
994
  ## Music providers
900
995
 
901
996
  A `music-provider` declares any subset of four sub-capabilities and lists the
@@ -44,6 +44,7 @@ import type { NarrationPart, NarrationPiece, NarrationPiecesQuery, NarrationSeri
44
44
  import type { NewsFeedDescriptor, NewsItem, NewsQuery } from './capabilities/news.js';
45
45
  import type { PodcastAudio, PodcastDirectoryEntry, PodcastDirectoryQuery, PodcastEpisode, PodcastEpisodesQuery, PodcastShow } from './capabilities/podcast.js';
46
46
  import type { InboundMessage, MessagingAction, MessagingAnnounceTarget, MessagingButton, MessagingCommand, MessagingReceiveQuery, MessagingReceiveResult, MessagingSendResult, MessagingSender, OutboundMessage } from './capabilities/messaging.js';
47
+ import type { OutputDevice, OutputMetadata, OutputMetadataRequest, OutputPlayRequest, OutputStatus } from './capabilities/output.js';
47
48
  import type { ScrobblePlay, ScrobbleRejection, ScrobbleResult } from './capabilities/scrobble.js';
48
49
  import type { SearchQuery, SearchResult } from './capabilities/search.js';
49
50
  import type { ArtistTrack, SimilarArtist } from './capabilities/similarity.js';
@@ -53,7 +54,7 @@ import type { GetPlaylistTracksOptions, ListPlaylistsOptions, PlaybackState, Pro
53
54
  import type { LlmMessage, LlmModelInfo, LlmRequest, LlmResult, LlmToolCall, LlmToolDeclaration, LlmUsage } from './capabilities/llm.js';
54
55
  import type { SpeechLimits, SpeechRequest, SpeechVoice } from './capabilities/speech.js';
55
56
  import type { ConfigField, ConfigFieldColumn, ConfigFieldOption, ConfigFieldPreset } from './plugin.config.fields.js';
56
- import type { PlaylistTracksRequest, PluginSocketOptions, TrackFetchRequest, TrackFetchSession } from './plugin.host.js';
57
+ import type { DiscoveredService, DiscoveryOptions, DiscoveryQuery, PlaylistTracksRequest, PluginSocketOptions, PluginTlsOptions, TrackFetchRequest, TrackFetchSession } from './plugin.host.js';
57
58
  import type { PluginConnectionResult } from './plugin.lifecycle.js';
58
59
  import type { PluginManifest } from './plugin.manifest.js';
59
60
  import type { NetworkPermissionFromConfig, NetworkPermissionHost, PluginGrantRequest, PluginPermissions } from './plugin.permissions.js';
@@ -121,6 +122,10 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
121
122
  TrackFetchRequest: IsJsonSafe<TrackFetchRequest>;
122
123
  PlaylistTracksRequest: IsJsonSafe<PlaylistTracksRequest>;
123
124
  PluginSocketOptions: IsJsonSafe<PluginSocketOptions>;
125
+ PluginTlsOptions: IsJsonSafe<PluginTlsOptions>;
126
+ DiscoveryQuery: IsJsonSafe<DiscoveryQuery>;
127
+ DiscoveryOptions: IsJsonSafe<DiscoveryOptions>;
128
+ DiscoveredService: IsJsonSafe<DiscoveredService>;
124
129
  SearchTracksOptions: IsJsonSafe<SearchTracksOptions>;
125
130
  ListPlaylistsOptions: IsJsonSafe<ListPlaylistsOptions>;
126
131
  GetPlaylistTracksOptions: IsJsonSafe<GetPlaylistTracksOptions>;
@@ -194,6 +199,11 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
194
199
  MessagingSendResult: IsJsonSafe<MessagingSendResult>;
195
200
  MessagingAnnounceTarget: IsJsonSafe<MessagingAnnounceTarget>;
196
201
  MessagingCommand: IsJsonSafe<MessagingCommand>;
202
+ OutputDevice: IsJsonSafe<OutputDevice>;
203
+ OutputMetadata: IsJsonSafe<OutputMetadata>;
204
+ OutputPlayRequest: IsJsonSafe<OutputPlayRequest>;
205
+ OutputMetadataRequest: IsJsonSafe<OutputMetadataRequest>;
206
+ OutputStatus: IsJsonSafe<OutputStatus>;
197
207
  SpeechLimits: IsJsonSafe<SpeechLimits>;
198
208
  }>;
199
209
  /**
@@ -201,7 +211,7 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
201
211
  * registry-coverage test can compare it against what is actually exported
202
212
  * from the boundary source files.
203
213
  */
204
- export declare const JSON_SAFE_PAYLOAD_TYPES: readonly ["PluginConnectionResult", "PluginPermissions", "NetworkPermissionHost", "NetworkPermissionFromConfig", "PluginGrantRequest", "ConfigField", "ConfigFieldOption", "ConfigFieldColumn", "ConfigFieldPreset", "PluginManifest", "ProviderTrack", "ProviderPlaylist", "ProviderStream", "TrackFetchSession", "TrackFetchRequest", "PlaylistTracksRequest", "PluginSocketOptions", "SearchTracksOptions", "ListPlaylistsOptions", "GetPlaylistTracksOptions", "PlaybackState", "TrackRef", "ArtistRef", "AlbumRef", "ExternalId", "ExternalLink", "SourceDocument", "TrackEnrichment", "ArtistEnrichment", "AlbumEnrichment", "SpeechRequest", "SpeechVoice", "LlmMessage", "LlmToolDeclaration", "LlmToolCall", "LlmUsage", "LlmRequest", "LlmResult", "LlmModelInfo", "AnalysisRef", "AudioJoin", "AudioOverlay", "AudioTranscode", "TrackCuePoints", "TrackLoudness", "TrackTaggedLoudness", "TrackAnalysis", "ChartDescriptor", "ChartQuery", "ChartEntry", "NewsFeedDescriptor", "NewsQuery", "NewsItem", "NarrationSeries", "NarrationPiece", "NarrationPart", "NarrationText", "NarrationPiecesQuery", "NarrationTextQuery", "PodcastShow", "PodcastAudio", "PodcastEpisode", "PodcastEpisodesQuery", "PodcastDirectoryQuery", "PodcastDirectoryEntry", "SimilarArtist", "ArtistTrack", "SearchQuery", "SearchResult", "WeatherQuery", "WeatherConditions", "WeatherDay", "WeatherReading", "AlmanacQuery", "AlmanacSubject", "AlmanacEntry", "AlmanacDay", "ScrobblePlay", "ScrobbleRejection", "ScrobbleResult", "MessagingSender", "MessagingAction", "MessagingButton", "InboundMessage", "MessagingReceiveQuery", "MessagingReceiveResult", "OutboundMessage", "MessagingSendResult", "MessagingAnnounceTarget", "MessagingCommand", "SpeechLimits"];
214
+ export declare const JSON_SAFE_PAYLOAD_TYPES: readonly ["PluginConnectionResult", "PluginPermissions", "NetworkPermissionHost", "NetworkPermissionFromConfig", "PluginGrantRequest", "ConfigField", "ConfigFieldOption", "ConfigFieldColumn", "ConfigFieldPreset", "PluginManifest", "ProviderTrack", "ProviderPlaylist", "ProviderStream", "TrackFetchSession", "TrackFetchRequest", "PlaylistTracksRequest", "PluginSocketOptions", "PluginTlsOptions", "DiscoveryOptions", "DiscoveredService", "SearchTracksOptions", "ListPlaylistsOptions", "GetPlaylistTracksOptions", "PlaybackState", "TrackRef", "ArtistRef", "AlbumRef", "ExternalId", "ExternalLink", "SourceDocument", "TrackEnrichment", "ArtistEnrichment", "AlbumEnrichment", "SpeechRequest", "SpeechVoice", "LlmMessage", "LlmToolDeclaration", "LlmToolCall", "LlmUsage", "LlmRequest", "LlmResult", "LlmModelInfo", "AnalysisRef", "AudioJoin", "AudioOverlay", "AudioTranscode", "TrackCuePoints", "TrackLoudness", "TrackTaggedLoudness", "TrackAnalysis", "ChartDescriptor", "ChartQuery", "ChartEntry", "NewsFeedDescriptor", "NewsQuery", "NewsItem", "NarrationSeries", "NarrationPiece", "NarrationPart", "NarrationText", "NarrationPiecesQuery", "NarrationTextQuery", "PodcastShow", "PodcastAudio", "PodcastEpisode", "PodcastEpisodesQuery", "PodcastDirectoryQuery", "PodcastDirectoryEntry", "SimilarArtist", "ArtistTrack", "SearchQuery", "SearchResult", "WeatherQuery", "WeatherConditions", "WeatherDay", "WeatherReading", "AlmanacQuery", "AlmanacSubject", "AlmanacEntry", "AlmanacDay", "ScrobblePlay", "ScrobbleRejection", "ScrobbleResult", "MessagingSender", "MessagingAction", "MessagingButton", "InboundMessage", "MessagingReceiveQuery", "MessagingReceiveResult", "OutboundMessage", "MessagingSendResult", "MessagingAnnounceTarget", "MessagingCommand", "OutputDevice", "OutputMetadata", "OutputPlayRequest", "OutputMetadataRequest", "OutputStatus", "SpeechLimits"];
205
215
  /**
206
216
  * Boundary interfaces that are deliberately NOT payloads: they describe
207
217
  * methods, so they carry functions by definition and can never be JSON-safe.
@@ -211,7 +221,7 @@ export declare const JSON_SAFE_PAYLOAD_TYPES: readonly ["PluginConnectionResult"
211
221
  * interfaces explicitly is what makes "is this a payload or a contract?" a
212
222
  * conscious decision for anyone adding one, rather than a silent omission.
213
223
  */
214
- export declare const BOUNDARY_METHOD_TYPES: readonly ["PluginLogger", "PluginStorage", "PluginSecrets", "PluginConfigAccess", "PluginOAuth", "PluginEvents", "PluginTrackFetcher", "PluginSocket", "PluginHost", "PluginLifecycle", "MusicProviderCatalog", "MusicProviderStream", "MusicProviderSteer", "MusicProviderOAuth", "MusicProvider", "EnrichmentProvider", "SpeechPluginInstance", "LlmPluginInstance", "AnalysisProvider", "MixerProvider", "TranscodeProvider", "ChartsProvider", "NewsProvider", "NarrationProvider", "PodcastProvider", "SimilarityProvider", "SearchProvider", "WeatherProvider", "AlmanacProvider", "ScrobbleProvider", "MessagingProvider"];
224
+ export declare const BOUNDARY_METHOD_TYPES: readonly ["PluginLogger", "PluginStorage", "PluginSecrets", "PluginConfigAccess", "PluginOAuth", "PluginEvents", "PluginTrackFetcher", "PluginSocket", "PluginTlsSocket", "PluginHost", "PluginLifecycle", "MusicProviderCatalog", "MusicProviderStream", "MusicProviderSteer", "MusicProviderOAuth", "MusicProvider", "EnrichmentProvider", "SpeechPluginInstance", "LlmPluginInstance", "AnalysisProvider", "MixerProvider", "TranscodeProvider", "ChartsProvider", "NewsProvider", "NarrationProvider", "PodcastProvider", "SimilarityProvider", "SearchProvider", "WeatherProvider", "AlmanacProvider", "ScrobbleProvider", "MessagingProvider", "OutputProvider"];
215
225
  /**
216
226
  * Boundary interfaces that deliberately carry a LIVE object, and so are neither
217
227
  * payloads nor method contracts.
@@ -1 +1 @@
1
- {"version":3,"file":"boundary.json.safe.d.ts","sourceRoot":"","sources":["../src/boundary.json.safe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"boundary.json.safe.d.ts","sourceRoot":"","sources":["../src/boundary.json.safe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * The `output` kind. An output plugin puts the station on a speaker somewhere
3
+ * else: a Chromecast, a Sonos, a BluOS player, a DLNA renderer.
4
+ *
5
+ * ## The speaker fetches the stream, and nothing here carries audio
6
+ *
7
+ * Every speaker this describes is a PULL speaker: it is told a URL and fetches
8
+ * the station's mount itself, the way any other listener does. So the contract
9
+ * is commands and status, never bytes, and the station's rule that no audio is
10
+ * decoded or mixed in Node holds without an exception for it.
11
+ *
12
+ * That is also the line this capability does not cross. A PUSH protocol, where
13
+ * the sender encodes the audio and streams it to the device (AirPlay audio,
14
+ * Bluetooth), cannot implement it: there is no URL to hand over, and building
15
+ * one would put an encoder in the station's process. A speaker that only
16
+ * speaks such a protocol is out of reach of this capability on purpose, not by
17
+ * omission.
18
+ *
19
+ * ## A device is a listener
20
+ *
21
+ * A speaker playing the station is one more connection to the mount, and the
22
+ * station counts it as an audience like any other. That is the point rather
23
+ * than a side effect: a station with nobody listening may stand down, and a
24
+ * kitchen speaker is somebody listening. It is also why `stop` has to mean it:
25
+ * a device left playing holds the audience open.
26
+ *
27
+ * ## What the host decides, and what the plugin does
28
+ *
29
+ * The host chooses WHICH mount a device is given, from the content types the
30
+ * device says it {@link OutputDevice.accepts}, and builds the URL from the
31
+ * station's public address. A plugin never builds a station URL and never
32
+ * picks a format: it is handed both and passes them on. The host also owns
33
+ * whether a cast is still wanted: it remembers what it started, asks
34
+ * {@link OutputProvider.status} how each one is doing, and plays it again when
35
+ * a device drops it. So a plugin does not retry on its own, and should not:
36
+ * two things deciding to reconnect is one thing reconnecting twice.
37
+ *
38
+ * ## Status is the device's word, read honestly
39
+ *
40
+ * A speaker takes seconds to start a live stream, and reports a stream it has
41
+ * not started yet in whatever way it likes. {@link OutputPhase} is the shared
42
+ * vocabulary for that, and the rule for using it is that warming up is
43
+ * `opening` or `buffering`, never a failure, and a device that did not answer
44
+ * at all is `unreachable` rather than an exception: the host lists it all the
45
+ * same, so an operator sees the speaker they configured and why it is quiet.
46
+ */
47
+ /**
48
+ * Where a device is, as far as playing the station goes.
49
+ *
50
+ * - `idle`: answering, and playing nothing of ours.
51
+ * - `opening`: told to play, and has not started fetching yet.
52
+ * - `buffering`: fetching, and not yet making sound.
53
+ * - `playing`: making the station's sound.
54
+ * - `stopped`: was playing ours and has stopped, by request or on its own.
55
+ * - `unreachable`: did not answer.
56
+ */
57
+ export type OutputPhase = 'idle' | 'opening' | 'buffering' | 'playing' | 'stopped' | 'unreachable';
58
+ /** One speaker a plugin can play the station on. */
59
+ export interface OutputDevice {
60
+ /**
61
+ * Stable and unique within this plugin, across restarts: the host stores it
62
+ * to resume a cast after a reboot, so an id that changes is a cast that is
63
+ * forgotten. Compare them case-insensitively if your sources disagree on
64
+ * case; the host does not.
65
+ */
66
+ id: string;
67
+ /** What the operator calls it, as the device or the settings name it. */
68
+ name: string;
69
+ /** The make or model, where the device says. */
70
+ model?: string;
71
+ /**
72
+ * How the plugin reaches it, for the operator to recognise rather than for
73
+ * anybody to dial: an address, or a URL.
74
+ */
75
+ address: string;
76
+ /**
77
+ * The protocol it is driven over, as a short word (`chromecast`, `upnp`,
78
+ * `bluos`), for a plugin that speaks several. Shown, never interpreted.
79
+ */
80
+ protocol?: string;
81
+ /**
82
+ * The content types it can play, as MIME types (`audio/mpeg`, `audio/aac`,
83
+ * `audio/ogg`, `audio/flac`, `application/vnd.apple.mpegurl`). The host
84
+ * offers a device only the mounts it lists, so be honest: a Sonos takes MP3
85
+ * and AAC for a radio URL and nothing else, and listing more is a cast that
86
+ * fails on the device rather than here. Never empty: MP3 is the floor.
87
+ */
88
+ accepts: string[];
89
+ /**
90
+ * Whether {@link OutputProvider.updateMetadata} changes what the device
91
+ * shows. `false` for a device that reads the stream's own titles, or one that
92
+ * can only be told at the start; the host then does not call it.
93
+ */
94
+ followsMetadata: boolean;
95
+ }
96
+ /** What a device shows while it plays the station. */
97
+ export interface OutputMetadata {
98
+ /** The line it shows largest: the record, or the station's name. */
99
+ title: string;
100
+ /** The line under it: the artist, or the show. */
101
+ subtitle?: string;
102
+ /** An absolute `http(s)` URL the device fetches itself. */
103
+ artworkUrl?: string;
104
+ }
105
+ /** Play the station on one device. */
106
+ export interface OutputPlayRequest {
107
+ /** An {@link OutputDevice.id} this plugin listed. */
108
+ deviceId: string;
109
+ /** The mount, absolute, on the station's public address. Pass it on as it is. */
110
+ url: string;
111
+ /** The mount's content type, one the device said it {@link OutputDevice.accepts}. */
112
+ contentType: string;
113
+ /** What to show to begin with. */
114
+ metadata: OutputMetadata;
115
+ }
116
+ /** Change what a device shows, without restarting what it plays. */
117
+ export interface OutputMetadataRequest {
118
+ deviceId: string;
119
+ metadata: OutputMetadata;
120
+ }
121
+ /** How one device is doing. */
122
+ export interface OutputStatus {
123
+ deviceId: string;
124
+ phase: OutputPhase;
125
+ /** The URL it is playing, where it says; how the host tells ours from somebody else's. */
126
+ url?: string;
127
+ /** A sentence for the operator when the phase needs one, such as why it is unreachable. */
128
+ detail?: string;
129
+ }
130
+ /**
131
+ * The `output` capability's methods.
132
+ *
133
+ * Every method but {@link listDevices} names a device by the id
134
+ * {@link listDevices} gave it, and should answer for an id it does not know by
135
+ * throwing a `PluginError` with code `config`: the operator removed a speaker
136
+ * the host still remembered, and that is theirs to see.
137
+ */
138
+ export interface OutputProvider {
139
+ /**
140
+ * Every speaker this plugin can play on: the ones the operator configured,
141
+ * and any it found. A configured device that does not answer is still
142
+ * listed, because the operator asked for it by name.
143
+ */
144
+ listDevices(): Promise<OutputDevice[]>;
145
+ /**
146
+ * Start the station on a device, replacing whatever it was playing.
147
+ *
148
+ * Resolve once the device has ACCEPTED the command, not once it is making
149
+ * sound: starting a live stream takes seconds, and the host reads progress
150
+ * through {@link status}. Throw when the device refused or could not be
151
+ * reached.
152
+ */
153
+ play(request: OutputPlayRequest): Promise<void>;
154
+ /** Change what a device shows. Called only for a device that {@link OutputDevice.followsMetadata}. */
155
+ updateMetadata(request: OutputMetadataRequest): Promise<void>;
156
+ /**
157
+ * Stop the station on a device. Resolve when it has stopped, or when it was
158
+ * not playing ours to begin with: stopping is idempotent.
159
+ */
160
+ stop(deviceId: string): Promise<void>;
161
+ /**
162
+ * How a device is doing right now. Answer `unreachable` rather than
163
+ * throwing when it does not answer; throw only for an id this plugin does
164
+ * not know.
165
+ */
166
+ status(deviceId: string): Promise<OutputStatus>;
167
+ }
168
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/capabilities/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAEnG,oDAAoD;AACpD,MAAM,WAAW,YAAY;IACzB;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC3B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAC9B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,QAAQ,EAAE,cAAc,CAAC;CAC5B;AAED,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;CAC5B;AAED,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,0FAA0F;IAC1F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD,sGAAsG;IACtG,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;OAGG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACnD"}
@@ -5,6 +5,7 @@ import type { MessagingProvider } from './capabilities/messaging.js';
5
5
  import type { MusicProviderCatalog, MusicProviderOAuth, MusicProviderSteer, MusicProviderStream } from './capabilities/music.provider.js';
6
6
  import type { NarrationProvider } from './capabilities/narration.js';
7
7
  import type { NewsProvider } from './capabilities/news.js';
8
+ import type { OutputProvider } from './capabilities/output.js';
8
9
  import type { PodcastProvider } from './capabilities/podcast.js';
9
10
  import type { ScrobbleProvider } from './capabilities/scrobble.js';
10
11
  import type { SearchProvider } from './capabilities/search.js';
@@ -55,6 +56,8 @@ export type AlmanacPluginInstance = PluginLifecycle & AlmanacProvider;
55
56
  export type ScrobblePluginInstance = PluginLifecycle & ScrobbleProvider;
56
57
  /** Instance shape for a `messaging` plugin. */
57
58
  export type MessagingPluginInstance = PluginLifecycle & MessagingProvider;
59
+ /** Instance shape for an `output` plugin. */
60
+ export type OutputPluginInstance = PluginLifecycle & OutputProvider;
58
61
  /**
59
62
  * Pairs a manifest with its factory and returns the object a plugin package
60
63
  * default-exports. Purely a typing helper: it does no validation, because the
@@ -1 +1 @@
1
- {"version":3,"file":"define.plugin.d.ts","sourceRoot":"","sources":["../src/define.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC1I,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc,IAAI,MAAM,SAAS,CAAC;AAE/F,6CAA6C;AAC7C,MAAM,WAAW,aAAa,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc;IAC5E,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,eAAe,GACrD,OAAO,CAAC,oBAAoB,CAAC,GAC7B,OAAO,CAAC,mBAAmB,CAAC,GAC5B,OAAO,CAAC,kBAAkB,CAAC,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEpE,0CAA0C;AAC1C,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,YAAY,CAAC;AAEhE,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE1E,uGAAuG;AACvG,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,gDAAgD;AAChD,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,8CAA8C;AAC9C,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAExE,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE1E;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,SAAS,SAAS,cAAc,EACzD,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,GAClC,aAAa,CAAC,SAAS,CAAC,CAE1B"}
1
+ {"version":3,"file":"define.plugin.d.ts","sourceRoot":"","sources":["../src/define.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC1I,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc,IAAI,MAAM,SAAS,CAAC;AAE/F,6CAA6C;AAC7C,MAAM,WAAW,aAAa,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc;IAC5E,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,eAAe,GACrD,OAAO,CAAC,oBAAoB,CAAC,GAC7B,OAAO,CAAC,mBAAmB,CAAC,GAC5B,OAAO,CAAC,kBAAkB,CAAC,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEhC,iDAAiD;AACjD,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEpE,0CAA0C;AAC1C,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,YAAY,CAAC;AAEhE,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE1E,uGAAuG;AACvG,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,gDAAgD;AAChD,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,8CAA8C;AAC9C,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAExE,+CAA+C;AAC/C,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE1E,6CAA6C;AAC7C,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,SAAS,SAAS,cAAc,EACzD,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,GAClC,aAAa,CAAC,SAAS,CAAC,CAE1B"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from './capabilities/mixer.js';
9
9
  export * from './capabilities/music.provider.js';
10
10
  export * from './capabilities/narration.js';
11
11
  export * from './capabilities/news.js';
12
+ export * from './capabilities/output.js';
12
13
  export * from './capabilities/podcast.js';
13
14
  export * from './capabilities/scrobble.js';
14
15
  export * from './capabilities/search.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,9 @@ var JSON_SAFE_PAYLOAD_TYPES = [
21
21
  "TrackFetchRequest",
22
22
  "PlaylistTracksRequest",
23
23
  "PluginSocketOptions",
24
+ "PluginTlsOptions",
25
+ "DiscoveryOptions",
26
+ "DiscoveredService",
24
27
  "SearchTracksOptions",
25
28
  "ListPlaylistsOptions",
26
29
  "GetPlaylistTracksOptions",
@@ -94,6 +97,11 @@ var JSON_SAFE_PAYLOAD_TYPES = [
94
97
  "MessagingSendResult",
95
98
  "MessagingAnnounceTarget",
96
99
  "MessagingCommand",
100
+ "OutputDevice",
101
+ "OutputMetadata",
102
+ "OutputPlayRequest",
103
+ "OutputMetadataRequest",
104
+ "OutputStatus",
97
105
  "SpeechLimits"
98
106
  ];
99
107
  var BOUNDARY_METHOD_TYPES = [
@@ -105,6 +113,7 @@ var BOUNDARY_METHOD_TYPES = [
105
113
  "PluginEvents",
106
114
  "PluginTrackFetcher",
107
115
  "PluginSocket",
116
+ "PluginTlsSocket",
108
117
  "PluginHost",
109
118
  "PluginLifecycle",
110
119
  "MusicProviderCatalog",
@@ -127,7 +136,8 @@ var BOUNDARY_METHOD_TYPES = [
127
136
  "WeatherProvider",
128
137
  "AlmanacProvider",
129
138
  "ScrobbleProvider",
130
- "MessagingProvider"
139
+ "MessagingProvider",
140
+ "OutputProvider"
131
141
  ];
132
142
  var BOUNDARY_LIVE_OBJECT_TYPES = [
133
143
  // `signal`: the invocation's own `AbortSignal`, watched by `host.fetch` and
@@ -1206,6 +1216,17 @@ var pluginPermissionsSchema = z2.object({
1206
1216
  oauth: z2.boolean(),
1207
1217
  trackFetcher: z2.boolean().optional(),
1208
1218
  sockets: z2.boolean().optional(),
1219
+ tls: z2.boolean().optional(),
1220
+ discovery: z2.array(z2.union([
1221
+ z2.object({
1222
+ protocol: z2.literal("mdns"),
1223
+ service: z2.string().min(1)
1224
+ }),
1225
+ z2.object({
1226
+ protocol: z2.literal("ssdp"),
1227
+ searchTarget: z2.string().min(1)
1228
+ })
1229
+ ])).optional(),
1209
1230
  grants: z2.array(grantRequestSchema).optional()
1210
1231
  });
1211
1232
 
@@ -1230,6 +1251,7 @@ var PLUGIN_CAPABILITY_WEATHER = "weather";
1230
1251
  var PLUGIN_CAPABILITY_ALMANAC = "almanac";
1231
1252
  var PLUGIN_CAPABILITY_SCROBBLE = "scrobble";
1232
1253
  var PLUGIN_CAPABILITY_MESSAGING = "messaging";
1254
+ var PLUGIN_CAPABILITY_OUTPUT = "output";
1233
1255
  var KNOWN_PLUGIN_CAPABILITIES = [
1234
1256
  PLUGIN_CAPABILITY_CATALOG,
1235
1257
  PLUGIN_CAPABILITY_STREAM,
@@ -1250,7 +1272,8 @@ var KNOWN_PLUGIN_CAPABILITIES = [
1250
1272
  PLUGIN_CAPABILITY_WEATHER,
1251
1273
  PLUGIN_CAPABILITY_ALMANAC,
1252
1274
  PLUGIN_CAPABILITY_SCROBBLE,
1253
- PLUGIN_CAPABILITY_MESSAGING
1275
+ PLUGIN_CAPABILITY_MESSAGING,
1276
+ PLUGIN_CAPABILITY_OUTPUT
1254
1277
  ];
1255
1278
  function isZodSchema(value) {
1256
1279
  if (value instanceof z3.ZodType) return true;
@@ -1300,6 +1323,7 @@ export {
1300
1323
  PLUGIN_CAPABILITY_NARRATION,
1301
1324
  PLUGIN_CAPABILITY_NEWS,
1302
1325
  PLUGIN_CAPABILITY_OAUTH,
1326
+ PLUGIN_CAPABILITY_OUTPUT,
1303
1327
  PLUGIN_CAPABILITY_PODCAST,
1304
1328
  PLUGIN_CAPABILITY_SCROBBLE,
1305
1329
  PLUGIN_CAPABILITY_SEARCH,