@camstack/types 0.1.34 → 0.1.36

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 (112) hide show
  1. package/dist/capabilities/addon-widgets-source.cap.d.ts +73 -5
  2. package/dist/capabilities/addon-widgets-source.cap.d.ts.map +1 -1
  3. package/dist/capabilities/addon-widgets.cap.d.ts +22 -4
  4. package/dist/capabilities/addon-widgets.cap.d.ts.map +1 -1
  5. package/dist/capabilities/addons.cap.d.ts +21 -0
  6. package/dist/capabilities/addons.cap.d.ts.map +1 -1
  7. package/dist/capabilities/audio-analysis.cap.d.ts +7 -4
  8. package/dist/capabilities/audio-analysis.cap.d.ts.map +1 -1
  9. package/dist/capabilities/camera-streams.cap.d.ts +7 -5
  10. package/dist/capabilities/camera-streams.cap.d.ts.map +1 -1
  11. package/dist/capabilities/capability-definition.d.ts +114 -0
  12. package/dist/capabilities/capability-definition.d.ts.map +1 -1
  13. package/dist/capabilities/decoder.cap.d.ts +90 -0
  14. package/dist/capabilities/decoder.cap.d.ts.map +1 -1
  15. package/dist/capabilities/detection-pipeline.cap.d.ts +6 -4
  16. package/dist/capabilities/detection-pipeline.cap.d.ts.map +1 -1
  17. package/dist/capabilities/device-manager.cap.d.ts +3 -3
  18. package/dist/capabilities/device-ops.cap.d.ts +1 -1
  19. package/dist/capabilities/index.d.ts +20 -20
  20. package/dist/capabilities/index.d.ts.map +1 -1
  21. package/dist/capabilities/local-network.cap.d.ts +5 -5
  22. package/dist/capabilities/mesh-network.cap.d.ts +4 -2
  23. package/dist/capabilities/mesh-network.cap.d.ts.map +1 -1
  24. package/dist/capabilities/motion-detection.cap.d.ts +2 -0
  25. package/dist/capabilities/motion-detection.cap.d.ts.map +1 -1
  26. package/dist/capabilities/motion-zones.cap.d.ts +83 -0
  27. package/dist/capabilities/motion-zones.cap.d.ts.map +1 -0
  28. package/dist/capabilities/network-access.cap.d.ts +5 -4
  29. package/dist/capabilities/network-access.cap.d.ts.map +1 -1
  30. package/dist/capabilities/nodes.cap.d.ts +9 -0
  31. package/dist/capabilities/nodes.cap.d.ts.map +1 -1
  32. package/dist/capabilities/oauth-integration.cap.d.ts +103 -0
  33. package/dist/capabilities/oauth-integration.cap.d.ts.map +1 -0
  34. package/dist/capabilities/pipeline-analytics.cap.d.ts +2 -0
  35. package/dist/capabilities/pipeline-analytics.cap.d.ts.map +1 -1
  36. package/dist/capabilities/ptz-autotrack.cap.d.ts +10 -0
  37. package/dist/capabilities/ptz-autotrack.cap.d.ts.map +1 -1
  38. package/dist/capabilities/ptz.cap.d.ts +57 -1
  39. package/dist/capabilities/ptz.cap.d.ts.map +1 -1
  40. package/dist/capabilities/schemas/streaming-shared.d.ts +110 -3
  41. package/dist/capabilities/schemas/streaming-shared.d.ts.map +1 -1
  42. package/dist/capabilities/snapshot.cap.d.ts +2 -0
  43. package/dist/capabilities/snapshot.cap.d.ts.map +1 -1
  44. package/dist/capabilities/sso-bridge.cap.d.ts +120 -0
  45. package/dist/capabilities/sso-bridge.cap.d.ts.map +1 -1
  46. package/dist/capabilities/stream-broker.cap.d.ts +97 -4
  47. package/dist/capabilities/stream-broker.cap.d.ts.map +1 -1
  48. package/dist/capabilities/stream-params-config-schema.d.ts +56 -0
  49. package/dist/capabilities/stream-params-config-schema.d.ts.map +1 -0
  50. package/dist/capabilities/stream-params.cap.d.ts +482 -0
  51. package/dist/capabilities/stream-params.cap.d.ts.map +1 -0
  52. package/dist/capabilities/user-management.cap.d.ts +198 -1
  53. package/dist/capabilities/user-management.cap.d.ts.map +1 -1
  54. package/dist/capabilities/webrtc-session.cap.d.ts +2 -0
  55. package/dist/capabilities/webrtc-session.cap.d.ts.map +1 -1
  56. package/dist/generated/addon-api.d.ts +1396 -544
  57. package/dist/generated/addon-api.d.ts.map +1 -1
  58. package/dist/generated/cap-status-types.d.ts +7 -3
  59. package/dist/generated/cap-status-types.d.ts.map +1 -1
  60. package/dist/generated/capability-router-map.d.ts +13 -16
  61. package/dist/generated/capability-router-map.d.ts.map +1 -1
  62. package/dist/generated/device-local-state.d.ts +6 -0
  63. package/dist/generated/device-local-state.d.ts.map +1 -1
  64. package/dist/generated/device-proxy.d.ts +6 -0
  65. package/dist/generated/device-proxy.d.ts.map +1 -1
  66. package/dist/generated/method-access-map.d.ts +1 -1
  67. package/dist/generated/method-access-map.d.ts.map +1 -1
  68. package/dist/generated/system-proxy.d.ts +7 -13
  69. package/dist/generated/system-proxy.d.ts.map +1 -1
  70. package/dist/{index-DS7418lf.js → index-BblD92Si.js} +630 -349
  71. package/dist/index-BblD92Si.js.map +1 -0
  72. package/dist/{index-Ce7RZWP4.mjs → index-CgPd35k5.mjs} +957 -676
  73. package/dist/index-CgPd35k5.mjs.map +1 -0
  74. package/dist/index.d.ts +2 -1
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +325 -75
  77. package/dist/index.js.map +1 -1
  78. package/dist/index.mjs +597 -347
  79. package/dist/index.mjs.map +1 -1
  80. package/dist/interfaces/addon.d.ts +123 -29
  81. package/dist/interfaces/addon.d.ts.map +1 -1
  82. package/dist/interfaces/capability.d.ts +7 -29
  83. package/dist/interfaces/capability.d.ts.map +1 -1
  84. package/dist/interfaces/config-ui.d.ts +4 -101
  85. package/dist/interfaces/config-ui.d.ts.map +1 -1
  86. package/dist/interfaces/decoder.d.ts +12 -0
  87. package/dist/interfaces/decoder.d.ts.map +1 -1
  88. package/dist/interfaces/device-provider.d.ts +0 -4
  89. package/dist/interfaces/device-provider.d.ts.map +1 -1
  90. package/dist/interfaces/event-bus.d.ts +15 -0
  91. package/dist/interfaces/event-bus.d.ts.map +1 -1
  92. package/dist/interfaces/frame-handle.d.ts +40 -0
  93. package/dist/interfaces/frame-handle.d.ts.map +1 -0
  94. package/dist/interfaces/kernel-abstractions.d.ts +6 -0
  95. package/dist/interfaces/kernel-abstractions.d.ts.map +1 -1
  96. package/dist/interfaces/server-network.d.ts +8 -33
  97. package/dist/interfaces/server-network.d.ts.map +1 -1
  98. package/dist/interfaces/stream-broker.d.ts +40 -21
  99. package/dist/interfaces/stream-broker.d.ts.map +1 -1
  100. package/dist/node.js +1 -1
  101. package/dist/node.mjs +1 -1
  102. package/package.json +1 -1
  103. package/dist/capabilities/authentication.cap.d.ts +0 -73
  104. package/dist/capabilities/authentication.cap.d.ts.map +0 -1
  105. package/dist/capabilities/mesh-orchestrator.cap.d.ts +0 -151
  106. package/dist/capabilities/mesh-orchestrator.cap.d.ts.map +0 -1
  107. package/dist/capabilities/remote-access.cap.d.ts +0 -91
  108. package/dist/capabilities/remote-access.cap.d.ts.map +0 -1
  109. package/dist/capabilities/turn-orchestrator.cap.d.ts +0 -64
  110. package/dist/capabilities/turn-orchestrator.cap.d.ts.map +0 -1
  111. package/dist/index-Ce7RZWP4.mjs.map +0 -1
  112. package/dist/index-DS7418lf.js.map +0 -1
