@camstack/types 0.1.31 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/capabilities/admin-ui.cap.d.ts +6 -2
  2. package/dist/capabilities/admin-ui.cap.d.ts.map +1 -1
  3. package/dist/capabilities/advanced-notifier.cap.d.ts +202 -29
  4. package/dist/capabilities/advanced-notifier.cap.d.ts.map +1 -1
  5. package/dist/capabilities/audio-codec.cap.d.ts +2 -2
  6. package/dist/capabilities/capability-definition.d.ts +22 -0
  7. package/dist/capabilities/capability-definition.d.ts.map +1 -1
  8. package/dist/capabilities/device-export.cap.d.ts +77 -0
  9. package/dist/capabilities/device-export.cap.d.ts.map +1 -0
  10. package/dist/capabilities/embedding-encoder.cap.d.ts +14 -7
  11. package/dist/capabilities/embedding-encoder.cap.d.ts.map +1 -1
  12. package/dist/capabilities/index.d.ts +15 -11
  13. package/dist/capabilities/index.d.ts.map +1 -1
  14. package/dist/capabilities/intercom.cap.d.ts +34 -0
  15. package/dist/capabilities/intercom.cap.d.ts.map +1 -1
  16. package/dist/capabilities/mesh-network.cap.d.ts +18 -20
  17. package/dist/capabilities/mesh-network.cap.d.ts.map +1 -1
  18. package/dist/capabilities/mqtt-broker.cap.d.ts +153 -0
  19. package/dist/capabilities/mqtt-broker.cap.d.ts.map +1 -0
  20. package/dist/capabilities/network-access.cap.d.ts +41 -1
  21. package/dist/capabilities/network-access.cap.d.ts.map +1 -1
  22. package/dist/capabilities/platform-probe.cap.d.ts +234 -15
  23. package/dist/capabilities/platform-probe.cap.d.ts.map +1 -1
  24. package/dist/capabilities/smtp-provider.cap.d.ts +11 -10
  25. package/dist/capabilities/smtp-provider.cap.d.ts.map +1 -1
  26. package/dist/capabilities/sso-bridge.cap.d.ts +3 -0
  27. package/dist/capabilities/sso-bridge.cap.d.ts.map +1 -1
  28. package/dist/capabilities/stream-broker.cap.d.ts +90 -85
  29. package/dist/capabilities/stream-broker.cap.d.ts.map +1 -1
  30. package/dist/capabilities/webrtc-session.cap.d.ts +34 -0
  31. package/dist/capabilities/webrtc-session.cap.d.ts.map +1 -1
  32. package/dist/enums/event-category.d.ts +1 -8
  33. package/dist/enums/event-category.d.ts.map +1 -1
  34. package/dist/generated/addon-api.d.ts +12923 -10641
  35. package/dist/generated/addon-api.d.ts.map +1 -1
  36. package/dist/generated/cap-status-types.d.ts +5 -1
  37. package/dist/generated/cap-status-types.d.ts.map +1 -1
  38. package/dist/generated/capability-router-map.d.ts +7 -7
  39. package/dist/generated/capability-router-map.d.ts.map +1 -1
  40. package/dist/generated/device-proxy.d.ts +2 -0
  41. package/dist/generated/device-proxy.d.ts.map +1 -1
  42. package/dist/generated/method-access-map.d.ts +1 -1
  43. package/dist/generated/method-access-map.d.ts.map +1 -1
  44. package/dist/generated/provider-kind-map.d.ts +22 -0
  45. package/dist/generated/provider-kind-map.d.ts.map +1 -0
  46. package/dist/generated/system-proxy.d.ts +7 -3
  47. package/dist/generated/system-proxy.d.ts.map +1 -1
  48. package/dist/{index-BKnvgAep.mjs → index-BBVUwOlZ.mjs} +641 -610
  49. package/dist/index-BBVUwOlZ.mjs.map +1 -0
  50. package/dist/{index-BKifir_y.js → index-BUBhoPUu.js} +381 -350
  51. package/dist/index-BUBhoPUu.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +108 -39
  55. package/dist/index.js.map +1 -1
  56. package/dist/index.mjs +365 -296
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/interfaces/addon.d.ts +14 -3
  59. package/dist/interfaces/addon.d.ts.map +1 -1
  60. package/dist/interfaces/advanced-notifier.d.ts +8 -7
  61. package/dist/interfaces/advanced-notifier.d.ts.map +1 -1
  62. package/dist/interfaces/capability.d.ts +6 -6
  63. package/dist/interfaces/capability.d.ts.map +1 -1
  64. package/dist/interfaces/embedding-encoder.d.ts +16 -7
  65. package/dist/interfaces/embedding-encoder.d.ts.map +1 -1
  66. package/dist/interfaces/rtp-egress.d.ts +45 -0
  67. package/dist/interfaces/rtp-egress.d.ts.map +1 -0
  68. package/dist/node.js +1 -1
  69. package/dist/node.mjs +1 -1
  70. package/package.json +1 -1
  71. package/dist/capabilities/home-assistant.cap.d.ts +0 -138
  72. package/dist/capabilities/home-assistant.cap.d.ts.map +0 -1
  73. package/dist/capabilities/mqtt-provider.cap.d.ts +0 -91
  74. package/dist/capabilities/mqtt-provider.cap.d.ts.map +0 -1
  75. package/dist/index-BKifir_y.js.map +0 -1
  76. package/dist/index-BKnvgAep.mjs.map +0 -1
@@ -1070,9 +1070,9 @@ const DecodedFrameSchema = zod.z.object({
1070
1070
  format: zod.z.enum(["jpeg", "rgb", "bgr", "yuv420", "gray"]),
1071
1071
  timestamp: zod.z.number()
1072
1072
  });
1073
- const BrokerStatusSchema = zod.z.enum(["idle", "connecting", "streaming", "error", "stopped"]);
1073
+ const BrokerStatusSchema$1 = zod.z.enum(["idle", "connecting", "streaming", "error", "stopped"]);
1074
1074
  const BrokerStatsSchema = zod.z.object({
1075
- status: BrokerStatusSchema,
1075
+ status: BrokerStatusSchema$1,
1076
1076
  inputFps: zod.z.number(),
1077
1077
  decodeFps: zod.z.number(),
1078
1078
  encodedSubscribers: zod.z.number(),
@@ -1178,22 +1178,34 @@ const PlaceholderReasonSchema = zod.z.enum([
1178
1178
  "disabled",
1179
1179
  "waking"
1180
1180
  ]);
1181
+ const VideoCodecTargetSchema = zod.z.enum(["H264", "H265", "auto"]);
1182
+ const AudioCodecTargetSchema = zod.z.enum(["AAC", "Opus", "PCMU", "none"]);
1183
+ const MaxResolutionSchema = zod.z.object({
1184
+ width: zod.z.number().int().positive(),
1185
+ height: zod.z.number().int().positive()
1186
+ });
1187
+ const GetStreamWithCodecInputSchema = zod.z.object({
1188
+ deviceId: zod.z.number().int().nonnegative(),
1189
+ videoCodec: VideoCodecTargetSchema,
1190
+ audioCodec: AudioCodecTargetSchema.optional(),
1191
+ maxResolution: MaxResolutionSchema.optional(),
1192
+ tag: zod.z.string().optional()
1193
+ });
1194
+ const RtpSourceSchema = zod.z.object({
1195
+ url: zod.z.string(),
1196
+ videoCodec: zod.z.enum(["H264", "H265"]),
1197
+ audioCodec: zod.z.string(),
1198
+ resolution: MaxResolutionSchema,
1199
+ transcoded: zod.z.boolean(),
1200
+ encoder: zod.z.string(),
1201
+ pipelineKey: zod.z.string()
1202
+ });
1181
1203
  const streamBrokerCapability = {
1182
1204
  name: "stream-broker",
1183
1205
  scope: "system",
1184
1206
  mode: "singleton",
1185
1207
  exposesDeviceSettings: true,
1186
1208
  methods: {
1187
- // ── Cam stream lifecycle (publish / retract) ─────────────────────
1188
- /**
1189
- * Register a physical camera stream as an input option. Idempotent
1190
- * for (deviceId, camStreamId) — re-publishing updates metadata
1191
- * without disturbing profile assignments. The provider calls this
1192
- * in `onInitialize` for each stream it offers. Third-party addons
1193
- * may also publish (e.g. an RTMP discovery layer) — camstack has
1194
- * no notion of "owner" beyond the (deviceId, camStreamId) key.
1195
- */
1196
- /* — see STREAM_BROKER_CAP_EVENTS below for cap-event category strings — */
1197
1209
  publishCameraStream: method(
1198
1210
  zod.z.object({
1199
1211
  deviceId: zod.z.number().int().nonnegative(),
@@ -1204,28 +1216,8 @@ const streamBrokerCapability = {
1204
1216
  resolution: CamStreamResolutionSchema.optional(),
1205
1217
  fps: zod.z.number().positive().optional(),
1206
1218
  label: zod.z.string().optional(),
1207
- /**
1208
- * Device-level features that the broker / manager / snapshot
1209
- * orchestrator consult to derive per-stream policy (e.g.
1210
- * `BatteryOperated` → relax stall watchdog, default pre-buffer
1211
- * to off, raise snapshot rate-limit). Single source of truth —
1212
- * publishers no longer set per-stream flags like `allowStall`.
1213
- */
1214
1219
  deviceFeatures: zod.z.array(zod.z.string()).optional(),
1215
- /**
1216
- * Whether this stream participates in the broker's automatic
1217
- * profile assignment. Defaults `true`. Publishers set `false` for
1218
- * streams that should be SELECTABLE but not auto-picked — e.g.
1219
- * Reolink publishes native Baichuan as eligible and RTSP/RTMP
1220
- * mirrors as ineligible (still assignable manually via
1221
- * `assignProfile`).
1222
- */
1223
1220
  autoEligible: zod.z.boolean().optional(),
1224
- /**
1225
- * Transport-specific opaque metadata stashed alongside the stream
1226
- * record. `pull-rfc4571` publishers put the SDP here so the broker
1227
- * reader can route packets without an in-band DESCRIBE phase.
1228
- */
1229
1221
  metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
1230
1222
  }),
1231
1223
  zod.z.object({ success: zod.z.literal(true) }),
@@ -1239,12 +1231,6 @@ const streamBrokerCapability = {
1239
1231
  zod.z.object({ success: zod.z.literal(true) }),
1240
1232
  { kind: "mutation", auth: "admin" }
1241
1233
  ),
1242
- // ── Profile assignment ───────────────────────────────────────────
1243
- /**
1244
- * Assign a cam stream to a profile slot. Tears down any existing
1245
- * broker for that slot and rebuilds against the new source. Persists
1246
- * the choice — survives reboots.
1247
- */
1248
1234
  assignProfile: method(
1249
1235
  zod.z.object({
1250
1236
  deviceId: zod.z.number().int().nonnegative(),
@@ -1262,12 +1248,6 @@ const streamBrokerCapability = {
1262
1248
  zod.z.object({ success: zod.z.literal(true) }),
1263
1249
  { kind: "mutation", auth: "admin" }
1264
1250
  ),
1265
- // ── System-wide views ────────────────────────────────────────────
1266
- /**
1267
- * Full dump of every published cam stream across every device.
1268
- * For dashboards and cross-device tooling; per-device reads go
1269
- * through the `camera-streams` cap on the device proxy.
1270
- */
1271
1251
  listAllCameraStreams: method(
1272
1252
  zod.z.void(),
1273
1253
  zod.z.array(CameraStreamSchema).readonly()
@@ -1276,7 +1256,6 @@ const streamBrokerCapability = {
1276
1256
  zod.z.void(),
1277
1257
  zod.z.array(ProfileSlotSchema).readonly()
1278
1258
  ),
1279
- // ── Broker runtime (stats + client inventory) ────────────────────
1280
1259
  getBrokerStats: method(
1281
1260
  zod.z.object({ brokerId: zod.z.string() }),
1282
1261
  BrokerStatsSchema
@@ -1294,7 +1273,6 @@ const streamBrokerCapability = {
1294
1273
  zod.z.object({ killed: zod.z.boolean() }),
1295
1274
  { kind: "mutation", auth: "admin" }
1296
1275
  ),
1297
- /** Rebuild the broker for a profile slot in place (re-dial source). */
1298
1276
  restartProfile: method(
1299
1277
  zod.z.object({
1300
1278
  deviceId: zod.z.number().int().nonnegative(),
@@ -1303,24 +1281,28 @@ const streamBrokerCapability = {
1303
1281
  zod.z.object({ success: zod.z.boolean() }),
1304
1282
  { kind: "mutation", auth: "admin" }
1305
1283
  ),
1306
- // ── Stream URLs ──────────────────────────────────────────────────
1307
1284
  getStreamUrl: method(
1308
1285
  zod.z.object({ streamId: zod.z.string(), format: StreamFormatSchema }),
1309
1286
  zod.z.object({ url: zod.z.string() })
1310
1287
  ),
1311
- // ── In-process broker access ─────────────────────────────────────
1312
1288
  /**
1313
- * Return the live IStreamBroker instance for a given brokerId. Same
1314
- * LOCAL-ONLY contract as before: callers (pipeline-runner) must be
1315
- * co-located. BrokerId is `${deviceId}/${camStreamId}` — profile
1316
- * lookup goes through `assignments` if a caller starts from a
1317
- * profile.
1289
+ * Shared codec-targeted stream API see Task #184.
1290
+ * Resolution order: source-select HW transcode libx264/libx265.
1318
1291
  */
1292
+ getStreamWithCodec: method(
1293
+ GetStreamWithCodecInputSchema,
1294
+ RtpSourceSchema,
1295
+ { kind: "mutation", auth: "admin" }
1296
+ ),
1297
+ releaseStreamWithCodec: method(
1298
+ zod.z.object({ pipelineKey: zod.z.string() }),
1299
+ zod.z.object({ released: zod.z.boolean(), refcount: zod.z.number().int().nonnegative() }),
1300
+ { kind: "mutation", auth: "admin" }
1301
+ ),
1319
1302
  getBroker: method(
1320
1303
  zod.z.object({ brokerId: zod.z.string() }),
1321
1304
  zod.z.custom()
1322
1305
  ),
1323
- // ── Pre-buffer ───────────────────────────────────────────────────
1324
1306
  setPreBufferDuration: method(
1325
1307
  zod.z.object({ brokerId: zod.z.string(), seconds: zod.z.number().min(0).max(30) }),
1326
1308
  zod.z.void(),
@@ -1330,7 +1312,6 @@ const streamBrokerCapability = {
1330
1312
  zod.z.object({ brokerId: zod.z.string() }),
1331
1313
  zod.z.object({ configuredSec: zod.z.number(), bufferedMs: zod.z.number(), packetCount: zod.z.number() })
1332
1314
  ),
1333
- // ── RTSP restream ────────────────────────────────────────────────
1334
1315
  getRtspPort: method(zod.z.void(), zod.z.number()),
1335
1316
  getAllRtspEntries: method(
1336
1317
  zod.z.object({ hostname: zod.z.string().optional() }),
@@ -1356,37 +1337,15 @@ const streamBrokerCapability = {
1356
1337
  )
1357
1338
  },
1358
1339
  events: {
1359
- /**
1360
- * Emitted when a profile starts consuming a push-kind cam stream.
1361
- * Push-kind providers (e.g. Reolink Baichuan native streams)
1362
- * subscribe and begin emitting packets only on demand — battery
1363
- * cams stay asleep until someone actually watches.
1364
- */
1365
1340
  onCamStreamDemand: event(zod.z.object({
1366
1341
  deviceId: zod.z.number().int().nonnegative(),
1367
1342
  camStreamId: zod.z.string(),
1368
1343
  profile: CamProfileSchema
1369
1344
  })),
1370
- /**
1371
- * Emitted when the last profile consuming a push-kind cam stream
1372
- * releases it. Providers tear down upstream connections on this
1373
- * signal.
1374
- */
1375
1345
  onCamStreamIdle: event(zod.z.object({
1376
1346
  deviceId: zod.z.number().int().nonnegative(),
1377
1347
  camStreamId: zod.z.string()
1378
1348
  })),
1379
- /**
1380
- * Emitted by a broker that failed to dial a managed-loopback
1381
- * source (today: `pull-rfc4571`). The publisher's transport (e.g.
1382
- * the Reolink lib's RFC 4571 TCP server) idle-tears-down after
1383
- * ~15s with no clients and may rebind to a different port on
1384
- * recreate, leaving the URL the broker has cached stale. The owning
1385
- * camera provider re-runs its publish pipeline on receipt — that
1386
- * call self-heals the loopback server (`ensureRfc4571Server`) and
1387
- * `publishCameraStream` propagates the fresh URL back into the
1388
- * broker's source resolver.
1389
- */
1390
1349
  onRequestStreamSourceRefresh: event(zod.z.object({
1391
1350
  deviceId: zod.z.number().int().nonnegative(),
1392
1351
  camStreamId: zod.z.string(),
@@ -3660,14 +3619,16 @@ const logDestinationCapability = {
3660
3619
  )
3661
3620
  }
3662
3621
  };
3622
+ const StaticDirOutputSchema = zod.z.object({ staticDir: zod.z.string() });
3623
+ const VersionOutputSchema = zod.z.object({ version: zod.z.string() });
3663
3624
  const adminUiCapability = {
3664
3625
  name: "admin-ui",
3665
3626
  scope: "system",
3666
3627
  mode: "singleton",
3667
3628
  internal: true,
3668
3629
  methods: {
3669
- getStaticDir: method(zod.z.void(), zod.z.string()),
3670
- getVersion: method(zod.z.void(), zod.z.string())
3630
+ getStaticDir: method(zod.z.void(), StaticDirOutputSchema),
3631
+ getVersion: method(zod.z.void(), VersionOutputSchema)
3671
3632
  }
3672
3633
  };
3673
3634
  const SsoBridgeClaimsSchema = zod.z.object({
@@ -3676,7 +3637,16 @@ const SsoBridgeClaimsSchema = zod.z.object({
3676
3637
  isAdmin: zod.z.boolean(),
3677
3638
  provider: zod.z.string(),
3678
3639
  email: zod.z.string().optional(),
3679
- displayName: zod.z.string().optional()
3640
+ displayName: zod.z.string().optional(),
3641
+ /**
3642
+ * Public HTTPS URL of the hub that issued this token. Used by
3643
+ * cloud-mode OAuth proxies (Alexa Smart Home Lambda, future Google
3644
+ * Home Lambda) to route a request back to the originating hub
3645
+ * without holding routing state of their own. The Lambda decodes the
3646
+ * JWT WITHOUT verifying the signature — the hub re-verifies on every
3647
+ * inbound call so trust still rests with the signing hub.
3648
+ */
3649
+ hubUrl: zod.z.string().optional()
3680
3650
  });
3681
3651
  const ssoBridgeCapability = {
3682
3652
  name: "sso-bridge",
@@ -3758,7 +3728,7 @@ const userPasskeysCapability = {
3758
3728
  )
3759
3729
  }
3760
3730
  };
3761
- const EmailAddressSchema = zod.z.string().email();
3731
+ const EmailAddressSchema = zod.z.email();
3762
3732
  const SendEmailInputSchema = zod.z.object({
3763
3733
  to: zod.z.union([EmailAddressSchema, zod.z.array(EmailAddressSchema).min(1)]),
3764
3734
  cc: zod.z.array(EmailAddressSchema).optional(),
@@ -3796,6 +3766,7 @@ const smtpProviderCapability = {
3796
3766
  scope: "system",
3797
3767
  mode: "collection",
3798
3768
  internal: true,
3769
+ providerKind: "email",
3799
3770
  methods: {
3800
3771
  sendEmail: method(
3801
3772
  SendEmailInputSchema,
@@ -3816,204 +3787,125 @@ const smtpProviderCapability = {
3816
3787
  )
3817
3788
  }
3818
3789
  };
3819
- const QosSchema = zod.z.union([zod.z.literal(0), zod.z.literal(1), zod.z.literal(2)]);
3820
- const PublishInputSchema = zod.z.object({
3821
- topic: zod.z.string(),
3822
- /** UTF-8 payload. Binary payloads must be base64-encoded by the caller. */
3823
- payload: zod.z.string(),
3824
- qos: QosSchema.default(0),
3825
- retain: zod.z.boolean().default(false)
3826
- });
3827
- const SubscribeInputSchema = zod.z.object({
3828
- /** MQTT topic filter (supports `+` single-level and `#` multi-level wildcards). */
3829
- topic: zod.z.string(),
3830
- qos: QosSchema.default(0),
3790
+ const BrokerKindSchema = zod.z.enum(["external", "embedded"]);
3791
+ const BrokerStatusSchema = zod.z.enum([
3792
+ "connected",
3793
+ "disconnected",
3794
+ "auth-failed",
3795
+ "unreachable",
3796
+ "tls-error"
3797
+ ]);
3798
+ const BrokerInfoSchema = zod.z.object({
3799
+ id: zod.z.string(),
3800
+ name: zod.z.string(),
3801
+ url: zod.z.string(),
3802
+ kind: BrokerKindSchema,
3803
+ status: BrokerStatusSchema,
3804
+ latencyMs: zod.z.number().nullable(),
3805
+ error: zod.z.string().optional(),
3806
+ /** Embedded brokers only: number of MQTT clients currently connected. */
3807
+ connectedClients: zod.z.number().int().nonnegative().optional(),
3808
+ /** Epoch ms of the last live probe (external) or aedes snapshot (embedded). */
3809
+ lastCheckedAt: zod.z.number().optional()
3810
+ });
3811
+ const BrokerConnectionDetailsSchema = zod.z.object({
3812
+ url: zod.z.string(),
3813
+ username: zod.z.string().optional(),
3814
+ password: zod.z.string().optional(),
3831
3815
  /**
3832
- * Caller-supplied owner tag. Useful for debugging + the
3833
- * `listSubscriptions` admin view ("which consumer owns this?").
3834
- * When omitted, the addon synthesizes one from the caller's addon id.
3816
+ * Suggested prefix for `clientId`. Each consumer should suffix this
3817
+ * with its own discriminator (addon id, instance id) so reconnects
3818
+ * don't kick each other off (MQTT spec: clientId must be unique per
3819
+ * broker).
3835
3820
  */
3836
- owner: zod.z.string().optional()
3821
+ clientIdPrefix: zod.z.string().optional()
3837
3822
  });
3838
- const SubscribeResultSchema = zod.z.object({
3839
- success: zod.z.literal(true),
3840
- /** Server-generated subscription id. Pass to `unsubscribe` to release. */
3841
- subscriptionId: zod.z.string()
3823
+ const AddBrokerInputSchema = zod.z.object({
3824
+ name: zod.z.string().min(1),
3825
+ url: zod.z.string().regex(/^(mqtt|mqtts|ws|wss):\/\//, "URL must start with mqtt(s):// or ws(s)://"),
3826
+ username: zod.z.string().optional(),
3827
+ password: zod.z.string().optional(),
3828
+ clientIdPrefix: zod.z.string().optional()
3842
3829
  });
3843
- const UnsubscribeInputSchema = zod.z.object({
3844
- /** Subscription id from `subscribe`. */
3845
- subscriptionId: zod.z.string()
3830
+ const AddBrokerResultSchema = zod.z.object({
3831
+ id: zod.z.string()
3846
3832
  });
3847
- const MqttStatusSchema = zod.z.object({
3848
- /** True iff the addon has an active connection to the broker. */
3849
- connected: zod.z.boolean(),
3850
- /** Operator-visible host string (e.g. `mqtt://broker.example:1883`). */
3851
- brokerUrl: zod.z.string(),
3852
- /** Active subscription count (per-owner, NOT broker-side topic count). */
3853
- subscriptionCount: zod.z.number().int(),
3854
- /** Last error reported by the broker. */
3855
- error: zod.z.string().optional(),
3856
- /** Last successful connection timestamp (unix ms). */
3857
- connectedAt: zod.z.number().optional()
3858
- });
3859
- const SubscriptionInfoSchema = zod.z.object({
3860
- subscriptionId: zod.z.string(),
3861
- topic: zod.z.string(),
3862
- qos: QosSchema,
3863
- owner: zod.z.string(),
3864
- /** When this individual subscription was created. */
3865
- createdAt: zod.z.number()
3833
+ const IdInputSchema = zod.z.object({ id: zod.z.string() });
3834
+ const TestResultSchema = zod.z.discriminatedUnion("ok", [
3835
+ zod.z.object({ ok: zod.z.literal(true), latencyMs: zod.z.number() }),
3836
+ zod.z.object({ ok: zod.z.literal(false), error: zod.z.string() })
3837
+ ]);
3838
+ const StartEmbeddedInputSchema = zod.z.object({
3839
+ port: zod.z.number().int().min(1).max(65535).default(1883),
3840
+ /** Allow anonymous connect (no username/password). Default: false. */
3841
+ allowAnonymous: zod.z.boolean().default(false),
3842
+ /** Optional shared username/password for clients. */
3843
+ username: zod.z.string().optional(),
3844
+ password: zod.z.string().optional()
3866
3845
  });
3867
- const mqttProviderCapability = {
3868
- name: "mqtt-provider",
3846
+ const StartEmbeddedResultSchema = zod.z.object({
3847
+ id: zod.z.string(),
3848
+ url: zod.z.string()
3849
+ });
3850
+ const StatusSchema = zod.z.object({
3851
+ brokerCount: zod.z.number(),
3852
+ embeddedRunning: zod.z.boolean()
3853
+ });
3854
+ const mqttBrokerCapability = {
3855
+ name: "mqtt-broker",
3869
3856
  scope: "system",
3870
3857
  mode: "collection",
3871
- internal: true,
3858
+ providerKind: "broker",
3859
+ status: { schema: StatusSchema, kind: "poll" },
3872
3860
  methods: {
3873
- /** Publish a message. Lazy-opens the connection if not yet active. */
3874
- publish: method(
3875
- PublishInputSchema,
3876
- zod.z.object({ success: zod.z.literal(true) }),
3877
- { kind: "mutation", auth: "admin", access: "create" }
3878
- ),
3879
- /**
3880
- * Subscribe to a topic. Returns a `subscriptionId` to pass to
3881
- * `unsubscribe`. The addon refcounts broker subscriptions —
3882
- * multiple consumers on the same topic share one upstream sub.
3883
- * Messages arrive on `mqtt.message` events with `subscriptionIds[]`
3884
- * listing which subscriptions matched.
3885
- */
3886
- subscribe: method(
3887
- SubscribeInputSchema,
3888
- SubscribeResultSchema,
3889
- { kind: "mutation", auth: "admin", access: "create" }
3890
- ),
3891
- /** Release a specific subscription. Tears down the broker sub
3892
- * only when the last owner releases. Idempotent. */
3893
- unsubscribe: method(
3894
- UnsubscribeInputSchema,
3895
- zod.z.object({ success: zod.z.literal(true) }),
3896
- { kind: "mutation", auth: "admin", access: "delete" }
3897
- ),
3898
- /** List active per-owner subscriptions on this provider. */
3899
- listSubscriptions: method(
3900
- zod.z.void(),
3901
- zod.z.array(SubscriptionInfoSchema),
3902
- { auth: "admin" }
3903
- ),
3904
- getStatus: method(
3905
- zod.z.void(),
3906
- MqttStatusSchema,
3907
- { auth: "admin" }
3908
- )
3861
+ listBrokers: method(zod.z.void(), zod.z.array(BrokerInfoSchema)),
3862
+ getBrokerConfig: method(IdInputSchema, BrokerConnectionDetailsSchema),
3863
+ addBroker: method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }),
3864
+ removeBroker: method(IdInputSchema, zod.z.void(), { kind: "mutation" }),
3865
+ testConnection: method(IdInputSchema, TestResultSchema, { kind: "mutation" }),
3866
+ startEmbeddedBroker: method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }),
3867
+ stopEmbeddedBroker: method(IdInputSchema, zod.z.void(), { kind: "mutation" }),
3868
+ getStatus: method(zod.z.void(), StatusSchema)
3909
3869
  }
3910
3870
  };
3911
- const HaServiceCallSchema = zod.z.object({
3912
- /** HA domain (e.g. `light`, `switch`, `notify`). */
3913
- domain: zod.z.string(),
3914
- /** HA service (e.g. `turn_on`, `toggle`). */
3915
- service: zod.z.string(),
3916
- /** Service-specific data payload (e.g. `{entity_id: 'light.kitchen', brightness: 200}`). */
3917
- serviceData: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
3918
- /** Optional target spec (entity_id / device_id / area_id). */
3919
- target: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
3920
- });
3921
- const HaStateSchema = zod.z.object({
3922
- entity_id: zod.z.string(),
3923
- state: zod.z.string(),
3924
- attributes: zod.z.record(zod.z.string(), zod.z.unknown()).default({}),
3925
- last_changed: zod.z.string().optional(),
3926
- last_updated: zod.z.string().optional()
3871
+ const LinkStateSchema = zod.z.enum(["unlinked", "linked", "error"]);
3872
+ const DeviceExportStatusSchema = zod.z.object({
3873
+ linkState: LinkStateSchema,
3874
+ exposedDeviceCount: zod.z.number(),
3875
+ error: zod.z.string().optional()
3927
3876
  });
3928
- const HaStatusSchema = zod.z.object({
3929
- connected: zod.z.boolean(),
3930
- host: zod.z.string(),
3931
- /** Active per-owner subscription count. */
3932
- subscriptionCount: zod.z.number().int(),
3933
- /** Last error reported by the WebSocket. */
3934
- error: zod.z.string().optional(),
3935
- /** HA version reported during the auth handshake, when reachable. */
3936
- haVersion: zod.z.string().optional(),
3937
- connectedAt: zod.z.number().optional()
3877
+ const DeviceKindSchema = zod.z.string();
3878
+ const ExposedDeviceSchema = zod.z.object({
3879
+ deviceId: zod.z.string(),
3880
+ exposedAs: zod.z.string().optional(),
3881
+ capabilities: zod.z.array(zod.z.string()).optional()
3938
3882
  });
3939
- const HaSubscribeInputSchema = zod.z.object({
3940
- /**
3941
- * Specific HA event type to subscribe to (`state_changed`,
3942
- * `service_called`, etc.). Empty string = all events (firehose —
3943
- * only for debugging).
3944
- */
3945
- eventType: zod.z.string().optional(),
3946
- /** Caller-supplied tag for listSubscriptions debugging. */
3947
- owner: zod.z.string().optional()
3948
- });
3949
- const HaSubscribeResultSchema = zod.z.object({
3950
- success: zod.z.literal(true),
3951
- subscriptionId: zod.z.string()
3952
- });
3953
- const HaUnsubscribeInputSchema = zod.z.object({
3954
- subscriptionId: zod.z.string()
3955
- });
3956
- const HaSubscriptionInfoSchema = zod.z.object({
3957
- subscriptionId: zod.z.string(),
3958
- /** Empty string when subscribed to ALL events. */
3959
- eventType: zod.z.string(),
3960
- owner: zod.z.string(),
3961
- createdAt: zod.z.number()
3883
+ const ExposeInputSchema = zod.z.object({
3884
+ deviceId: zod.z.string(),
3885
+ capabilities: zod.z.array(zod.z.string()).optional()
3962
3886
  });
3963
- const homeAssistantCapability = {
3964
- name: "home-assistant",
3887
+ const UnexposeInputSchema = zod.z.object({ deviceId: zod.z.string() });
3888
+ const deviceExportCapability = {
3889
+ name: "device-export",
3965
3890
  scope: "system",
3966
3891
  mode: "collection",
3967
- internal: true,
3892
+ providerKind: "device-export",
3893
+ status: { schema: DeviceExportStatusSchema, kind: "poll" },
3894
+ /**
3895
+ * Each export provider contributes its own per-device "Export" panel
3896
+ * (enabled toggle, preferred stream, addon-specific knobs like the
3897
+ * HA-MQTT discovery prefix). The three framework methods
3898
+ * `getDeviceSettingsContribution` / `getDeviceLiveContribution` /
3899
+ * `applyDeviceSettingsPatch` are auto-injected on the provider
3900
+ * interface and routed to the device-details aggregator.
3901
+ */
3902
+ exposesDeviceSettings: true,
3968
3903
  methods: {
3969
- /**
3970
- * Subscribe to HA events. Returns a `subscriptionId` to pass to
3971
- * `unsubscribeEvents`. The addon refcounts upstream subscriptions
3972
- * so multiple consumers share one HA-side event stream.
3973
- * Events arrive on the kernel bus under `home-assistant.event`
3974
- * with `subscriptionIds[]` listing which subs matched.
3975
- */
3976
- subscribeEvents: method(
3977
- HaSubscribeInputSchema,
3978
- HaSubscribeResultSchema,
3979
- { kind: "mutation", auth: "admin", access: "create" }
3980
- ),
3981
- /** Release a specific subscription. Tears down the upstream sub
3982
- * only when the last owner releases. Idempotent. */
3983
- unsubscribeEvents: method(
3984
- HaUnsubscribeInputSchema,
3985
- zod.z.object({ success: zod.z.literal(true) }),
3986
- { kind: "mutation", auth: "admin", access: "delete" }
3987
- ),
3988
- /**
3989
- * Call an HA service (turn light on, run a script, etc.). Returns
3990
- * the HA response object — usually `{context, response: ...}`.
3991
- */
3992
- callService: method(
3993
- HaServiceCallSchema,
3994
- zod.z.object({ result: zod.z.unknown() }),
3995
- { kind: "mutation", auth: "admin", access: "create" }
3996
- ),
3997
- /** Fetch all entity states. Cheap snapshot — HA returns the full
3998
- * state registry on every call. */
3999
- getStates: method(
4000
- zod.z.void(),
4001
- zod.z.array(HaStateSchema).readonly(),
4002
- { auth: "admin" }
4003
- ),
4004
- /** Fetch a single entity's current state. `null` when not found. */
4005
- getState: method(
4006
- zod.z.object({ entityId: zod.z.string() }),
4007
- HaStateSchema.nullable(),
4008
- { auth: "admin" }
4009
- ),
4010
- /** List active per-owner subscriptions. */
4011
- listSubscriptions: method(
4012
- zod.z.void(),
4013
- zod.z.array(HaSubscriptionInfoSchema).readonly(),
4014
- { auth: "admin" }
4015
- ),
4016
- getStatus: method(zod.z.void(), HaStatusSchema, { auth: "admin" })
3904
+ getStatus: method(zod.z.void(), DeviceExportStatusSchema),
3905
+ listSupportedDeviceKinds: method(zod.z.void(), zod.z.array(DeviceKindSchema)),
3906
+ listExposedDevices: method(zod.z.void(), zod.z.array(ExposedDeviceSchema)),
3907
+ exposeDevice: method(ExposeInputSchema, zod.z.void(), { kind: "mutation" }),
3908
+ unexposeDevice: method(UnexposeInputSchema, zod.z.void(), { kind: "mutation" })
4017
3909
  }
4018
3910
  };
4019
3911
  const AddonPageDeclarationSchema$1 = zod.z.object({
@@ -4415,6 +4307,29 @@ const webrtcSessionCapability = {
4415
4307
  zod.z.object({ sessionId: zod.z.string(), sdpOffer: zod.z.string() }),
4416
4308
  { kind: "mutation" }
4417
4309
  ),
4310
+ /**
4311
+ * Accept a CLIENT-generated SDP offer and return the server's
4312
+ * SDP answer. Mirrors the WHEP / Alexa
4313
+ * `Alexa.RTCSessionController.InitiateSessionWithOffer` direction
4314
+ * (client offers, server answers) — the dual of `createSession`,
4315
+ * which has the server offer first.
4316
+ *
4317
+ * `target` defaults to the device's adaptive selection when
4318
+ * omitted; an optional `sessionId` lets the client provide its
4319
+ * own correlation id (Alexa supplies one in the directive
4320
+ * payload). The returned `sessionId` is whatever the server uses
4321
+ * to track the session and accepts via `closeSession`.
4322
+ */
4323
+ handleOffer: method(
4324
+ zod.z.object({
4325
+ deviceId: zod.z.number().int().nonnegative(),
4326
+ target: WebrtcStreamTargetSchema.optional(),
4327
+ sdpOffer: zod.z.string(),
4328
+ sessionId: zod.z.string().optional()
4329
+ }),
4330
+ zod.z.object({ sessionId: zod.z.string(), sdpAnswer: zod.z.string() }),
4331
+ { kind: "mutation" }
4332
+ ),
4418
4333
  handleAnswer: method(
4419
4334
  zod.z.object({
4420
4335
  deviceId: zod.z.number().int().nonnegative(),
@@ -5054,12 +4969,12 @@ const audioCodecCapability = {
5054
4969
  };
5055
4970
  const EmbeddingResultSchema = zod.z.object({
5056
4971
  embedding: zod.z.array(zod.z.number()),
5057
- dimensions: zod.z.number()
4972
+ inferenceMs: zod.z.number()
5058
4973
  });
5059
4974
  const EmbeddingInfoSchema = zod.z.object({
5060
4975
  modelId: zod.z.string(),
5061
- dimensions: zod.z.number(),
5062
- inputSize: zod.z.number()
4976
+ embeddingDim: zod.z.number(),
4977
+ ready: zod.z.boolean()
5063
4978
  });
5064
4979
  const embeddingEncoderCapability = {
5065
4980
  name: "embedding-encoder",
@@ -5794,16 +5709,36 @@ const NetworkAccessStatusSchema = zod.z.object({
5794
5709
  endpoint: NetworkEndpointSchema.nullable(),
5795
5710
  error: zod.z.string().optional()
5796
5711
  });
5712
+ const NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
5713
+ /**
5714
+ * Stable id within the provider — typically `<mode>-<sourcePort>` so
5715
+ * the orchestrator can dedupe across `listEndpoints` polls.
5716
+ */
5717
+ id: zod.z.string(),
5718
+ /** Operator-facing label (mirrors `MeshEndpoint.label`). */
5719
+ label: zod.z.string(),
5720
+ /** Optional provider-specific mode tag, used for icon/colour in admin UI. */
5721
+ mode: zod.z.string().optional(),
5722
+ /** Originating local port the ingress fronts (informational). */
5723
+ sourcePort: zod.z.number().optional()
5724
+ });
5797
5725
  const networkAccessCapability = {
5798
5726
  name: "network-access",
5799
5727
  scope: "system",
5800
5728
  mode: "collection",
5801
5729
  internal: true,
5730
+ providerKind: "ingress",
5802
5731
  methods: {
5803
5732
  start: method(zod.z.void(), NetworkEndpointSchema, { kind: "mutation" }),
5804
5733
  stop: method(zod.z.void(), zod.z.void(), { kind: "mutation" }),
5805
5734
  getEndpoint: method(zod.z.void(), NetworkEndpointSchema.nullable()),
5806
- getStatus: method(zod.z.void(), NetworkAccessStatusSchema)
5735
+ getStatus: method(zod.z.void(), NetworkAccessStatusSchema),
5736
+ /**
5737
+ * Enumerate every active ingress entry. Default implementation (when
5738
+ * the provider omits this method) is derived from `getEndpoint()` —
5739
+ * see the remote-access orchestrator for the fallback path.
5740
+ */
5741
+ listEndpoints: method(zod.z.void(), zod.z.array(NetworkEndpointEntrySchema).readonly())
5807
5742
  }
5808
5743
  };
5809
5744
  const RemoteAccessEndpointSchema = zod.z.object({
@@ -6007,20 +5942,59 @@ const notificationOutputCapability = {
6007
5942
  )
6008
5943
  }
6009
5944
  };
5945
+ const NotificationRuleConditionsSchema = zod.z.object({
5946
+ deviceIds: zod.z.array(zod.z.number()).readonly().optional(),
5947
+ classNames: zod.z.array(zod.z.string()).readonly().optional(),
5948
+ zoneIds: zod.z.array(zod.z.string()).readonly().optional(),
5949
+ minConfidence: zod.z.number().optional(),
5950
+ source: zod.z.enum(["pipeline", "onboard", "any"]).optional(),
5951
+ schedule: zod.z.object({
5952
+ days: zod.z.array(zod.z.number()).readonly(),
5953
+ startHour: zod.z.number(),
5954
+ endHour: zod.z.number()
5955
+ }).optional(),
5956
+ cooldownSeconds: zod.z.number().optional(),
5957
+ minDwellSeconds: zod.z.number().optional()
5958
+ });
5959
+ const NotificationRuleTemplateSchema = zod.z.object({
5960
+ title: zod.z.string(),
5961
+ body: zod.z.string(),
5962
+ imageMode: zod.z.enum(["crop", "annotated", "full", "none"])
5963
+ });
6010
5964
  const NotificationRuleSchema = zod.z.object({
6011
5965
  id: zod.z.string(),
6012
5966
  name: zod.z.string(),
6013
5967
  enabled: zod.z.boolean(),
6014
- conditions: zod.z.record(zod.z.string(), zod.z.unknown()),
6015
- actions: zod.z.array(zod.z.record(zod.z.string(), zod.z.unknown()))
5968
+ eventTypes: zod.z.array(zod.z.string()).readonly(),
5969
+ conditions: NotificationRuleConditionsSchema,
5970
+ outputs: zod.z.array(zod.z.string()).readonly(),
5971
+ template: NotificationRuleTemplateSchema.optional(),
5972
+ priority: zod.z.enum(["low", "normal", "high", "critical"])
5973
+ });
5974
+ const NotificationTestResultSchema = zod.z.object({
5975
+ ruleId: zod.z.string(),
5976
+ eventId: zod.z.string(),
5977
+ timestamp: zod.z.number(),
5978
+ wouldFire: zod.z.boolean(),
5979
+ reason: zod.z.string().optional()
6016
5980
  });
6017
5981
  const NotificationHistoryEntrySchema = zod.z.object({
6018
5982
  id: zod.z.string(),
6019
5983
  ruleId: zod.z.string(),
5984
+ ruleName: zod.z.string(),
5985
+ eventId: zod.z.string(),
6020
5986
  timestamp: zod.z.number(),
6021
- deviceId: zod.z.number().optional(),
5987
+ outputs: zod.z.array(zod.z.string()).readonly(),
6022
5988
  success: zod.z.boolean(),
6023
- error: zod.z.string().optional()
5989
+ error: zod.z.string().optional(),
5990
+ deviceId: zod.z.number().optional()
5991
+ });
5992
+ const NotificationHistoryFilterSchema = zod.z.object({
5993
+ ruleId: zod.z.string().optional(),
5994
+ deviceId: zod.z.number().optional(),
5995
+ from: zod.z.number().optional(),
5996
+ to: zod.z.number().optional(),
5997
+ limit: zod.z.number().optional()
6024
5998
  });
6025
5999
  const advancedNotifierCapability = {
6026
6000
  name: "advanced-notifier",
@@ -6028,17 +6002,28 @@ const advancedNotifierCapability = {
6028
6002
  mode: "singleton",
6029
6003
  internal: true,
6030
6004
  methods: {
6031
- getRules: method(zod.z.void(), zod.z.array(NotificationRuleSchema).readonly()),
6032
- upsertRule: method(NotificationRuleSchema, zod.z.void(), { kind: "mutation" }),
6033
- deleteRule: method(zod.z.object({ ruleId: zod.z.string() }), zod.z.void(), { kind: "mutation" }),
6005
+ getRules: method(
6006
+ zod.z.void(),
6007
+ zod.z.object({ rules: zod.z.array(NotificationRuleSchema).readonly() })
6008
+ ),
6009
+ upsertRule: method(
6010
+ zod.z.object({ rule: NotificationRuleSchema }),
6011
+ zod.z.object({ success: zod.z.literal(true) }),
6012
+ { kind: "mutation" }
6013
+ ),
6014
+ deleteRule: method(
6015
+ zod.z.object({ ruleId: zod.z.string() }),
6016
+ zod.z.object({ success: zod.z.literal(true) }),
6017
+ { kind: "mutation" }
6018
+ ),
6034
6019
  testRule: method(
6035
6020
  zod.z.object({ ruleId: zod.z.string(), lookbackMinutes: zod.z.number() }),
6036
- zod.z.array(zod.z.record(zod.z.string(), zod.z.unknown())),
6021
+ zod.z.object({ results: zod.z.array(NotificationTestResultSchema).readonly() }),
6037
6022
  { kind: "mutation" }
6038
6023
  ),
6039
6024
  getHistory: method(
6040
- zod.z.object({ ruleId: zod.z.string().optional(), limit: zod.z.number().optional() }),
6041
- zod.z.array(NotificationHistoryEntrySchema)
6025
+ zod.z.object({ filter: NotificationHistoryFilterSchema.optional() }),
6026
+ zod.z.object({ entries: zod.z.array(NotificationHistoryEntrySchema).readonly() })
6042
6027
  )
6043
6028
  }
6044
6029
  };
@@ -7060,6 +7045,47 @@ const intercomCapability = {
7060
7045
  zod.z.object({ deviceId: zod.z.number(), sessionId: zod.z.string() }),
7061
7046
  zod.z.void(),
7062
7047
  { kind: "mutation", auth: "admin" }
7048
+ ),
7049
+ /**
7050
+ * Open a raw-PCM talk session (no WebRTC SDP plumbing). Used by
7051
+ * non-WebRTC consumers (HomeKit export, Alexa raw audio, test
7052
+ * harnesses) that already have decoded PCM frames and just need a
7053
+ * direct path onto the camera's talk channel. Mutually exclusive
7054
+ * with `startSession` (an active WebRTC session must be stopped
7055
+ * before a raw-PCM session can be opened on the same device, and
7056
+ * vice versa).
7057
+ */
7058
+ startTalkSession: method(
7059
+ zod.z.object({ deviceId: zod.z.number() }),
7060
+ zod.z.object({ sessionId: zod.z.string() }),
7061
+ { kind: "mutation", auth: "admin" }
7062
+ ),
7063
+ /**
7064
+ * Push a chunk of PCM s16le mono onto the active raw-PCM talk
7065
+ * session. Frames are encoded to the firmware's expected codec
7066
+ * (Reolink: IMA ADPCM @ camera sample rate; Hikvision: G.711 @
7067
+ * 8 kHz) inside the provider — callers must resample upstream to
7068
+ * the rate the camera negotiated (typical: 16 kHz Reolink,
7069
+ * 8 kHz Hikvision). PCM is shipped base64-encoded so the payload
7070
+ * survives JSON serialization across tRPC.
7071
+ */
7072
+ pushTalkPcm: method(
7073
+ zod.z.object({
7074
+ deviceId: zod.z.number(),
7075
+ /** PCM frames as little-endian s16, mono. Base64-encoded so
7076
+ * the payload survives tRPC JSON serialization. */
7077
+ pcmBase64: zod.z.string(),
7078
+ /** Sequence number for ordering / dropping out-of-order frames. */
7079
+ sequenceNumber: zod.z.number().int()
7080
+ }),
7081
+ zod.z.object({ accepted: zod.z.boolean() }),
7082
+ { kind: "mutation", auth: "admin" }
7083
+ ),
7084
+ /** Close the raw-PCM talk session. Idempotent. */
7085
+ endTalkSession: method(
7086
+ zod.z.object({ deviceId: zod.z.number() }),
7087
+ zod.z.void(),
7088
+ { kind: "mutation", auth: "admin" }
7063
7089
  )
7064
7090
  },
7065
7091
  events: {
@@ -7135,6 +7161,33 @@ const HwAccelBackendInputSchema = zod.z.enum([
7135
7161
  const HwAccelResolutionSchema = zod.z.object({
7136
7162
  preferred: zod.z.array(zod.z.string()).readonly()
7137
7163
  });
7164
+ const HardwareEncoderIdSchema = zod.z.enum([
7165
+ "h264_videotoolbox",
7166
+ "hevc_videotoolbox",
7167
+ "h264_vaapi",
7168
+ "hevc_vaapi",
7169
+ "h264_nvenc",
7170
+ "hevc_nvenc",
7171
+ "h264_qsv",
7172
+ "hevc_qsv",
7173
+ "h264_amf",
7174
+ "hevc_amf",
7175
+ "libx264",
7176
+ "libx265"
7177
+ ]);
7178
+ const HardwareEncoderProbeSchema = zod.z.object({
7179
+ encoder: HardwareEncoderIdSchema,
7180
+ codec: zod.z.enum(["H264", "H265"]),
7181
+ family: zod.z.enum(["videotoolbox", "vaapi", "nvenc", "qsv", "amf", "software"]),
7182
+ available: zod.z.boolean(),
7183
+ reason: zod.z.string().optional()
7184
+ });
7185
+ const HardwareEncodersSchema = zod.z.object({
7186
+ encoders: zod.z.array(HardwareEncoderProbeSchema).readonly(),
7187
+ defaultH264: HardwareEncoderIdSchema,
7188
+ defaultH265: HardwareEncoderIdSchema,
7189
+ probedAt: zod.z.number()
7190
+ });
7138
7191
  const HardwarePlatformSchema = zod.z.enum(["darwin", "linux", "win32"]);
7139
7192
  const HardwareArchSchema = zod.z.enum(["arm64", "x64"]);
7140
7193
  const GpuInfoSchema = zod.z.object({
@@ -7188,41 +7241,24 @@ const platformProbeCapability = {
7188
7241
  scope: "system",
7189
7242
  mode: "singleton",
7190
7243
  methods: {
7191
- /** Return cached hardware + scored backends for this node. */
7192
- getCapabilities: method(
7193
- zod.z.void(),
7194
- PlatformCapabilitiesSchema
7195
- ),
7196
- /** Convenience getter — hardware only. */
7197
- getHardware: method(
7198
- zod.z.void(),
7199
- HardwareInfoSchema
7200
- ),
7201
- /**
7202
- * Resolve the best (model, runtime, backend, format) for a given list
7203
- * of requirements, using this node's scored backends as the candidate
7204
- * pool. Always returns a config — falls back to CPU when no preferred
7205
- * backend matches.
7206
- */
7244
+ getCapabilities: method(zod.z.void(), PlatformCapabilitiesSchema),
7245
+ getHardware: method(zod.z.void(), HardwareInfoSchema),
7207
7246
  resolveInferenceConfig: method(
7208
- zod.z.object({
7209
- requirements: zod.z.array(ModelRequirementSchema).readonly()
7210
- }),
7247
+ zod.z.object({ requirements: zod.z.array(ModelRequirementSchema).readonly() }),
7211
7248
  ResolvedInferenceConfigSchema
7212
7249
  ),
7213
- /**
7214
- * Resolve the ordered HW acceleration backend list for this node.
7215
- * Pass `prefer` to hint a specific backend; pass `null` or omit
7216
- * for auto-detection. Replaces the legacy `$hwaccel.resolve`
7217
- * Moleculer action — cap routing handles per-node dispatch via
7218
- * `nodeId`.
7219
- */
7220
7250
  resolveHwAccel: method(
7221
- zod.z.object({
7222
- prefer: HwAccelBackendInputSchema,
7223
- nodeId: zod.z.string().optional()
7224
- }),
7251
+ zod.z.object({ prefer: HwAccelBackendInputSchema, nodeId: zod.z.string().optional() }),
7225
7252
  HwAccelResolutionSchema
7253
+ ),
7254
+ /**
7255
+ * Hardware-encoder probe — see Task #185. Cached after first call.
7256
+ */
7257
+ getHardwareEncoders: method(zod.z.void(), HardwareEncodersSchema),
7258
+ refreshHardwareEncoders: method(
7259
+ zod.z.void(),
7260
+ HardwareEncodersSchema,
7261
+ { kind: "mutation", auth: "admin" }
7226
7262
  )
7227
7263
  }
7228
7264
  };
@@ -7459,25 +7495,11 @@ const MeshStatusSchema = zod.z.object({
7459
7495
  /** Last error from the daemon, when not joined. */
7460
7496
  error: zod.z.string().optional()
7461
7497
  });
7462
- const PublicIngressConfigSchema = zod.z.object({
7463
- /** Whether the provider should expose CamStack via its public
7464
- * ingress (Tailscale Funnel, etc.). */
7465
- enabled: zod.z.boolean(),
7466
- /** Local port to forward. Auto-detected from the hub HTTP port
7467
- * when omitted. */
7468
- port: zod.z.number().int().min(1).max(65535).optional()
7469
- });
7470
- const MeshIngressConfigSchema = zod.z.object({
7471
- /** Whether the provider should expose CamStack inside the mesh
7472
- * via HTTPS (Tailscale Serve, etc.) instead of just raw IP. */
7473
- enabled: zod.z.boolean(),
7474
- /** Local port to forward. Auto-detected when omitted. */
7475
- port: zod.z.number().int().min(1).max(65535).optional()
7476
- });
7477
7498
  const meshNetworkCapability = {
7478
7499
  name: "mesh-network",
7479
7500
  scope: "system",
7480
7501
  mode: "collection",
7502
+ providerKind: "mesh",
7481
7503
  methods: {
7482
7504
  /** Return the current join state + endpoints + peer count. Cheap
7483
7505
  * poll-target — admin UI hits this every few seconds. */
@@ -7499,6 +7521,29 @@ const meshNetworkCapability = {
7499
7521
  zod.z.object({ joined: zod.z.literal(true) }),
7500
7522
  { kind: "mutation" }
7501
7523
  ),
7524
+ /**
7525
+ * Start an interactive browser-redirect login flow.
7526
+ *
7527
+ * The provider spawns its daemon's join command without a pre-auth
7528
+ * key, captures the verification URL the daemon prints, and returns
7529
+ * it. The admin UI opens the URL in a new tab; the user completes
7530
+ * authentication in the provider's web console and the background
7531
+ * process self-terminates. The caller then polls `getStatus()` until
7532
+ * `joined: true`.
7533
+ *
7534
+ * Mirrors the `tailscale up` (no `--auth-key`) flow.
7535
+ */
7536
+ startLogin: method(
7537
+ zod.z.object({
7538
+ /** Optional hostname override the host should advertise once joined. */
7539
+ hostname: zod.z.string().optional()
7540
+ }),
7541
+ zod.z.object({
7542
+ /** Authentication URL the operator should open in a browser. */
7543
+ loginUrl: zod.z.string()
7544
+ }),
7545
+ { kind: "mutation" }
7546
+ ),
7502
7547
  /** Leave the mesh. After this the meshIp/magicDnsHostname/etc.
7503
7548
  * vanish until the next `join`. */
7504
7549
  leave: method(
@@ -7510,24 +7555,6 @@ const meshNetworkCapability = {
7510
7555
  listPeers: method(zod.z.void(), zod.z.object({
7511
7556
  peers: zod.z.array(MeshPeerSchema).readonly()
7512
7557
  })),
7513
- /**
7514
- * Toggle the public ingress (e.g. Tailscale Funnel) that maps a
7515
- * local port to the open internet via the provider's edge. Idempotent.
7516
- */
7517
- setPublicIngress: method(
7518
- PublicIngressConfigSchema,
7519
- zod.z.object({ success: zod.z.literal(true) }),
7520
- { kind: "mutation" }
7521
- ),
7522
- /**
7523
- * Toggle the in-mesh HTTPS ingress (e.g. Tailscale Serve) so peers
7524
- * inside the mesh hit a valid TLS endpoint instead of the raw IP.
7525
- */
7526
- setMeshIngress: method(
7527
- MeshIngressConfigSchema,
7528
- zod.z.object({ success: zod.z.literal(true) }),
7529
- { kind: "mutation" }
7530
- ),
7531
7558
  /**
7532
7559
  * Probe the mesh daemon / API for a sanity check WITHOUT joining.
7533
7560
  * Operator-facing "test connection" button: validates the auth key
@@ -8461,6 +8488,7 @@ exports.AUDIO_MACRO_LABELS = AUDIO_MACRO_LABELS;
8461
8488
  exports.AbortUploadInputSchema = AbortUploadInputSchema;
8462
8489
  exports.AccessoriesStatusSchema = AccessoriesStatusSchema;
8463
8490
  exports.AccessoryKind = AccessoryKind;
8491
+ exports.AddBrokerInputSchema = AddBrokerInputSchema;
8464
8492
  exports.AddonAutoUpdateSchema = AddonAutoUpdateSchema;
8465
8493
  exports.AddonListItemSchema = AddonListItemSchema;
8466
8494
  exports.AddonPageDeclarationSchema = AddonPageDeclarationSchema;
@@ -8506,10 +8534,12 @@ exports.BoundingBoxSchema = BoundingBoxSchema;
8506
8534
  exports.BrightnessStatusSchema = BrightnessStatusSchema;
8507
8535
  exports.BrokerAudioClientSchema = BrokerAudioClientSchema;
8508
8536
  exports.BrokerClientsSchema = BrokerClientsSchema;
8537
+ exports.BrokerConnectionDetailsSchema = BrokerConnectionDetailsSchema;
8509
8538
  exports.BrokerDecodedClientSchema = BrokerDecodedClientSchema;
8539
+ exports.BrokerInfoSchema = BrokerInfoSchema;
8510
8540
  exports.BrokerRtspClientSchema = BrokerRtspClientSchema;
8511
8541
  exports.BrokerStatsSchema = BrokerStatsSchema;
8512
- exports.BrokerStatusSchema = BrokerStatusSchema;
8542
+ exports.BrokerStatusSchema = BrokerStatusSchema$1;
8513
8543
  exports.CAM_PROFILE_ORDER = CAM_PROFILE_ORDER;
8514
8544
  exports.CamProfileSchema = CamProfileSchema;
8515
8545
  exports.CamStreamKindSchema = CamStreamKindSchema;
@@ -8549,6 +8579,7 @@ exports.DecoderStatsSchema = DecoderStatsSchema;
8549
8579
  exports.DeleteIntegrationResultSchema = DeleteIntegrationResultSchema;
8550
8580
  exports.DetectorOutputSchema = DetectorOutputSchema;
8551
8581
  exports.DeviceDiscoveryStatusSchema = DeviceDiscoveryStatusSchema;
8582
+ exports.DeviceExportStatusSchema = DeviceExportStatusSchema;
8552
8583
  exports.DeviceFeature = DeviceFeature;
8553
8584
  exports.DeviceInfoSchema = DeviceInfoSchema;
8554
8585
  exports.DeviceNetworkStatsSchema = DeviceNetworkStatsSchema;
@@ -8567,16 +8598,16 @@ exports.EndDownloadInputSchema = EndDownloadInputSchema;
8567
8598
  exports.EnrichedWidgetMetadataSchema = EnrichedWidgetMetadataSchema;
8568
8599
  exports.EventItemSchema = EventItemSchema;
8569
8600
  exports.EventKindSchema = EventKindSchema;
8601
+ exports.ExposeInputSchema = ExposeInputSchema;
8602
+ exports.ExposedDeviceSchema = ExposedDeviceSchema;
8570
8603
  exports.ExposedResourceSchema = ExposedResourceSchema;
8571
8604
  exports.FeatureManifestSchema = FeatureManifestSchema;
8572
8605
  exports.FeatureProbeStatusSchema = FeatureProbeStatusSchema;
8573
8606
  exports.FinalizeUploadInputSchema = FinalizeUploadInputSchema;
8574
8607
  exports.FrameInputSchema = FrameInputSchema;
8608
+ exports.GetStreamWithCodecInputSchema = GetStreamWithCodecInputSchema;
8575
8609
  exports.GlobalMetricsSchema = GlobalMetricsSchema;
8576
8610
  exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
8577
- exports.HaServiceCallSchema = HaServiceCallSchema;
8578
- exports.HaStateSchema = HaStateSchema;
8579
- exports.HaStatusSchema = HaStatusSchema;
8580
8611
  exports.HealthStatusSchema = HealthStatusSchema;
8581
8612
  exports.HistoryPointSchema = HistoryPointSchema;
8582
8613
  exports.HistoryResolutionEnum = HistoryResolutionEnum;
@@ -8601,7 +8632,6 @@ exports.MotionSourcesSchema = MotionSourcesSchema;
8601
8632
  exports.MotionStatusSchema = MotionStatusSchema;
8602
8633
  exports.MotionTriggerRuntimeStateSchema = MotionTriggerRuntimeStateSchema;
8603
8634
  exports.MotionTriggerStatusSchema = MotionTriggerStatusSchema;
8604
- exports.MqttStatusSchema = MqttStatusSchema;
8605
8635
  exports.NativeDetectionSchema = NativeDetectionSchema;
8606
8636
  exports.NativeObjectClassEnum = NativeObjectClassEnum;
8607
8637
  exports.NativeObjectDetectionStatusSchema = NativeObjectDetectionStatusSchema;
@@ -8643,13 +8673,13 @@ exports.PtzAutotrackTargetOptionSchema = PtzAutotrackTargetOptionSchema;
8643
8673
  exports.PtzMoveCommandSchema = PtzMoveCommandSchema;
8644
8674
  exports.PtzPositionSchema = PtzPositionSchema;
8645
8675
  exports.PtzPresetSchema = PtzPresetSchema;
8646
- exports.PublishInputSchema = PublishInputSchema;
8647
8676
  exports.QueryFilterSchema = QueryFilterSchema;
8648
8677
  exports.ReadChunkInputSchema = ReadChunkInputSchema;
8649
8678
  exports.RegisteredStreamSchema = RegisteredStreamSchema;
8650
8679
  exports.RemoteAccessEndpointSchema = RemoteAccessEndpointSchema;
8651
8680
  exports.RemoteAccessProviderInfoSchema = RemoteAccessProviderInfoSchema;
8652
8681
  exports.ReportMotionInputSchema = ReportMotionInputSchema;
8682
+ exports.RtpSourceSchema = RtpSourceSchema;
8653
8683
  exports.RtspRestreamEntrySchema = RtspRestreamEntrySchema;
8654
8684
  exports.RunnerCameraConfigSchema = RunnerCameraConfigSchema;
8655
8685
  exports.RunnerCameraDeviceUIFields = RunnerCameraDeviceUIFields;
@@ -8670,6 +8700,8 @@ exports.SmtpStatusSchema = SmtpStatusSchema;
8670
8700
  exports.SnapshotImageSchema = SnapshotImageSchema;
8671
8701
  exports.SpatialDetectionSchema = SpatialDetectionSchema;
8672
8702
  exports.SsoBridgeClaimsSchema = SsoBridgeClaimsSchema;
8703
+ exports.StartEmbeddedInputSchema = StartEmbeddedInputSchema;
8704
+ exports.StatusSchema = StatusSchema;
8673
8705
  exports.StorageLocationRefSchema = StorageLocationRefSchema;
8674
8706
  exports.StorageLocationSchema = StorageLocationSchema;
8675
8707
  exports.StorageLocationTypeSchema = StorageLocationTypeSchema;
@@ -8678,8 +8710,6 @@ exports.StreamInfoSchema = StreamInfoSchema;
8678
8710
  exports.StreamNetworkStatsSchema = StreamNetworkStatsSchema;
8679
8711
  exports.StreamSourceEntrySchema = StreamSourceEntrySchema$1;
8680
8712
  exports.StreamSourceSchema = StreamSourceSchema;
8681
- exports.SubscribeInputSchema = SubscribeInputSchema;
8682
- exports.SubscriptionInfoSchema = SubscriptionInfoSchema;
8683
8713
  exports.SwitchStatusSchema = SwitchStatusSchema;
8684
8714
  exports.SystemMetricsSchema = SystemMetricsSchema;
8685
8715
  exports.TestConnectionResultSchema = TestConnectionResultSchema;
@@ -8694,6 +8724,7 @@ exports.TrackStateSchema = TrackStateSchema;
8694
8724
  exports.TrackedDetectionSchema = TrackedDetectionSchema;
8695
8725
  exports.TurnProviderInfoSchema = TurnProviderInfoSchema;
8696
8726
  exports.TurnServerSchema = TurnServerSchema;
8727
+ exports.UnexposeInputSchema = UnexposeInputSchema;
8697
8728
  exports.UpdateIntegrationInputSchema = UpdateIntegrationInputSchema;
8698
8729
  exports.UpdateUserInputSchema = UpdateUserInputSchema;
8699
8730
  exports.UserRecordSchema = UserRecordSchema;
@@ -8740,6 +8771,7 @@ exports.cameraStreamsCapability = cameraStreamsCapability;
8740
8771
  exports.decoderCapability = decoderCapability;
8741
8772
  exports.detectionPipelineCapability = detectionPipelineCapability;
8742
8773
  exports.deviceDiscoveryCapability = deviceDiscoveryCapability;
8774
+ exports.deviceExportCapability = deviceExportCapability;
8743
8775
  exports.deviceManagerCapability = deviceManagerCapability;
8744
8776
  exports.deviceMatchesProfile = deviceMatchesProfile;
8745
8777
  exports.deviceOpsCapability = deviceOpsCapability;
@@ -8754,7 +8786,6 @@ exports.eventsCapability = eventsCapability;
8754
8786
  exports.expandCapMethods = expandCapMethods;
8755
8787
  exports.featureProbeCapability = featureProbeCapability;
8756
8788
  exports.getAudioMacroClassIds = getAudioMacroClassIds;
8757
- exports.homeAssistantCapability = homeAssistantCapability;
8758
8789
  exports.hydrateSchema = hydrateSchema;
8759
8790
  exports.integrationsCapability = integrationsCapability;
8760
8791
  exports.intercomCapability = intercomCapability;
@@ -8768,7 +8799,7 @@ exports.metricsProviderCapability = metricsProviderCapability;
8768
8799
  exports.motionCapability = motionCapability;
8769
8800
  exports.motionDetectionCapability = motionDetectionCapability;
8770
8801
  exports.motionTriggerCapability = motionTriggerCapability;
8771
- exports.mqttProviderCapability = mqttProviderCapability;
8802
+ exports.mqttBrokerCapability = mqttBrokerCapability;
8772
8803
  exports.nativeObjectDetectionCapability = nativeObjectDetectionCapability;
8773
8804
  exports.networkAccessCapability = networkAccessCapability;
8774
8805
  exports.networkQualityCapability = networkQualityCapability;
@@ -8810,4 +8841,4 @@ exports.webrtcSessionCapability = webrtcSessionCapability;
8810
8841
  exports.zoneAnalyticsCapability = zoneAnalyticsCapability;
8811
8842
  exports.zoneRulesCapability = zoneRulesCapability;
8812
8843
  exports.zonesCapability = zonesCapability;
8813
- //# sourceMappingURL=index-BKifir_y.js.map
8844
+ //# sourceMappingURL=index-BUBhoPUu.js.map