@@ -13,6 +13,7 @@ const WELL_KNOWN_TABS = [
13
13
  { id: "osd", label: "OSD", icon: "type", order: 18 },
14
14
  { id: "stream-broker", label: "Stream Broker", icon: "radio", order: 20 },
15
15
  { id: "streaming", label: "Streaming", icon: "video", order: 35 },
16
+ { id: "ptz", label: "PTZ", icon: "move", order: 40 },
16
17
  { id: "pipeline", label: "Detection Pipeline", icon: "cpu", order: 39 },
17
18
  { id: "zones", label: "Detection", icon: "shapes", order: 38 },
18
19
  { id: "live-stats", label: "Live Stats", icon: "activity", order: 39 },
@@ -80,6 +81,9 @@ function hydrateField(field, values) {
80
81
  return { ...field, value: items };
81
82
  }
82
83
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
84
+ if (field.type === "password") {
85
+ return { ...field, value: "" };
86
+ }
83
87
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
84
88
  const hydrated = { ...field, value };
85
89
  return hydrated;
@@ -182,7 +186,19 @@ const DecoderSessionConfigSchema = zod.z.object({
182
186
  * on every line so `grep tag=broker:5/high` filters one camera
183
187
  * profile cleanly.
184
188
  */
185
- tag: zod.z.string().optional()
189
+ tag: zod.z.string().optional(),
190
+ /**
191
+ * Where the session delivers decoded frames (Phase 5 / D9):
192
+ *
193
+ * - `'callback'` (default) — the legacy pixel path: decoded frames are
194
+ * buffered as `DecodedFrame`s and drained via `pullFrames`.
195
+ * - `'shm'` — the shared-memory frame plane: decoded frames are written
196
+ * into an OS shared-memory ring and drained as zero-pixel
197
+ * `FrameHandle`s via `pullHandles`. A session is one mode or the
198
+ * other — `pullFrames` returns nothing for an `'shm'` session and
199
+ * `pullHandles` returns nothing for a `'callback'` session.
200
+ */
201
+ frameSink: zod.z.enum(["callback", "shm"]).default("callback")
186
202
  });
187
203
  function errMsg(err) {
188
204
  if (err instanceof Error) return err.message;
@@ -768,6 +784,9 @@ function method(input, output, options) {
768
784
  function event(data) {
769
785
  return { data };
770
786
  }
787
+ function isDeviceConfigCap(def) {
788
+ return def?.deviceConfig !== void 0;
789
+ }
771
790
  const AudioClassSummarySchema = zod.z.object({
772
791
  className: zod.z.string(),
773
792
  /** Number of windows (chunks) where this class was the top hit. */
@@ -1070,6 +1089,53 @@ const DecodedFrameSchema = zod.z.object({
1070
1089
  format: zod.z.enum(["jpeg", "rgb", "bgr", "yuv420", "gray"]),
1071
1090
  timestamp: zod.z.number()
1072
1091
  });
1092
+ const FrameHandleSchema = zod.z.object({
1093
+ shmId: zod.z.string(),
1094
+ slot: zod.z.number().int().nonnegative(),
1095
+ seq: zod.z.number().int().nonnegative(),
1096
+ width: zod.z.number().int().positive(),
1097
+ height: zod.z.number().int().positive(),
1098
+ format: zod.z.enum(["jpeg", "rgb", "bgr", "yuv420", "gray"]),
1099
+ pts: zod.z.number(),
1100
+ byteLength: zod.z.number().int().nonnegative(),
1101
+ nodeId: zod.z.string(),
1102
+ slotCount: zod.z.number().int().positive()
1103
+ });
1104
+ const FrameHandleFormatSchema = zod.z.enum(["rgb", "bgr", "yuv420", "gray"]);
1105
+ const SubscribeFramesInputSchema = zod.z.object({
1106
+ brokerId: zod.z.string(),
1107
+ format: FrameHandleFormatSchema,
1108
+ /**
1109
+ * Optional reader-side cadence hint in frames per second. The broker does
1110
+ * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
1111
+ * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
1112
+ * the consumer can pace its own `pullFrameHandles` polling.
1113
+ */
1114
+ maxFps: zod.z.number().positive().optional(),
1115
+ /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
1116
+ tag: zod.z.string().optional()
1117
+ });
1118
+ const SubscribeFramesResultSchema = zod.z.object({
1119
+ /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
1120
+ subscriptionId: zod.z.string(),
1121
+ /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
1122
+ maxFps: zod.z.number().nonnegative()
1123
+ });
1124
+ const DecodedAudioChunkSchema = zod.z.object({
1125
+ data: zod.z.instanceof(Uint8Array),
1126
+ sampleRate: zod.z.number().int().positive(),
1127
+ channels: zod.z.number().int().positive(),
1128
+ timestamp: zod.z.number()
1129
+ });
1130
+ const SubscribeAudioChunksInputSchema = zod.z.object({
1131
+ brokerId: zod.z.string(),
1132
+ /** Short caller-identity tag (`audio-analyzer`, …) for `listClients`. */
1133
+ tag: zod.z.string().optional()
1134
+ });
1135
+ const SubscribeAudioChunksResultSchema = zod.z.object({
1136
+ /** Opaque id passed to `pullAudioChunks` / `unsubscribeAudioChunks`. */
1137
+ subscriptionId: zod.z.string()
1138
+ });
1073
1139
  const BrokerStatusSchema$1 = zod.z.enum(["idle", "connecting", "streaming", "error", "stopped"]);
1074
1140
  const BrokerStatsSchema = zod.z.object({
1075
1141
  status: BrokerStatusSchema$1,
@@ -1299,9 +1365,76 @@ const streamBrokerCapability = {
1299
1365
  zod.z.object({ released: zod.z.boolean(), refcount: zod.z.number().int().nonnegative() }),
1300
1366
  { kind: "mutation", auth: "admin" }
1301
1367
  ),
1302
- getBroker: method(
1303
- zod.z.object({ brokerId: zod.z.string() }),
1304
- zod.z.custom()
1368
+ /**
1369
+ * ── Decoded audio-chunk plane (Phase 5 / D9) ──────────────────────
1370
+ *
1371
+ * The serialisable replacement for the live-object `IStreamBroker.
1372
+ * onDecodedAudioChunk` callback path. Unlike the video frame plane,
1373
+ * audio chunks are tiny (a ~500ms PCM window is a few KB) so they ship
1374
+ * their bytes INLINE over tRPC — no shared-memory ring. A consumer:
1375
+ *
1376
+ * 1. `subscribeAudioChunks({ brokerId, tag })` — the broker registers
1377
+ * a per-subscription bounded FIFO queue and returns a
1378
+ * `subscriptionId`.
1379
+ * 2. polls `pullAudioChunks({ subscriptionId, maxCount })` — drains
1380
+ * `DecodedAudioChunk[]` in arrival order (FIFO, no latest-wins
1381
+ * drop: an audio gap is audible / breaks an analysis window). The
1382
+ * queue is generously sized; it only drops its oldest chunk if a
1383
+ * truly stalled consumer lets it overflow.
1384
+ * 3. `unsubscribeAudioChunks({ subscriptionId })` on teardown.
1385
+ */
1386
+ subscribeAudioChunks: method(
1387
+ SubscribeAudioChunksInputSchema,
1388
+ SubscribeAudioChunksResultSchema,
1389
+ { kind: "mutation" }
1390
+ ),
1391
+ pullAudioChunks: method(
1392
+ zod.z.object({
1393
+ subscriptionId: zod.z.string(),
1394
+ maxCount: zod.z.number().int().positive().default(8)
1395
+ }),
1396
+ zod.z.array(DecodedAudioChunkSchema).readonly()
1397
+ ),
1398
+ unsubscribeAudioChunks: method(
1399
+ zod.z.object({ subscriptionId: zod.z.string() }),
1400
+ zod.z.object({ released: zod.z.boolean() }),
1401
+ { kind: "mutation" }
1402
+ ),
1403
+ /**
1404
+ * ── Shared-memory frame plane (Phase 5 / D9) ──────────────────────
1405
+ *
1406
+ * The handle-based replacement for the live-object `IStreamBroker.
1407
+ * onDecodedFrame` callback path. A consumer:
1408
+ *
1409
+ * 1. `subscribeFrames({ brokerId, format })` — the broker spins up
1410
+ * (or reuses) a `frameSink: 'shm'` decoder session producing that
1411
+ * `format` and returns a `subscriptionId`.
1412
+ * 2. polls `pullFrameHandles({ subscriptionId, maxCount })` — drains
1413
+ * zero-pixel `FrameHandle[]`; each handle is fed to a
1414
+ * `FrameRingReader` that opens the named shm segment and reads the
1415
+ * pixels back zero-copy.
1416
+ * 3. `unsubscribeFrames({ subscriptionId })` on teardown.
1417
+ *
1418
+ * The broker keeps one shm ring per `(brokerId, format)` actually
1419
+ * requested — no broker-side `sharp` conversion. fps throttling is
1420
+ * implicit (latest-wins ring reads drop frames for a slow consumer).
1421
+ */
1422
+ subscribeFrames: method(
1423
+ SubscribeFramesInputSchema,
1424
+ SubscribeFramesResultSchema,
1425
+ { kind: "mutation" }
1426
+ ),
1427
+ pullFrameHandles: method(
1428
+ zod.z.object({
1429
+ subscriptionId: zod.z.string(),
1430
+ maxCount: zod.z.number().int().positive().default(4)
1431
+ }),
1432
+ zod.z.array(FrameHandleSchema).readonly()
1433
+ ),
1434
+ unsubscribeFrames: method(
1435
+ zod.z.object({ subscriptionId: zod.z.string() }),
1436
+ zod.z.object({ released: zod.z.boolean() }),
1437
+ { kind: "mutation" }
1305
1438
  ),
1306
1439
  setPreBufferDuration: method(
1307
1440
  zod.z.object({ brokerId: zod.z.string(), seconds: zod.z.number().min(0).max(30) }),
@@ -1357,6 +1490,8 @@ const cameraStreamsCapability = {
1357
1490
  name: "camera-streams",
1358
1491
  scope: "device",
1359
1492
  mode: "singleton",
1493
+ kind: "wrapper",
1494
+ defaultActive: true,
1360
1495
  deviceTypes: [DeviceType.Camera],
1361
1496
  methods: {
1362
1497
  getCameraStreams: method(
@@ -1652,6 +1787,8 @@ const motionDetectionCapability = {
1652
1787
  name: "motion-detection",
1653
1788
  scope: "device",
1654
1789
  mode: "singleton",
1790
+ kind: "wrapper",
1791
+ defaultActive: true,
1655
1792
  exposesDeviceSettings: true,
1656
1793
  methods: {
1657
1794
  analyze: method(
@@ -2523,6 +2660,42 @@ const motionTriggerCapability = {
2523
2660
  },
2524
2661
  runtimeState: MotionTriggerRuntimeStateSchema
2525
2662
  };
2663
+ const MotionZoneStatusSchema = zod.z.object({
2664
+ enabled: zod.z.boolean(),
2665
+ sensitivity: zod.z.number(),
2666
+ /** Row-major active-cell grid. Length = gridWidth*gridHeight (see getOptions). */
2667
+ cells: zod.z.array(zod.z.boolean()),
2668
+ lastFetchedAt: zod.z.number()
2669
+ });
2670
+ const MotionZoneOptionsSchema = zod.z.object({
2671
+ gridWidth: zod.z.number(),
2672
+ gridHeight: zod.z.number(),
2673
+ sensitivity: zod.z.object({ min: zod.z.number(), max: zod.z.number(), step: zod.z.number() })
2674
+ });
2675
+ const MotionZonePatchSchema = zod.z.object({
2676
+ enabled: zod.z.boolean().optional(),
2677
+ sensitivity: zod.z.number().optional(),
2678
+ cells: zod.z.array(zod.z.boolean()).optional()
2679
+ });
2680
+ const motionZonesCapability = {
2681
+ name: "motion-zones",
2682
+ scope: "device",
2683
+ mode: "singleton",
2684
+ deviceTypes: [DeviceType.Camera],
2685
+ deviceConfig: {
2686
+ ui: { kind: "widget", widgetId: "host/motion-zones-grid", tab: "motion", label: "Motion Zones" }
2687
+ },
2688
+ methods: {
2689
+ getOptions: method(zod.z.object({ deviceId: zod.z.number() }), MotionZoneOptionsSchema),
2690
+ setZone: method(
2691
+ zod.z.object({ deviceId: zod.z.number(), patch: MotionZonePatchSchema }),
2692
+ zod.z.void(),
2693
+ { kind: "mutation", auth: "admin" }
2694
+ )
2695
+ },
2696
+ status: { schema: MotionZoneStatusSchema, kind: "poll" },
2697
+ runtimeState: MotionZoneStatusSchema
2698
+ };
2526
2699
  const AutotrackTargetTypeSchema = zod.z.string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
2527
2700
  const PtzAutotrackSettingsSchema = zod.z.object({
2528
2701
  targetType: AutotrackTargetTypeSchema,
@@ -2561,6 +2734,9 @@ const ptzAutotrackCapability = {
2561
2734
  scope: "device",
2562
2735
  mode: "singleton",
2563
2736
  deviceTypes: [DeviceType.Camera],
2737
+ deviceConfig: {
2738
+ ui: { kind: "widget", widgetId: "host/ptz-autotrack", tab: "ptz", topTab: true, label: "Auto-Tracking", order: 5 }
2739
+ },
2564
2740
  methods: {
2565
2741
  /**
2566
2742
  * Read the current on/off state + last-applied settings.
@@ -2627,6 +2803,111 @@ const ptzAutotrackCapability = {
2627
2803
  */
2628
2804
  runtimeState: PtzAutotrackRuntimeStateSchema
2629
2805
  };
2806
+ const StreamProfileSchema = zod.z.enum(["main", "sub", "ext"]);
2807
+ const StreamProfileConfigSchema = zod.z.object({
2808
+ width: zod.z.number(),
2809
+ height: zod.z.number(),
2810
+ codec: zod.z.enum(["h264", "h265"]),
2811
+ framerate: zod.z.number(),
2812
+ bitrate: zod.z.number(),
2813
+ // kbps
2814
+ bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
2815
+ encoderProfile: zod.z.enum(["high", "main", "baseline"]).optional(),
2816
+ gop: zod.z.number().optional(),
2817
+ audio: zod.z.boolean().optional()
2818
+ });
2819
+ const StreamParamsStatusSchema = zod.z.object({
2820
+ /** Per-profile current config. A profile absent = the camera doesn't have it. */
2821
+ main: StreamProfileConfigSchema.optional(),
2822
+ sub: StreamProfileConfigSchema.optional(),
2823
+ ext: StreamProfileConfigSchema.optional(),
2824
+ lastFetchedAt: zod.z.number()
2825
+ });
2826
+ const StreamProfileOptionsSchema = zod.z.object({
2827
+ resolutions: zod.z.array(zod.z.object({ width: zod.z.number(), height: zod.z.number() })),
2828
+ codecs: zod.z.array(zod.z.enum(["h264", "h265"])),
2829
+ framerates: zod.z.array(zod.z.number()),
2830
+ /** Allowed bitrate values (kbps). Empty if the camera takes a free range. */
2831
+ bitrates: zod.z.array(zod.z.number()),
2832
+ /** Optional [min,max] kbps when the camera accepts a continuous range. */
2833
+ bitrateRange: zod.z.tuple([zod.z.number(), zod.z.number()]).optional(),
2834
+ supportsBitrateMode: zod.z.boolean(),
2835
+ supportsEncoderProfile: zod.z.boolean(),
2836
+ supportsGop: zod.z.boolean(),
2837
+ /** Allowed GOP / keyframe-interval range, in seconds — drives the
2838
+ * I-frame-interval selector. Absent when the camera advertises GOP
2839
+ * support but no concrete range (callers then fall back to a free
2840
+ * numeric input). `{ min, max, step }` per the getOptions convention. */
2841
+ gop: zod.z.object({ min: zod.z.number(), max: zod.z.number(), step: zod.z.number() }).optional()
2842
+ });
2843
+ const StreamParamsOptionsSchema = zod.z.object({
2844
+ main: StreamProfileOptionsSchema.optional(),
2845
+ sub: StreamProfileOptionsSchema.optional(),
2846
+ ext: StreamProfileOptionsSchema.optional()
2847
+ });
2848
+ const StreamProfilePatchSchema = zod.z.object({
2849
+ width: zod.z.number().optional(),
2850
+ height: zod.z.number().optional(),
2851
+ codec: zod.z.enum(["h264", "h265"]).optional(),
2852
+ framerate: zod.z.number().optional(),
2853
+ bitrate: zod.z.number().optional(),
2854
+ bitrateMode: zod.z.enum(["vbr", "cbr"]).optional(),
2855
+ encoderProfile: zod.z.enum(["high", "main", "baseline"]).optional(),
2856
+ gop: zod.z.number().optional(),
2857
+ audio: zod.z.boolean().optional()
2858
+ });
2859
+ const streamParamsCapability = {
2860
+ name: "stream-params",
2861
+ scope: "device",
2862
+ mode: "singleton",
2863
+ deviceTypes: [DeviceType.Camera],
2864
+ deviceConfig: {
2865
+ ui: { kind: "derived-form", builderId: "stream-params", tab: "streaming" }
2866
+ },
2867
+ methods: {
2868
+ getOptions: method(
2869
+ zod.z.object({ deviceId: zod.z.number() }),
2870
+ StreamParamsOptionsSchema
2871
+ ),
2872
+ setProfile: method(
2873
+ zod.z.object({
2874
+ deviceId: zod.z.number(),
2875
+ profile: StreamProfileSchema,
2876
+ patch: StreamProfilePatchSchema
2877
+ }),
2878
+ zod.z.void(),
2879
+ { kind: "mutation", auth: "admin" }
2880
+ ),
2881
+ /**
2882
+ * Build the `ConfigUISchema` (admin-ui `ConfigFormBuilder` input
2883
+ * shape) for this camera's stream-encoder settings — one section per
2884
+ * profile (main / sub / ext) with the resolution / codec / framerate
2885
+ * / bitrate / bitrate-mode / encoder-profile / GOP controls the
2886
+ * firmware actually exposes.
2887
+ *
2888
+ * Driven by `getOptions` (camera-probed availability) + `getStatus`
2889
+ * (current per-profile config); each field's `default` is seeded
2890
+ * from the live config so the form renders the camera state in one
2891
+ * pass. Returns `null` when the camera exposes no configurable
2892
+ * stream property — the renderer then shows the unsupported message.
2893
+ *
2894
+ * Output is `z.unknown().nullable()` — the same convention every
2895
+ * other `ConfigUISchema`-returning cap method uses (`device-ops`,
2896
+ * `device-manager`); `ConfigUISchema` is a TS-only type with no
2897
+ * companion Zod schema, and a concrete object would collapse
2898
+ * unrelated AppRouter branches to `unknown` during codegen.
2899
+ */
2900
+ getConfigSchema: method(
2901
+ zod.z.object({ deviceId: zod.z.number() }),
2902
+ zod.z.unknown().nullable()
2903
+ )
2904
+ },
2905
+ status: {
2906
+ schema: StreamParamsStatusSchema,
2907
+ kind: "poll"
2908
+ },
2909
+ runtimeState: StreamParamsStatusSchema
2910
+ };
2630
2911
  const SwitchStatusSchema = zod.z.object({
2631
2912
  on: zod.z.boolean(),
2632
2913
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
@@ -3631,6 +3912,83 @@ const adminUiCapability = {
3631
3912
  getVersion: method(zod.z.void(), VersionOutputSchema)
3632
3913
  }
3633
3914
  };
3915
+ const MethodAccessSchema = zod.z.enum(["view", "create", "delete"]);
3916
+ const AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
3917
+ const AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
3918
+ const CapScopeSchema = zod.z.enum(["device", "system"]);
3919
+ const TokenScopeSchema = zod.z.discriminatedUnion("type", [
3920
+ zod.z.object({
3921
+ type: zod.z.literal("category"),
3922
+ target: CapScopeSchema,
3923
+ access: zod.z.array(MethodAccessSchema).min(1)
3924
+ }),
3925
+ zod.z.object({
3926
+ type: zod.z.literal("capability"),
3927
+ target: zod.z.string(),
3928
+ access: zod.z.array(MethodAccessSchema).min(1)
3929
+ }),
3930
+ zod.z.object({
3931
+ type: zod.z.literal("addon"),
3932
+ target: zod.z.string(),
3933
+ access: zod.z.array(MethodAccessSchema).min(1)
3934
+ }),
3935
+ zod.z.object({
3936
+ type: zod.z.literal("device"),
3937
+ /**
3938
+ * One or more deviceIds (serialised as strings for wire-format
3939
+ * consistency with the rest of the union). Matcher accepts if
3940
+ * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
3941
+ * of one scope-per-device when granting access to a set of cameras.
3942
+ */
3943
+ targets: zod.z.array(zod.z.string()).min(1),
3944
+ access: zod.z.array(MethodAccessSchema).min(1)
3945
+ })
3946
+ ]);
3947
+ const UserRecordSchema = zod.z.object({
3948
+ id: zod.z.string(),
3949
+ username: zod.z.string(),
3950
+ passwordHash: zod.z.string(),
3951
+ /**
3952
+ * Admin bypass. When true, the middleware skips the scope-access
3953
+ * check entirely. There is no other axis of privilege; the legacy
3954
+ * role enum collapsed onto this boolean in v2.
3955
+ */
3956
+ isAdmin: zod.z.boolean().default(false),
3957
+ allowedProviders: AllowedProviderSchema,
3958
+ allowedDevices: AllowedDevicesSchema,
3959
+ /**
3960
+ * Scopes granted to this user. Admins bypass; their `scopes` is
3961
+ * ignored. Non-admins without scopes are locked out of every
3962
+ * protected call.
3963
+ */
3964
+ scopes: zod.z.array(TokenScopeSchema).default([]),
3965
+ createdAt: zod.z.number(),
3966
+ updatedAt: zod.z.number()
3967
+ });
3968
+ const ApiKeyRecordSchema = zod.z.object({
3969
+ id: zod.z.string(),
3970
+ label: zod.z.string(),
3971
+ isAdmin: zod.z.boolean().default(false),
3972
+ allowedProviders: AllowedProviderSchema,
3973
+ allowedDevices: AllowedDevicesSchema,
3974
+ tokenHash: zod.z.string(),
3975
+ tokenPrefix: zod.z.string(),
3976
+ createdAt: zod.z.number(),
3977
+ lastUsedAt: zod.z.number().optional()
3978
+ });
3979
+ const ScopedTokenSchema = zod.z.object({
3980
+ id: zod.z.string(),
3981
+ userId: zod.z.string(),
3982
+ name: zod.z.string(),
3983
+ tokenHash: zod.z.string(),
3984
+ tokenPrefix: zod.z.string(),
3985
+ scopes: zod.z.array(TokenScopeSchema),
3986
+ // SQLite/JSON storage round-trips undefined → null. Use `nullish` so the
3987
+ // schema accepts both `null` (read from disk) and `undefined` (in-memory).
3988
+ expiresAt: zod.z.number().nullish(),
3989
+ lastUsedAt: zod.z.number().nullish(),
3990
+ createdAt: zod.z.number()
3991
+ });
3634
3992
  const SsoBridgeClaimsSchema = zod.z.object({
3635
3993
  userId: zod.z.string(),
3636
3994
  username: zod.z.string(),
@@ -3646,7 +4004,18 @@ const SsoBridgeClaimsSchema = zod.z.object({
3646
4004
  * JWT WITHOUT verifying the signature — the hub re-verifies on every
3647
4005
  * inbound call so trust still rests with the signing hub.
3648
4006
  */
3649
- hubUrl: zod.z.string().optional()
4007
+ hubUrl: zod.z.string().optional(),
4008
+ /** Permission scopes baked into the token. Set by the OAuth
4009
+ * account-linking grant; absent on ordinary SSO-login tokens. */
4010
+ scopes: zod.z.array(TokenScopeSchema).optional(),
4011
+ /** OAuth authorization-code binding — set only on `oauth-code` tokens. */
4012
+ redirectUri: zod.z.string().optional(),
4013
+ integrationId: zod.z.string().optional(),
4014
+ /** JWT ID — unique per issued code; consumed-set enforces single-use. */
4015
+ jti: zod.z.string().optional(),
4016
+ /** OAuth session registry id — set on `oauth-access`/`oauth-refresh`
4017
+ * tokens so the verify path can check the session is not revoked. */
4018
+ sessionId: zod.z.string().optional()
3650
4019
  });
3651
4020
  const ssoBridgeCapability = {
3652
4021
  name: "sso-bridge",
@@ -3667,6 +4036,27 @@ const ssoBridgeCapability = {
3667
4036
  )
3668
4037
  }
3669
4038
  };
4039
+ const OauthIntegrationDescriptorSchema = zod.z.object({
4040
+ /** Stable id used as the `integration=` query param, e.g. 'export-alexa'. */
4041
+ integrationId: zod.z.string(),
4042
+ /** Human label rendered on the consent page. */
4043
+ displayName: zod.z.string(),
4044
+ /** Scopes baked into every token issued for this integration. */
4045
+ requestedScopes: zod.z.array(TokenScopeSchema),
4046
+ /** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
4047
+ * redirect_uri that does not start with one of these. Required —
4048
+ * an empty list means the integration can never complete linking. */
4049
+ allowedRedirectPrefixes: zod.z.array(zod.z.string()).min(1)
4050
+ });
4051
+ const oauthIntegrationCapability = {
4052
+ name: "oauth-integration",
4053
+ scope: "system",
4054
+ mode: "collection",
4055
+ internal: true,
4056
+ methods: {
4057
+ getDescriptor: method(zod.z.void(), OauthIntegrationDescriptorSchema)
4058
+ }
4059
+ };
3670
4060
  const PasskeySummarySchema = zod.z.object({
3671
4061
  credentialId: zod.z.string(),
3672
4062
  label: zod.z.string(),
@@ -3982,21 +4372,30 @@ const addonPagesSourceCapability = {
3982
4372
  };
3983
4373
  const WidgetHostEnum = zod.z.enum(["device-tab", "dashboard", "integration-detail"]);
3984
4374
  const WidgetSizeEnum = zod.z.enum(["xs", "sm", "md", "lg", "xl"]);
4375
+ const WidgetRemoteSchema = zod.z.object({
4376
+ remoteName: zod.z.string(),
4377
+ exposedModule: zod.z.string(),
4378
+ componentKey: zod.z.string().optional()
4379
+ });
3985
4380
  const WidgetMetadataSchema = zod.z.object({
3986
- /** Stable id within the addon — kebab-case. */
3987
- stableId: zod.z.string(),
4381
+ // ── UiContribution core (kind:'remote') ──────────────────────────
4382
+ /** Primary host tab — `'dashboard'`, `'device-tab'`, or a device-detail tab id. */
4383
+ tab: zod.z.string(),
4384
+ /** Optional sub-tab within `tab`. */
4385
+ subTab: zod.z.string().optional(),
3988
4386
  /** Operator-facing label. */
3989
4387
  label: zod.z.string(),
4388
+ /** Ordering within `(tab, subTab)`, ascending. */
4389
+ order: zod.z.number().optional(),
4390
+ /** Always `'remote'` — a widget is a Module Federation remote. */
4391
+ kind: zod.z.literal("remote"),
4392
+ /** MF remote descriptor. */
4393
+ remote: WidgetRemoteSchema,
4394
+ // ── Widget-only metadata ─────────────────────────────────────────
4395
+ /** Stable id within the addon — kebab-case. Equals `remote.componentKey`. */
4396
+ stableId: zod.z.string(),
3990
4397
  description: zod.z.string().optional(),
3991
4398
  icon: zod.z.string().optional(),
3992
- /**
3993
- * Module Federation remote name — must match the `name` field on the
3994
- * widget addon's `federation()` plugin config. Used by the host's
3995
- * `<WidgetRegistryProvider>` to call `loadRemote('<remoteName>/widgets')`.
3996
- * Conventionally `addon_<addonid>_widgets` (snake_case; MF names
3997
- * cannot contain hyphens).
3998
- */
3999
- remoteName: zod.z.string(),
4000
4399
  /**
4001
4400
  * Bundle filename inside the addon's `dist/` dir served at
4002
4401
  * `/api/addon-widgets/<addonId>/<bundle>`. With Module Federation
@@ -4005,9 +4404,9 @@ const WidgetMetadataSchema = zod.z.object({
4005
4404
  * cache-buster URL without a separate filesystem stat.
4006
4405
  */
4007
4406
  bundle: zod.z.string(),
4008
- /** Where the widget makes sense to render. */
4407
+ /** Every host the widget supports. The picker filters on this set. */
4009
4408
  hosts: zod.z.array(WidgetHostEnum).readonly(),
4010
- /** Required props the host must supply. Validated at <WidgetSlot> mount. */
4409
+ /** Required props the host must supply. Validated at `<WidgetSlot>` mount. */
4011
4410
  requires: zod.z.object({
4012
4411
  deviceContext: zod.z.boolean().default(false),
4013
4412
  integrationContext: zod.z.boolean().default(false)
@@ -4107,6 +4506,16 @@ const DEFAULT_DECODER_HWACCEL_CONFIG = {
4107
4506
  hwaccel: "auto",
4108
4507
  probedBestHwaccel: ""
4109
4508
  };
4509
+ const ShmRingStatsSchema = zod.z.object({
4510
+ sessionId: zod.z.string(),
4511
+ slotCount: zod.z.number().int(),
4512
+ slotByteLength: zod.z.number().int(),
4513
+ segmentBytes: zod.z.number().int(),
4514
+ budgetMb: zod.z.number().int(),
4515
+ framesWritten: zod.z.number().int(),
4516
+ getFrameHits: zod.z.number().int(),
4517
+ getFrameMisses: zod.z.number().int()
4518
+ });
4110
4519
  const decoderCapability = {
4111
4520
  name: "decoder",
4112
4521
  scope: "system",
@@ -4143,10 +4552,27 @@ const decoderCapability = {
4143
4552
  url: zod.z.string()
4144
4553
  }), zod.z.void()),
4145
4554
  // ── Output — polling-based frame retrieval ────────────────────
4555
+ // `pullFrames` drains the pixel `DecodedFrame[]` of a `frameSink:
4556
+ // 'callback'` session. `pullHandles` (Phase 5 / D9) drains the
4557
+ // zero-pixel `FrameHandle[]` of a `frameSink: 'shm'` session — the
4558
+ // broker hands each handle to a `FrameRingReader` that opens the
4559
+ // named segment and reads the pixels back zero-copy. A session is
4560
+ // one mode or the other; the unmatched method returns an empty
4561
+ // array.
4146
4562
  pullFrames: method(zod.z.object({
4147
4563
  sessionId: zod.z.string(),
4148
4564
  maxCount: zod.z.number().default(1)
4149
4565
  }), zod.z.array(DecodedFrameSchema)),
4566
+ pullHandles: method(zod.z.object({
4567
+ sessionId: zod.z.string(),
4568
+ maxCount: zod.z.number().default(1)
4569
+ }), zod.z.array(FrameHandleSchema)),
4570
+ // ── Frame fetch (Phase 5 / D9 downstream access) ──────────────
4571
+ // Read the pixels a FrameHandle refers to from this node's shm ring.
4572
+ // Returns null when the slot was already recycled (latest-wins).
4573
+ getFrame: method(zod.z.object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()),
4574
+ // shm ring usage stats for a session.
4575
+ getShmStats: method(zod.z.object({ sessionId: zod.z.string() }), ShmRingStatsSchema.nullable()),
4150
4576
  // ── Control ───────────────────────────────────────────────────
4151
4577
  updateConfig: method(zod.z.object({
4152
4578
  sessionId: zod.z.string(),
@@ -4299,6 +4725,8 @@ const webrtcSessionCapability = {
4299
4725
  name: "webrtc-session",
4300
4726
  scope: "device",
4301
4727
  mode: "singleton",
4728
+ kind: "wrapper",
4729
+ defaultActive: true,
4302
4730
  deviceTypes: [DeviceType.Camera],
4303
4731
  methods: {
4304
4732
  /**
@@ -4817,6 +5245,8 @@ const audioAnalysisCapability = {
4817
5245
  name: "audio-analysis",
4818
5246
  scope: "device",
4819
5247
  mode: "singleton",
5248
+ kind: "wrapper",
5249
+ defaultActive: true,
4820
5250
  deviceTypes: [DeviceType.Camera],
4821
5251
  exposesDeviceSettings: true,
4822
5252
  methods: {
@@ -5356,8 +5786,8 @@ const deviceManagerCapability = {
5356
5786
  /**
5357
5787
  * Return the addon ids that declared a wrapper provider for `capName`.
5358
5788
  * Backs the device-bindings UI's wrapper-picker dropdown. Entries are
5359
- * sourced from `CapabilityRegistry.wrapperProviders`, populated at
5360
- * `ProviderRegistration.kind === 'wrapper'` time.
5789
+ * sourced from `CapabilityRegistry.wrapperProviders`, populated when
5790
+ * the cap definition declares `kind: 'wrapper'`.
5361
5791
  */
5362
5792
  listWrappersForCap: method(
5363
5793
  zod.z.object({ capName: zod.z.string() }),
@@ -5670,54 +6100,6 @@ const authProviderCapability = {
5670
6100
  validateToken: method(zod.z.object({ token: zod.z.string() }), AuthResultSchema.nullable())
5671
6101
  }
5672
6102
  };
5673
- const AuthProviderInfoSchema = zod.z.object({
5674
- /** Stable id matching the addon id (used for `getLoginUrl({addonId,…})`). */
5675
- addonId: zod.z.string(),
5676
- /**
5677
- * Per-instance id when one addon registers multiple "logical"
5678
- * providers (e.g. OIDC with Google + Microsoft + custom). The login
5679
- * URL becomes `/addon/${addonId}/${instanceId}/start` — handler reads
5680
- * `:instanceId` from the route. Empty/unset means the addon is a
5681
- * single-instance provider; the URL is `/addon/${addonId}/start`.
5682
- */
5683
- instanceId: zod.z.string().optional(),
5684
- /** Display label shown on the login button + admin row. */
5685
- displayName: zod.z.string(),
5686
- /** Optional iconography hint (lucide-react icon name OR emoji). */
5687
- icon: zod.z.string().optional(),
5688
- /** When true, the provider exposes a redirect-based login flow
5689
- * (`getLoginUrl` returns a URL the browser navigates to). */
5690
- hasRedirectFlow: zod.z.boolean(),
5691
- /** When true, the provider exposes a credential-form login flow
5692
- * (`validateCredentials` accepts username + password). */
5693
- hasCredentialFlow: zod.z.boolean(),
5694
- /** Provider kind, drives admin-UI hint dispatch (oidc / saml / totp / …). */
5695
- kind: zod.z.string().optional(),
5696
- /** Operator-facing status string (e.g. "Connected to https://login.acme.com"). */
5697
- status: zod.z.string().optional(),
5698
- /** When false, the provider is registered but disabled by config; the
5699
- * UI surfaces it as inactive without enumerating it for login. */
5700
- enabled: zod.z.boolean()
5701
- });
5702
- const authenticationCapability = {
5703
- name: "authentication",
5704
- scope: "system",
5705
- mode: "singleton",
5706
- methods: {
5707
- /** All registered auth providers, both enabled and disabled. */
5708
- listProviders: method(zod.z.void(), zod.z.array(AuthProviderInfoSchema).readonly()),
5709
- /**
5710
- * Toggle a provider's enabled flag. Disabled providers stay
5711
- * registered but aren't surfaced on the login page. The orchestrator
5712
- * persists the state in `addon-settings` so it survives restarts.
5713
- */
5714
- setProviderEnabled: method(
5715
- zod.z.object({ addonId: zod.z.string(), enabled: zod.z.boolean() }),
5716
- zod.z.object({ success: zod.z.literal(true) }),
5717
- { kind: "mutation", auth: "admin" }
5718
- )
5719
- }
5720
- };
5721
6103
  const NetworkEndpointSchema = zod.z.object({
5722
6104
  url: zod.z.string(),
5723
6105
  hostname: zod.z.string(),
@@ -5746,7 +6128,6 @@ const networkAccessCapability = {
5746
6128
  name: "network-access",
5747
6129
  scope: "system",
5748
6130
  mode: "collection",
5749
- internal: true,
5750
6131
  providerKind: "ingress",
5751
6132
  methods: {
5752
6133
  start: method(zod.z.void(), NetworkEndpointSchema, { kind: "mutation" }),
@@ -5754,58 +6135,13 @@ const networkAccessCapability = {
5754
6135
  getEndpoint: method(zod.z.void(), NetworkEndpointSchema.nullable()),
5755
6136
  getStatus: method(zod.z.void(), NetworkAccessStatusSchema),
5756
6137
  /**
5757
- * Enumerate every active ingress entry. Default implementation (when
5758
- * the provider omits this method) is derived from `getEndpoint()` —
5759
- * see the remote-access orchestrator for the fallback path.
6138
+ * Enumerate every active ingress entry. Providers that expose only a
6139
+ * single endpoint may omit this method; callers fall back to
6140
+ * `getEndpoint()` in that case.
5760
6141
  */
5761
6142
  listEndpoints: method(zod.z.void(), zod.z.array(NetworkEndpointEntrySchema).readonly())
5762
6143
  }
5763
6144
  };
5764
- const RemoteAccessEndpointSchema = zod.z.object({
5765
- url: zod.z.string(),
5766
- hostname: zod.z.string(),
5767
- port: zod.z.number(),
5768
- protocol: zod.z.enum(["http", "https"])
5769
- });
5770
- const RemoteAccessProviderInfoSchema = zod.z.object({
5771
- /** Stable id matching the addon id. */
5772
- addonId: zod.z.string(),
5773
- /** Display label shown on the admin row — sourced from the addon manifest. */
5774
- displayName: zod.z.string(),
5775
- /** When false, the provider is registered but disabled. */
5776
- enabled: zod.z.boolean(),
5777
- /** True when the underlying tunnel/connection is up. */
5778
- connected: zod.z.boolean(),
5779
- /** Public-facing endpoint, when connected. Null otherwise. */
5780
- endpoint: RemoteAccessEndpointSchema.nullable(),
5781
- /** Last error message (when connected=false), if available. */
5782
- error: zod.z.string().optional()
5783
- });
5784
- const remoteAccessCapability = {
5785
- name: "remote-access",
5786
- scope: "system",
5787
- mode: "singleton",
5788
- methods: {
5789
- /** All registered remote-access providers + their live status. */
5790
- listProviders: method(zod.z.void(), zod.z.array(RemoteAccessProviderInfoSchema).readonly()),
5791
- /**
5792
- * Start a specific provider's tunnel. Per-provider config still
5793
- * lives on the addon's settings panel; this is just the on/off
5794
- * trigger so the admin UI can manage the lifecycle from one place.
5795
- */
5796
- startProvider: method(
5797
- zod.z.object({ addonId: zod.z.string() }),
5798
- RemoteAccessEndpointSchema,
5799
- { kind: "mutation", auth: "admin" }
5800
- ),
5801
- /** Stop a specific provider's tunnel (idempotent on already-stopped). */
5802
- stopProvider: method(
5803
- zod.z.object({ addonId: zod.z.string() }),
5804
- zod.z.object({ success: zod.z.literal(true) }),
5805
- { kind: "mutation", auth: "admin" }
5806
- )
5807
- }
5808
- };
5809
6145
  const TurnServerSchema = zod.z.object({
5810
6146
  /** Single URL or list of URLs (e.g. "turn:turn.example.com:3478?transport=udp"). */
5811
6147
  urls: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]),
@@ -5828,48 +6164,6 @@ const turnProviderCapability = {
5828
6164
  )
5829
6165
  }
5830
6166
  };
5831
- const TurnProviderInfoSchema = zod.z.object({
5832
- /** Stable id matching the addon id. */
5833
- addonId: zod.z.string(),
5834
- /** Display label shown on the admin row — sourced from the addon manifest. */
5835
- displayName: zod.z.string(),
5836
- /** When false, the provider is registered but disabled. */
5837
- enabled: zod.z.boolean(),
5838
- /** Number of servers this provider is currently exposing. */
5839
- serverCount: zod.z.number(),
5840
- /**
5841
- * Flat list of every TURN/STUN URL this provider currently exposes.
5842
- * One row per URL (multi-URL ICE server entries are flattened). The
5843
- * admin UI shows this in a compact per-provider list so operators
5844
- * can verify what's actually being negotiated without having to dig
5845
- * into the combined `getAllServers` output.
5846
- */
5847
- urls: zod.z.array(zod.z.string()).readonly(),
5848
- /** Last fetch error (when serverCount=0 due to API failure), if any. */
5849
- error: zod.z.string().optional()
5850
- });
5851
- const turnOrchestratorCapability = {
5852
- name: "turn-orchestrator",
5853
- scope: "system",
5854
- mode: "singleton",
5855
- methods: {
5856
- /** All registered TURN providers + per-provider stats. */
5857
- listProviders: method(zod.z.void(), zod.z.array(TurnProviderInfoSchema).readonly()),
5858
- /**
5859
- * Combined list of TURN/STUN servers from all ENABLED providers.
5860
- * Consumed by the WebRTC layer at session-creation time —
5861
- * implementations may fetch fresh short-lived credentials each
5862
- * call (e.g. Cloudflare API), so consumers SHOULD call per-session.
5863
- */
5864
- getAllServers: method(zod.z.void(), zod.z.array(TurnServerSchema).readonly()),
5865
- /** Toggle a provider's enabled flag. */
5866
- setProviderEnabled: method(
5867
- zod.z.object({ addonId: zod.z.string(), enabled: zod.z.boolean() }),
5868
- zod.z.object({ success: zod.z.literal(true) }),
5869
- { kind: "mutation", auth: "admin" }
5870
- )
5871
- }
5872
- };
5873
6167
  const SnapshotImageSchema = zod.z.object({
5874
6168
  base64: zod.z.string(),
5875
6169
  contentType: zod.z.string()
@@ -5888,6 +6182,8 @@ const snapshotCapability = {
5888
6182
  name: "snapshot",
5889
6183
  scope: "device",
5890
6184
  mode: "singleton",
6185
+ kind: "wrapper",
6186
+ defaultActive: true,
5891
6187
  deviceTypes: [DeviceType.Camera],
5892
6188
  // Owns per-device snapshot settings (preferred stream, debug logging).
5893
6189
  // The three DeviceSettingsContribution methods are auto-added to the
@@ -6237,6 +6533,8 @@ const detectionPipelineCapability = {
6237
6533
  name: "detection-pipeline",
6238
6534
  scope: "device",
6239
6535
  mode: "singleton",
6536
+ kind: "wrapper",
6537
+ defaultActive: true,
6240
6538
  deviceTypes: [DeviceType.Camera],
6241
6539
  exposesDeviceSettings: true,
6242
6540
  methods: {}
@@ -6345,6 +6643,8 @@ const pipelineAnalyticsCapability = {
6345
6643
  name: "pipeline-analytics",
6346
6644
  scope: "device",
6347
6645
  mode: "singleton",
6646
+ kind: "wrapper",
6647
+ defaultActive: true,
6348
6648
  deviceTypes: [DeviceType.Camera],
6349
6649
  exposesDeviceSettings: true,
6350
6650
  methods: {
@@ -6634,11 +6934,26 @@ const PtzMoveCommandSchema = zod.z.object({
6634
6934
  zoom: zod.z.number().optional(),
6635
6935
  speed: zod.z.number().optional()
6636
6936
  });
6937
+ const PtzStatusSchema = PtzPositionSchema.extend({ autofocus: zod.z.boolean() });
6938
+ const PtzOptionsSchema = zod.z.object({
6939
+ hasPan: zod.z.boolean(),
6940
+ hasTilt: zod.z.boolean(),
6941
+ hasZoom: zod.z.boolean(),
6942
+ supportsPresets: zod.z.boolean(),
6943
+ /** Max number of named presets the camera supports, when known. */
6944
+ maxPresets: zod.z.number().optional(),
6945
+ /** Whether the camera exposes a controllable autofocus toggle
6946
+ * (boolean `hasX` per the getOptions availability convention). */
6947
+ hasAutofocus: zod.z.boolean()
6948
+ });
6637
6949
  const ptzCapability = {
6638
6950
  name: "ptz",
6639
6951
  scope: "device",
6640
6952
  mode: "singleton",
6641
6953
  deviceTypes: [DeviceType.Camera],
6954
+ deviceConfig: {
6955
+ ui: { kind: "widget", widgetId: "host/ptz-panel", tab: "ptz", topTab: true, label: "PTZ", order: 0 }
6956
+ },
6642
6957
  methods: {
6643
6958
  move: method(
6644
6959
  PtzMoveCommandSchema.extend({ deviceId: zod.z.number() }),
@@ -6664,6 +6979,20 @@ const ptzCapability = {
6664
6979
  zod.z.void(),
6665
6980
  { kind: "mutation" }
6666
6981
  ),
6982
+ savePreset: method(
6983
+ zod.z.object({ deviceId: zod.z.number(), presetId: zod.z.string(), name: zod.z.string() }),
6984
+ zod.z.void(),
6985
+ { kind: "mutation", auth: "admin" }
6986
+ ),
6987
+ deletePreset: method(
6988
+ zod.z.object({ deviceId: zod.z.number(), presetId: zod.z.string() }),
6989
+ zod.z.void(),
6990
+ { kind: "mutation", auth: "admin" }
6991
+ ),
6992
+ getOptions: method(
6993
+ zod.z.object({ deviceId: zod.z.number() }),
6994
+ PtzOptionsSchema
6995
+ ),
6667
6996
  goHome: method(
6668
6997
  zod.z.object({ deviceId: zod.z.number() }),
6669
6998
  zod.z.void(),
@@ -6678,10 +7007,17 @@ const ptzCapability = {
6678
7007
  getPosition: method(
6679
7008
  zod.z.object({ deviceId: zod.z.number() }),
6680
7009
  PtzPositionSchema
7010
+ ),
7011
+ /** Toggle the camera's autofocus. Only meaningful when
7012
+ * `getOptions().hasAutofocus` is true. */
7013
+ setAutofocus: method(
7014
+ zod.z.object({ deviceId: zod.z.number(), enabled: zod.z.boolean() }),
7015
+ zod.z.void(),
7016
+ { kind: "mutation" }
6681
7017
  )
6682
7018
  },
6683
7019
  status: {
6684
- schema: PtzPositionSchema,
7020
+ schema: PtzStatusSchema,
6685
7021
  kind: "command-driven"
6686
7022
  }
6687
7023
  };
@@ -7465,7 +7801,7 @@ const localNetworkCapability = {
7465
7801
  )
7466
7802
  }
7467
7803
  };
7468
- const MeshEndpointSchema$1 = zod.z.object({
7804
+ const MeshEndpointSchema = zod.z.object({
7469
7805
  /** Stable identifier within the provider (e.g. `mesh-ipv4`, `magicdns`, `funnel`). */
7470
7806
  id: zod.z.string(),
7471
7807
  /** Operator-facing label (e.g. "Mesh IPv4", "MagicDNS"). */
@@ -7538,7 +7874,7 @@ const MeshStatusSchema = zod.z.object({
7538
7874
  /** Number of peers visible to this host (excluding self). */
7539
7875
  peerCount: zod.z.number(),
7540
7876
  /** Every endpoint this provider exposes for the current host. */
7541
- endpoints: zod.z.array(MeshEndpointSchema$1).readonly(),
7877
+ endpoints: zod.z.array(MeshEndpointSchema).readonly(),
7542
7878
  /** Last error from the daemon, when not joined. */
7543
7879
  error: zod.z.string().optional(),
7544
7880
  // ── Account / tenant identity (generic across providers) ────────
@@ -7705,185 +8041,6 @@ const meshNetworkCapability = {
7705
8041
  // tabs driven by this cap.
7706
8042
  }
7707
8043
  };
7708
- const MeshEndpointSchema = zod.z.object({
7709
- id: zod.z.string(),
7710
- label: zod.z.string(),
7711
- scope: zod.z.enum(["mesh", "public"]),
7712
- url: zod.z.string(),
7713
- hostname: zod.z.string(),
7714
- port: zod.z.number(),
7715
- protocol: zod.z.enum(["http", "https"])
7716
- });
7717
- const MeshProviderInfoSchema = zod.z.object({
7718
- /** Stable id matching the addon id. */
7719
- addonId: zod.z.string(),
7720
- /** Display label shown on the admin row — sourced from the addon manifest. */
7721
- displayName: zod.z.string(),
7722
- /** True when the host is joined to this provider's mesh. */
7723
- joined: zod.z.boolean(),
7724
- /** Local mesh IP (empty when not joined). */
7725
- meshIp: zod.z.string(),
7726
- /** MagicDNS / mesh hostname (empty when not configured). */
7727
- magicDnsHostname: zod.z.string(),
7728
- /** Peer count (excluding self). */
7729
- peerCount: zod.z.number(),
7730
- /** Active endpoints (mesh IP + MagicDNS + optional public Funnel). */
7731
- endpoints: zod.z.array(MeshEndpointSchema).readonly(),
7732
- /** Last error reported by the provider. */
7733
- error: zod.z.string().optional(),
7734
- // ── Generic identity fields mirrored from MeshStatus ─────────────
7735
- /** Tenant / tailnet / network display name. Empty pre-join. */
7736
- tenantName: zod.z.string(),
7737
- /** Mesh DNS suffix (e.g. tailXXXX.ts.net). Empty when not configured. */
7738
- magicDnsSuffix: zod.z.string(),
7739
- /** Authenticated user / account login. Null for token-only providers. */
7740
- userLogin: zod.z.string().nullable(),
7741
- /** Provider control-plane URL. */
7742
- controlPlaneUrl: zod.z.string(),
7743
- /** Machine-key expiry (epoch ms). Null when keys don't rotate. */
7744
- keyExpiry: zod.z.number().nullable()
7745
- });
7746
- const meshOrchestratorCapability = {
7747
- name: "mesh-orchestrator",
7748
- scope: "system",
7749
- mode: "singleton",
7750
- methods: {
7751
- /** All registered mesh-network providers + live status. */
7752
- listProviders: method(zod.z.void(), zod.z.array(MeshProviderInfoSchema).readonly()),
7753
- /**
7754
- * Join the mesh of a specific provider. Per-provider config still
7755
- * lives on its settings panel; the orchestrator forwards.
7756
- */
7757
- joinProvider: method(
7758
- zod.z.object({
7759
- addonId: zod.z.string(),
7760
- authKey: zod.z.string().min(8),
7761
- hostname: zod.z.string().optional()
7762
- }),
7763
- zod.z.object({ joined: zod.z.literal(true) }),
7764
- { kind: "mutation" }
7765
- ),
7766
- leaveProvider: method(
7767
- zod.z.object({ addonId: zod.z.string() }),
7768
- zod.z.object({ success: zod.z.literal(true) }),
7769
- { kind: "mutation" }
7770
- ),
7771
- /**
7772
- * Browser-redirect login flow. Forwards to the named provider's
7773
- * `mesh-network.startLogin` and returns the URL the daemon
7774
- * prints. UI opens it in a new tab, then polls `listProviders`
7775
- * for `joined: true`.
7776
- */
7777
- startLoginProvider: method(
7778
- zod.z.object({
7779
- addonId: zod.z.string(),
7780
- hostname: zod.z.string().optional()
7781
- }),
7782
- zod.z.object({ loginUrl: zod.z.string() }),
7783
- { kind: "mutation" }
7784
- ),
7785
- /**
7786
- * Sign out of the provider's account entirely (`mesh-network.logout`).
7787
- * Distinct from `leaveProvider` which only takes the host off-mesh;
7788
- * `logoutProvider` wipes credentials so the next start requires a
7789
- * fresh login.
7790
- */
7791
- logoutProvider: method(
7792
- zod.z.object({ addonId: zod.z.string() }),
7793
- zod.z.object({ loggedOut: zod.z.literal(true) }),
7794
- { kind: "mutation" }
7795
- ),
7796
- /**
7797
- * Per-provider peer list. Forwards to `mesh-network.listPeers` on
7798
- * the addressed provider. Separate from `listProviders` because
7799
- * peer payloads can be large on a heavily-populated tailnet —
7800
- * fetch only when the operator opens the Peers tab.
7801
- */
7802
- listProviderPeers: method(
7803
- zod.z.object({ addonId: zod.z.string() }),
7804
- zod.z.object({
7805
- peers: zod.z.array(MeshPeerSchema).readonly()
7806
- })
7807
- )
7808
- }
7809
- };
7810
- const MethodAccessSchema = zod.z.enum(["view", "create", "delete"]);
7811
- const AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
7812
- const AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
7813
- const CapScopeSchema = zod.z.enum(["device", "system"]);
7814
- const TokenScopeSchema = zod.z.discriminatedUnion("type", [
7815
- zod.z.object({
7816
- type: zod.z.literal("category"),
7817
- target: CapScopeSchema,
7818
- access: zod.z.array(MethodAccessSchema).min(1)
7819
- }),
7820
- zod.z.object({
7821
- type: zod.z.literal("capability"),
7822
- target: zod.z.string(),
7823
- access: zod.z.array(MethodAccessSchema).min(1)
7824
- }),
7825
- zod.z.object({
7826
- type: zod.z.literal("addon"),
7827
- target: zod.z.string(),
7828
- access: zod.z.array(MethodAccessSchema).min(1)
7829
- }),
7830
- zod.z.object({
7831
- type: zod.z.literal("device"),
7832
- /**
7833
- * One or more deviceIds (serialised as strings for wire-format
7834
- * consistency with the rest of the union). Matcher accepts if
7835
- * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
7836
- * of one scope-per-device when granting access to a set of cameras.
7837
- */
7838
- targets: zod.z.array(zod.z.string()).min(1),
7839
- access: zod.z.array(MethodAccessSchema).min(1)
7840
- })
7841
- ]);
7842
- const UserRecordSchema = zod.z.object({
7843
- id: zod.z.string(),
7844
- username: zod.z.string(),
7845
- passwordHash: zod.z.string(),
7846
- /**
7847
- * Admin bypass. When true, the middleware skips the scope-access
7848
- * check entirely. There is no other axis of privilege; the legacy
7849
- * role enum collapsed onto this boolean in v2.
7850
- */
7851
- isAdmin: zod.z.boolean().default(false),
7852
- allowedProviders: AllowedProviderSchema,
7853
- allowedDevices: AllowedDevicesSchema,
7854
- /**
7855
- * Scopes granted to this user. Admins bypass; their `scopes` is
7856
- * ignored. Non-admins without scopes are locked out of every
7857
- * protected call.
7858
- */
7859
- scopes: zod.z.array(TokenScopeSchema).default([]),
7860
- createdAt: zod.z.number(),
7861
- updatedAt: zod.z.number()
7862
- });
7863
- const ApiKeyRecordSchema = zod.z.object({
7864
- id: zod.z.string(),
7865
- label: zod.z.string(),
7866
- isAdmin: zod.z.boolean().default(false),
7867
- allowedProviders: AllowedProviderSchema,
7868
- allowedDevices: AllowedDevicesSchema,
7869
- tokenHash: zod.z.string(),
7870
- tokenPrefix: zod.z.string(),
7871
- createdAt: zod.z.number(),
7872
- lastUsedAt: zod.z.number().optional()
7873
- });
7874
- const ScopedTokenSchema = zod.z.object({
7875
- id: zod.z.string(),
7876
- userId: zod.z.string(),
7877
- name: zod.z.string(),
7878
- tokenHash: zod.z.string(),
7879
- tokenPrefix: zod.z.string(),
7880
- scopes: zod.z.array(TokenScopeSchema),
7881
- // SQLite/JSON storage round-trips undefined → null. Use `nullish` so the
7882
- // schema accepts both `null` (read from disk) and `undefined` (in-memory).
7883
- expiresAt: zod.z.number().nullish(),
7884
- lastUsedAt: zod.z.number().nullish(),
7885
- createdAt: zod.z.number()
7886
- });
7887
8044
  const UserSummarySchema = zod.z.object({
7888
8045
  id: zod.z.string(),
7889
8046
  username: zod.z.string(),
@@ -7956,6 +8113,16 @@ const CreateScopedTokenResultSchema = zod.z.object({
7956
8113
  token: zod.z.string(),
7957
8114
  record: ScopedTokenSummarySchema
7958
8115
  });
8116
+ const OauthSessionSummarySchema = zod.z.object({
8117
+ id: zod.z.string(),
8118
+ userId: zod.z.string(),
8119
+ username: zod.z.string(),
8120
+ integrationId: zod.z.string(),
8121
+ scopes: zod.z.array(TokenScopeSchema),
8122
+ createdAt: zod.z.number(),
8123
+ lastUsedAt: zod.z.number(),
8124
+ revokedAt: zod.z.number().nullable()
8125
+ });
7959
8126
  const TotpSetupResultSchema = zod.z.object({
7960
8127
  secret: zod.z.string(),
7961
8128
  otpauthUrl: zod.z.string()
@@ -8034,6 +8201,66 @@ const userManagementCapability = {
8034
8201
  zod.z.object({ userId: zod.z.string(), code: zod.z.string() }),
8035
8202
  zod.z.object({ valid: zod.z.boolean() }),
8036
8203
  { kind: "mutation", access: "view" }
8204
+ ),
8205
+ // ── OAuth account-linking grant ────────────────────────────────
8206
+ //
8207
+ // Core's /oauth2/* endpoints delegate here. Tokens are sso-bridge
8208
+ // JWTs (kinds oauth-code / oauth-access / oauth-refresh) and ALWAYS
8209
+ // carry isAdmin:false — the operator login proves hub control; the
8210
+ // issued token is minimal (device scope only).
8211
+ oauthIssueCode: method(
8212
+ zod.z.object({
8213
+ integrationId: zod.z.string(),
8214
+ userId: zod.z.string(),
8215
+ username: zod.z.string(),
8216
+ scopes: zod.z.array(TokenScopeSchema),
8217
+ redirectUri: zod.z.string(),
8218
+ hubUrl: zod.z.string()
8219
+ }),
8220
+ zod.z.object({ code: zod.z.string() }),
8221
+ { kind: "mutation", access: "create" }
8222
+ ),
8223
+ oauthExchangeCode: method(
8224
+ zod.z.object({ code: zod.z.string(), redirectUri: zod.z.string() }),
8225
+ zod.z.object({
8226
+ accessToken: zod.z.string(),
8227
+ refreshToken: zod.z.string(),
8228
+ expiresIn: zod.z.number()
8229
+ }).nullable(),
8230
+ { kind: "mutation", access: "view" }
8231
+ ),
8232
+ oauthRefresh: method(
8233
+ zod.z.object({ refreshToken: zod.z.string() }),
8234
+ zod.z.object({
8235
+ accessToken: zod.z.string(),
8236
+ refreshToken: zod.z.string(),
8237
+ expiresIn: zod.z.number()
8238
+ }).nullable(),
8239
+ { kind: "mutation", access: "view" }
8240
+ ),
8241
+ oauthVerifyAccessToken: method(
8242
+ zod.z.object({ token: zod.z.string() }),
8243
+ zod.z.object({
8244
+ userId: zod.z.string(),
8245
+ username: zod.z.string(),
8246
+ scopes: zod.z.array(TokenScopeSchema)
8247
+ }).nullable(),
8248
+ { access: "view" }
8249
+ ),
8250
+ // ── OAuth linked-session management (Phase D) ──────────────────
8251
+ //
8252
+ // The admin UI lists active account-linking sessions and revokes
8253
+ // them; revocation makes the linked integration's tokens fail
8254
+ // verification immediately.
8255
+ listOauthSessions: method(
8256
+ zod.z.void(),
8257
+ zod.z.array(OauthSessionSummarySchema),
8258
+ { auth: "admin" }
8259
+ ),
8260
+ revokeOauthSession: method(
8261
+ zod.z.object({ id: zod.z.string() }),
8262
+ zod.z.object({ success: zod.z.boolean() }),
8263
+ { kind: "mutation", auth: "admin", access: "delete" }
8037
8264
  )
8038
8265
  }
8039
8266
  };
@@ -8263,6 +8490,19 @@ const nodesCapability = {
8263
8490
  zod.z.record(zod.z.string(), ClusterAddonStatusEntrySchema),
8264
8491
  { auth: "admin" }
8265
8492
  ),
8493
+ getCapUsageGraph: method(
8494
+ zod.z.object({
8495
+ windowSeconds: zod.z.number().int().positive().max(300).default(60)
8496
+ }),
8497
+ zod.z.array(zod.z.object({
8498
+ callerAddonId: zod.z.string(),
8499
+ providerAddonId: zod.z.string(),
8500
+ capName: zod.z.string(),
8501
+ callsPerMin: zod.z.number(),
8502
+ lastCallAtMs: zod.z.number()
8503
+ })).readonly(),
8504
+ { auth: "admin" }
8505
+ ),
8266
8506
  /**
8267
8507
  * Direct per-node addon listing — calls `$agent.status` on the target
8268
8508
  * node (or returns the hub registry for `nodeId === 'hub'`) and surfaces
@@ -8699,6 +8939,29 @@ const addonsCapability = {
8699
8939
  isActive: zod.z.boolean()
8700
8940
  })).readonly()
8701
8941
  ),
8942
+ /**
8943
+ * Toggle a single collection-cap provider on/off. Generic write-side
8944
+ * counterpart of `listCapabilityProviders` — drives the per-provider
8945
+ * Enable/Disable affordance in admin pages (TURN servers, etc.)
8946
+ * without needing a bespoke orchestrator cap.
8947
+ *
8948
+ * Reaches the hub's `CapabilityRegistry` directly:
8949
+ * `enableCollectionProvider` / `disableCollectionProvider` flip the
8950
+ * registry-level `disabledProviders` set. `getCollectionEntries`
8951
+ * already filters disabled providers out, so a disabled provider
8952
+ * drops out of every collection aggregate immediately. Only valid
8953
+ * for `mode: 'collection'` caps — the registry no-ops + warns for
8954
+ * singletons.
8955
+ */
8956
+ setCapabilityProviderEnabled: method(
8957
+ zod.z.object({
8958
+ capName: zod.z.string().min(1),
8959
+ addonId: zod.z.string().min(1),
8960
+ enabled: zod.z.boolean()
8961
+ }),
8962
+ zod.z.object({ success: zod.z.literal(true) }),
8963
+ { kind: "mutation", auth: "admin" }
8964
+ ),
8702
8965
  /**
8703
8966
  * Live-update one of the framework packages marked
8704
8967
  * `camstack.system: true` (`@camstack/types|kernel|core|sdk|ui-library`).
@@ -8837,7 +9100,6 @@ exports.AudioMetricsHistoryPointSchema = AudioMetricsHistoryPointSchema;
8837
9100
  exports.AudioMetricsHistorySchema = AudioMetricsHistorySchema;
8838
9101
  exports.AudioMetricsSnapshotSchema = AudioMetricsSnapshotSchema;
8839
9102
  exports.AudioPcmChunkSchema = AudioPcmChunkSchema;
8840
- exports.AuthProviderInfoSchema = AuthProviderInfoSchema;
8841
9103
  exports.AuthResultSchema = AuthResultSchema;
8842
9104
  exports.AutoUpdateSettingsSchema = AutoUpdateSettingsSchema;
8843
9105
  exports.AvailableIntegrationTypeSchema = AvailableIntegrationTypeSchema;
@@ -8891,6 +9153,7 @@ exports.DEFAULT_DECODER_HWACCEL_CONFIG = DEFAULT_DECODER_HWACCEL_CONFIG;
8891
9153
  exports.DEVICE_PROFILES = DEVICE_PROFILES;
8892
9154
  exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = DEVICE_SETTINGS_CONTRIBUTION_METHODS;
8893
9155
  exports.DEVICE_STATUS_METHOD = DEVICE_STATUS_METHOD;
9156
+ exports.DecodedAudioChunkSchema = DecodedAudioChunkSchema;
8894
9157
  exports.DecodedFrameSchema = DecodedFrameSchema;
8895
9158
  exports.DecoderAssignmentSchema = DecoderAssignmentSchema;
8896
9159
  exports.DecoderSessionConfigSchema = DecoderSessionConfigSchema;
@@ -8925,6 +9188,8 @@ exports.ExposedResourceSchema = ExposedResourceSchema;
8925
9188
  exports.FeatureManifestSchema = FeatureManifestSchema;
8926
9189
  exports.FeatureProbeStatusSchema = FeatureProbeStatusSchema;
8927
9190
  exports.FinalizeUploadInputSchema = FinalizeUploadInputSchema;
9191
+ exports.FrameHandleFormatSchema = FrameHandleFormatSchema;
9192
+ exports.FrameHandleSchema = FrameHandleSchema;
8928
9193
  exports.FrameInputSchema = FrameInputSchema;
8929
9194
  exports.GetStreamWithCodecInputSchema = GetStreamWithCodecInputSchema;
8930
9195
  exports.GlobalMetricsSchema = GlobalMetricsSchema;
@@ -8943,6 +9208,8 @@ exports.LogLevelSchema = LogLevelSchema$1;
8943
9208
  exports.LogStreamEntrySchema = LogStreamEntrySchema;
8944
9209
  exports.MODEL_FORMATS = MODEL_FORMATS;
8945
9210
  exports.MediaFileSchema = MediaFileSchema;
9211
+ exports.MeshPeerSchema = MeshPeerSchema;
9212
+ exports.MeshStatusSchema = MeshStatusSchema;
8946
9213
  exports.MethodAccessSchema = MethodAccessSchema;
8947
9214
  exports.MotionAnalysisResultSchema = MotionAnalysisResultSchema;
8948
9215
  exports.MotionEventSchema = MotionEventSchema;
@@ -8953,6 +9220,9 @@ exports.MotionSourcesSchema = MotionSourcesSchema;
8953
9220
  exports.MotionStatusSchema = MotionStatusSchema;
8954
9221
  exports.MotionTriggerRuntimeStateSchema = MotionTriggerRuntimeStateSchema;
8955
9222
  exports.MotionTriggerStatusSchema = MotionTriggerStatusSchema;
9223
+ exports.MotionZoneOptionsSchema = MotionZoneOptionsSchema;
9224
+ exports.MotionZonePatchSchema = MotionZonePatchSchema;
9225
+ exports.MotionZoneStatusSchema = MotionZoneStatusSchema;
8956
9226
  exports.NativeDetectionSchema = NativeDetectionSchema;
8957
9227
  exports.NativeObjectClassEnum = NativeObjectClassEnum;
8958
9228
  exports.NativeObjectDetectionStatusSchema = NativeObjectDetectionStatusSchema;
@@ -8962,6 +9232,7 @@ exports.NetworkEndpointSchema = NetworkEndpointSchema;
8962
9232
  exports.NotificationHistoryEntrySchema = NotificationHistoryEntrySchema;
8963
9233
  exports.NotificationRuleSchema = NotificationRuleSchema;
8964
9234
  exports.NotificationSchema = NotificationSchema;
9235
+ exports.OauthIntegrationDescriptorSchema = OauthIntegrationDescriptorSchema;
8965
9236
  exports.ObjectEventSchema = ObjectEventSchema;
8966
9237
  exports.OrchestratorMetricsSchema = OrchestratorMetricsSchema;
8967
9238
  exports.OsdOverlayKindEnum = OsdOverlayKindEnum;
@@ -8994,11 +9265,10 @@ exports.PtzAutotrackTargetOptionSchema = PtzAutotrackTargetOptionSchema;
8994
9265
  exports.PtzMoveCommandSchema = PtzMoveCommandSchema;
8995
9266
  exports.PtzPositionSchema = PtzPositionSchema;
8996
9267
  exports.PtzPresetSchema = PtzPresetSchema;
9268
+ exports.PtzStatusSchema = PtzStatusSchema;
8997
9269
  exports.QueryFilterSchema = QueryFilterSchema;
8998
9270
  exports.ReadChunkInputSchema = ReadChunkInputSchema;
8999
9271
  exports.RegisteredStreamSchema = RegisteredStreamSchema;
9000
- exports.RemoteAccessEndpointSchema = RemoteAccessEndpointSchema;
9001
- exports.RemoteAccessProviderInfoSchema = RemoteAccessProviderInfoSchema;
9002
9272
  exports.ReportMotionInputSchema = ReportMotionInputSchema;
9003
9273
  exports.RtpSourceSchema = RtpSourceSchema;
9004
9274
  exports.RtspRestreamEntrySchema = RtspRestreamEntrySchema;
@@ -9017,6 +9287,7 @@ exports.SettingsPatchSchema = SettingsPatchSchema;
9017
9287
  exports.SettingsRecordSchema = SettingsRecordSchema;
9018
9288
  exports.SettingsSchemaWithValuesSchema = SettingsSchemaWithValuesSchema;
9019
9289
  exports.SettingsUpdateResultSchema = SettingsUpdateResultSchema;
9290
+ exports.ShmRingStatsSchema = ShmRingStatsSchema;
9020
9291
  exports.SmtpStatusSchema = SmtpStatusSchema;
9021
9292
  exports.SnapshotImageSchema = SnapshotImageSchema;
9022
9293
  exports.SpatialDetectionSchema = SpatialDetectionSchema;
@@ -9029,8 +9300,18 @@ exports.StorageLocationTypeSchema = StorageLocationTypeSchema;
9029
9300
  exports.StreamFormatSchema = StreamFormatSchema;
9030
9301
  exports.StreamInfoSchema = StreamInfoSchema;
9031
9302
  exports.StreamNetworkStatsSchema = StreamNetworkStatsSchema;
9303
+ exports.StreamParamsOptionsSchema = StreamParamsOptionsSchema;
9304
+ exports.StreamParamsStatusSchema = StreamParamsStatusSchema;
9305
+ exports.StreamProfileConfigSchema = StreamProfileConfigSchema;
9306
+ exports.StreamProfileOptionsSchema = StreamProfileOptionsSchema;
9307
+ exports.StreamProfilePatchSchema = StreamProfilePatchSchema;
9308
+ exports.StreamProfileSchema = StreamProfileSchema;
9032
9309
  exports.StreamSourceEntrySchema = StreamSourceEntrySchema$1;
9033
9310
  exports.StreamSourceSchema = StreamSourceSchema;
9311
+ exports.SubscribeAudioChunksInputSchema = SubscribeAudioChunksInputSchema;
9312
+ exports.SubscribeAudioChunksResultSchema = SubscribeAudioChunksResultSchema;
9313
+ exports.SubscribeFramesInputSchema = SubscribeFramesInputSchema;
9314
+ exports.SubscribeFramesResultSchema = SubscribeFramesResultSchema;
9034
9315
  exports.SwitchStatusSchema = SwitchStatusSchema;
9035
9316
  exports.SystemMetricsSchema = SystemMetricsSchema;
9036
9317
  exports.TestConnectionResultSchema = TestConnectionResultSchema;
@@ -9043,7 +9324,6 @@ exports.TopologyServiceSchema = TopologyServiceSchema;
9043
9324
  exports.TrackSchema = TrackSchema;
9044
9325
  exports.TrackStateSchema = TrackStateSchema;
9045
9326
  exports.TrackedDetectionSchema = TrackedDetectionSchema;
9046
- exports.TurnProviderInfoSchema = TurnProviderInfoSchema;
9047
9327
  exports.TurnServerSchema = TurnServerSchema;
9048
9328
  exports.UnexposeInputSchema = UnexposeInputSchema;
9049
9329
  exports.UpdateIntegrationInputSchema = UpdateIntegrationInputSchema;
@@ -9056,6 +9336,7 @@ exports.WebrtcStreamChoiceSchema = WebrtcStreamChoiceSchema;
9056
9336
  exports.WebrtcStreamTargetSchema = WebrtcStreamTargetSchema;
9057
9337
  exports.WidgetHostEnum = WidgetHostEnum;
9058
9338
  exports.WidgetMetadataSchema = WidgetMetadataSchema;
9339
+ exports.WidgetRemoteSchema = WidgetRemoteSchema;
9059
9340
  exports.WidgetSizeEnum = WidgetSizeEnum;
9060
9341
  exports.WriteChunkInputSchema = WriteChunkInputSchema;
9061
9342
  exports.YAMNET_TO_MACRO = YAMNET_TO_MACRO;
@@ -9083,7 +9364,6 @@ exports.audioAnalyzerCapability = audioAnalyzerCapability;
9083
9364
  exports.audioCodecCapability = audioCodecCapability;
9084
9365
  exports.audioMetricsCapability = audioMetricsCapability;
9085
9366
  exports.authProviderCapability = authProviderCapability;
9086
- exports.authenticationCapability = authenticationCapability;
9087
9367
  exports.backupCapability = backupCapability;
9088
9368
  exports.batteryCapability = batteryCapability;
9089
9369
  exports.brightnessCapability = brightnessCapability;
@@ -9110,22 +9390,24 @@ exports.getAudioMacroClassIds = getAudioMacroClassIds;
9110
9390
  exports.hydrateSchema = hydrateSchema;
9111
9391
  exports.integrationsCapability = integrationsCapability;
9112
9392
  exports.intercomCapability = intercomCapability;
9393
+ exports.isDeviceConfigCap = isDeviceConfigCap;
9113
9394
  exports.localNetworkCapability = localNetworkCapability;
9114
9395
  exports.logDestinationCapability = logDestinationCapability;
9115
9396
  exports.mapAudioLabelToMacro = mapAudioLabelToMacro;
9116
9397
  exports.meshNetworkCapability = meshNetworkCapability;
9117
- exports.meshOrchestratorCapability = meshOrchestratorCapability;
9118
9398
  exports.method = method;
9119
9399
  exports.metricsProviderCapability = metricsProviderCapability;
9120
9400
  exports.motionCapability = motionCapability;
9121
9401
  exports.motionDetectionCapability = motionDetectionCapability;
9122
9402
  exports.motionTriggerCapability = motionTriggerCapability;
9403
+ exports.motionZonesCapability = motionZonesCapability;
9123
9404
  exports.mqttBrokerCapability = mqttBrokerCapability;
9124
9405
  exports.nativeObjectDetectionCapability = nativeObjectDetectionCapability;
9125
9406
  exports.networkAccessCapability = networkAccessCapability;
9126
9407
  exports.networkQualityCapability = networkQualityCapability;
9127
9408
  exports.nodesCapability = nodesCapability;
9128
9409
  exports.notificationOutputCapability = notificationOutputCapability;
9410
+ exports.oauthIntegrationCapability = oauthIntegrationCapability;
9129
9411
  exports.osdCapability = osdCapability;
9130
9412
  exports.pipelineAnalyticsCapability = pipelineAnalyticsCapability;
9131
9413
  exports.pipelineExecutorCapability = pipelineExecutorCapability;
@@ -9137,7 +9419,6 @@ exports.ptzCapability = ptzCapability;
9137
9419
  exports.rebootCapability = rebootCapability;
9138
9420
  exports.recordingCapability = recordingCapability;
9139
9421
  exports.recordingEngineCapability = recordingEngineCapability;
9140
- exports.remoteAccessCapability = remoteAccessCapability;
9141
9422
  exports.resolveDeviceProfile = resolveDeviceProfile;
9142
9423
  exports.restreamerCapability = restreamerCapability;
9143
9424
  exports.settingsStoreCapability = settingsStoreCapability;
@@ -9148,11 +9429,11 @@ exports.ssoBridgeCapability = ssoBridgeCapability;
9148
9429
  exports.storageCapability = storageCapability;
9149
9430
  exports.storageProviderCapability = storageProviderCapability;
9150
9431
  exports.streamBrokerCapability = streamBrokerCapability;
9432
+ exports.streamParamsCapability = streamParamsCapability;
9151
9433
  exports.streamingEngineCapability = streamingEngineCapability;
9152
9434
  exports.switchCapability = switchCapability;
9153
9435
  exports.systemCapability = systemCapability;
9154
9436
  exports.toastCapability = toastCapability;
9155
- exports.turnOrchestratorCapability = turnOrchestratorCapability;
9156
9437
  exports.turnProviderCapability = turnProviderCapability;
9157
9438
  exports.userManagementCapability = userManagementCapability;
9158
9439
  exports.userPasskeysCapability = userPasskeysCapability;
@@ -9162,4 +9443,4 @@ exports.webrtcSessionCapability = webrtcSessionCapability;
9162
9443
  exports.zoneAnalyticsCapability = zoneAnalyticsCapability;
9163
9444
  exports.zoneRulesCapability = zoneRulesCapability;
9164
9445
  exports.zonesCapability = zonesCapability;
9165
- //# sourceMappingURL=index-DS7418lf.js.map
9446
+ //# sourceMappingURL=index-BblD92Si.js.map