@camstack/types 1.2.41 → 1.2.43

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 (43) hide show
  1. package/dist/addon.js +1 -1
  2. package/dist/addon.mjs +1 -1
  3. package/dist/canonical-hash-7nfBbEqR.mjs +35 -0
  4. package/dist/canonical-hash-BcZHRHIx.js +40 -0
  5. package/dist/cap-call-context.d.ts +26 -0
  6. package/dist/capabilities/index.d.ts +5 -5
  7. package/dist/capabilities/notification-rules.cap.d.ts +41 -0
  8. package/dist/capabilities/pipeline-analytics.cap.d.ts +92 -4
  9. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +149 -0
  10. package/dist/capabilities/pipeline-runner.cap.d.ts +119 -1
  11. package/dist/capabilities/platform-probe.cap.d.ts +3 -3
  12. package/dist/capabilities/privacy-mask.cap.d.ts +69 -9
  13. package/dist/capabilities/recording.cap.d.ts +30 -0
  14. package/dist/capabilities/snapshot.cap.d.ts +1 -1
  15. package/dist/capabilities/stream-broker.cap.d.ts +304 -0
  16. package/dist/capabilities/stream-params.cap.d.ts +8 -4
  17. package/dist/device/device-profile.d.ts +12 -4
  18. package/dist/device/system-mirror.d.ts +11 -0
  19. package/dist/encode-profile.d.ts +2 -0
  20. package/dist/ffmpeg/encode-defaults.d.ts +107 -0
  21. package/dist/ffmpeg/hwaccel.d.ts +98 -0
  22. package/dist/ffmpeg/invocation.d.ts +348 -0
  23. package/dist/ffmpeg/process.d.ts +135 -0
  24. package/dist/ffmpeg/sharing-key.d.ts +91 -0
  25. package/dist/generated/addon-api.d.ts +92 -4
  26. package/dist/generated/device-proxy.d.ts +2 -2
  27. package/dist/generated/method-access-map.d.ts +1 -1
  28. package/dist/generated/system-proxy.d.ts +2 -2
  29. package/dist/index.d.ts +7 -0
  30. package/dist/index.js +2069 -42
  31. package/dist/index.mjs +2006 -43
  32. package/dist/interfaces/camera-switches.d.ts +375 -0
  33. package/dist/interfaces/inference-engine.d.ts +24 -3
  34. package/dist/interfaces/ops-log.d.ts +4 -0
  35. package/dist/interfaces/pipeline-runner-capability.d.ts +9 -1
  36. package/dist/node.d.ts +2 -0
  37. package/dist/node.js +270 -36
  38. package/dist/node.mjs +269 -36
  39. package/dist/pipeline/native-lease.d.ts +150 -0
  40. package/dist/{sleep-DTce7-ch.js → sleep-Bx9IIoT0.js} +43 -1
  41. package/dist/{sleep-CXimb854.mjs → sleep-DtstvzWm.mjs} +38 -2
  42. package/dist/utils/addon-id.d.ts +30 -0
  43. package/package.json +1 -1
@@ -441,6 +441,15 @@ declare const CameraStatusSchema: z.ZodObject<{
441
441
  active: z.ZodBoolean;
442
442
  storageBytes: z.ZodNumber;
443
443
  }, z.core.$strip>>;
444
+ switchedOff: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
445
+ "privacy-mask": "privacy-mask";
446
+ "audio-analysis": "audio-analysis";
447
+ recording: "recording";
448
+ "stream-broker": "stream-broker";
449
+ notifications: "notifications";
450
+ "object-detection": "object-detection";
451
+ "device-audio": "device-audio";
452
+ }>>>;
444
453
  fetchedAt: z.ZodNumber;
445
454
  }, z.core.$strip>;
446
455
  declare const NodeInferenceDeviceSchema: z.ZodObject<{
@@ -1062,6 +1071,128 @@ export declare const pipelineOrchestratorCapability: {
1062
1071
  settings: z.ZodOptional<z.ZodReadonly<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
1063
1072
  }, z.core.$strip>>>;
1064
1073
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
1074
+ /**
1075
+ * The whole per-camera function switch group, DERIVED — never a stored
1076
+ * list ([D61](../../../../docs/decisions/adr-0067.md)).
1077
+ *
1078
+ * The group adds no state. Each switch is a view onto the authority that
1079
+ * already owned it (`deviceManager.setDisabled`,
1080
+ * `deviceManager.setWrapperActive`, `RecordingConfig.enabled`,
1081
+ * `notificationRules.setDeviceMuted`), and `switch.authority` says which.
1082
+ * Availability comes from `deviceManager.listBindableCapsForDeviceType`,
1083
+ * so a deployment with no audio analyzer renders no audio switch.
1084
+ *
1085
+ * `auth: 'view'` deliberately — a NON-admin must be able to see that a
1086
+ * camera is quiet because somebody switched it off. Only the mutation is
1087
+ * admin-gated.
1088
+ */
1089
+ readonly getCameraSwitches: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
1090
+ deviceId: z.ZodNumber;
1091
+ }, z.core.$strip>, z.ZodObject<{
1092
+ deviceId: z.ZodNumber;
1093
+ switches: z.ZodReadonly<z.ZodArray<z.ZodObject<{
1094
+ id: z.ZodEnum<{
1095
+ "privacy-mask": "privacy-mask";
1096
+ "audio-analysis": "audio-analysis";
1097
+ recording: "recording";
1098
+ "stream-broker": "stream-broker";
1099
+ notifications: "notifications";
1100
+ "object-detection": "object-detection";
1101
+ "device-audio": "device-audio";
1102
+ }>;
1103
+ label: z.ZodString;
1104
+ costWhenOff: z.ZodString;
1105
+ available: z.ZodBoolean;
1106
+ unavailableReason: z.ZodOptional<z.ZodEnum<{
1107
+ "no-provider": "no-provider";
1108
+ "source-unreachable": "source-unreachable";
1109
+ "not-configured": "not-configured";
1110
+ }>>;
1111
+ enabled: z.ZodBoolean;
1112
+ authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
1113
+ kind: z.ZodLiteral<"device-disabled">;
1114
+ }, z.core.$strip>, z.ZodObject<{
1115
+ kind: z.ZodLiteral<"wrapper-binding">;
1116
+ capName: z.ZodString;
1117
+ }, z.core.$strip>, z.ZodObject<{
1118
+ kind: z.ZodLiteral<"recording-config">;
1119
+ }, z.core.$strip>, z.ZodObject<{
1120
+ kind: z.ZodLiteral<"notification-mute">;
1121
+ }, z.core.$strip>, z.ZodObject<{
1122
+ kind: z.ZodLiteral<"camera-audio">;
1123
+ capName: z.ZodString;
1124
+ }, z.core.$strip>, z.ZodObject<{
1125
+ kind: z.ZodLiteral<"camera-mask">;
1126
+ capName: z.ZodString;
1127
+ }, z.core.$strip>], "kind">;
1128
+ }, z.core.$strip>>>;
1129
+ fetchedAt: z.ZodNumber;
1130
+ }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
1131
+ /**
1132
+ * Flip ONE switch, routed to its existing authority.
1133
+ *
1134
+ * Never writes a parallel map: `recording` patches `RecordingConfig.enabled`
1135
+ * and leaves `bands` byte-identical (clearing bands to express "off"
1136
+ * destroys the operator's authored schedule and turning the camera back on
1137
+ * would silently record nothing), and the two pipeline switches write the
1138
+ * SAME wrapper binding the legacy `pipelineEnabled` / `audioEnabled`
1139
+ * booleans were migrated onto.
1140
+ *
1141
+ * Rejects a switch this camera does not offer rather than persisting a
1142
+ * write nothing reads.
1143
+ */
1144
+ readonly setCameraSwitch: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
1145
+ deviceId: z.ZodNumber;
1146
+ switchId: z.ZodEnum<{
1147
+ "privacy-mask": "privacy-mask";
1148
+ "audio-analysis": "audio-analysis";
1149
+ recording: "recording";
1150
+ "stream-broker": "stream-broker";
1151
+ notifications: "notifications";
1152
+ "object-detection": "object-detection";
1153
+ "device-audio": "device-audio";
1154
+ }>;
1155
+ enabled: z.ZodBoolean;
1156
+ }, z.core.$strip>, z.ZodObject<{
1157
+ deviceId: z.ZodNumber;
1158
+ switches: z.ZodReadonly<z.ZodArray<z.ZodObject<{
1159
+ id: z.ZodEnum<{
1160
+ "privacy-mask": "privacy-mask";
1161
+ "audio-analysis": "audio-analysis";
1162
+ recording: "recording";
1163
+ "stream-broker": "stream-broker";
1164
+ notifications: "notifications";
1165
+ "object-detection": "object-detection";
1166
+ "device-audio": "device-audio";
1167
+ }>;
1168
+ label: z.ZodString;
1169
+ costWhenOff: z.ZodString;
1170
+ available: z.ZodBoolean;
1171
+ unavailableReason: z.ZodOptional<z.ZodEnum<{
1172
+ "no-provider": "no-provider";
1173
+ "source-unreachable": "source-unreachable";
1174
+ "not-configured": "not-configured";
1175
+ }>>;
1176
+ enabled: z.ZodBoolean;
1177
+ authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
1178
+ kind: z.ZodLiteral<"device-disabled">;
1179
+ }, z.core.$strip>, z.ZodObject<{
1180
+ kind: z.ZodLiteral<"wrapper-binding">;
1181
+ capName: z.ZodString;
1182
+ }, z.core.$strip>, z.ZodObject<{
1183
+ kind: z.ZodLiteral<"recording-config">;
1184
+ }, z.core.$strip>, z.ZodObject<{
1185
+ kind: z.ZodLiteral<"notification-mute">;
1186
+ }, z.core.$strip>, z.ZodObject<{
1187
+ kind: z.ZodLiteral<"camera-audio">;
1188
+ capName: z.ZodString;
1189
+ }, z.core.$strip>, z.ZodObject<{
1190
+ kind: z.ZodLiteral<"camera-mask">;
1191
+ capName: z.ZodString;
1192
+ }, z.core.$strip>], "kind">;
1193
+ }, z.core.$strip>>>;
1194
+ fetchedAt: z.ZodNumber;
1195
+ }, z.core.$strip>, "mutation">;
1065
1196
  /**
1066
1197
  * Server-composed aggregated status for a single camera.
1067
1198
  *
@@ -1171,6 +1302,15 @@ export declare const pipelineOrchestratorCapability: {
1171
1302
  active: z.ZodBoolean;
1172
1303
  storageBytes: z.ZodNumber;
1173
1304
  }, z.core.$strip>>;
1305
+ switchedOff: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
1306
+ "privacy-mask": "privacy-mask";
1307
+ "audio-analysis": "audio-analysis";
1308
+ recording: "recording";
1309
+ "stream-broker": "stream-broker";
1310
+ notifications: "notifications";
1311
+ "object-detection": "object-detection";
1312
+ "device-audio": "device-audio";
1313
+ }>>>;
1174
1314
  fetchedAt: z.ZodNumber;
1175
1315
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
1176
1316
  /**
@@ -1281,6 +1421,15 @@ export declare const pipelineOrchestratorCapability: {
1281
1421
  active: z.ZodBoolean;
1282
1422
  storageBytes: z.ZodNumber;
1283
1423
  }, z.core.$strip>>;
1424
+ switchedOff: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
1425
+ "privacy-mask": "privacy-mask";
1426
+ "audio-analysis": "audio-analysis";
1427
+ recording: "recording";
1428
+ "stream-broker": "stream-broker";
1429
+ notifications: "notifications";
1430
+ "object-detection": "object-detection";
1431
+ "device-audio": "device-audio";
1432
+ }>>>;
1284
1433
  fetchedAt: z.ZodNumber;
1285
1434
  }, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
1286
1435
  /** List every template the operator has saved. */
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { type InferProvider } from './capability-definition.js';
3
2
  import type { ConfigField } from '../interfaces/config-ui.js';
3
+ import { type InferProvider } from './capability-definition.js';
4
4
  /**
5
5
  * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
6
6
  * decode worker resolves it against the RETAINED native frame's real pixel dims,
@@ -60,6 +60,27 @@ declare const DetailResultSchema: z.ZodObject<{
60
60
  }, z.core.$strip>;
61
61
  export type DetailParent = z.infer<typeof DetailParentSchema>;
62
62
  export type DetailResult = z.infer<typeof DetailResultSchema>;
63
+ /**
64
+ * Why an executing node REFUSED a stateless step run (`runStatelessStep`).
65
+ *
66
+ * A refusal is a first-class answer, not an error, because the caller's next
67
+ * move depends on WHICH one it is — and because "the pass produced nothing"
68
+ * must never be reachable without a named, counted cause. The two tiers:
69
+ *
70
+ * - **node-level** (`unknown-step`, `model-not-servable`) — this node can
71
+ * never serve this (step, model) pair. The caller drops it from its rotation
72
+ * and retries the same work elsewhere; nothing about the work changes.
73
+ * - **work-level** (`unreadable-frame`, `execution-failed`) — this node is
74
+ * fine, this one request is not. Retrying it on another node would only
75
+ * spread the same failure.
76
+ */
77
+ declare const StatelessStepRefusalSchema: z.ZodEnum<{
78
+ "unknown-step": "unknown-step";
79
+ "model-not-servable": "model-not-servable";
80
+ "unreadable-frame": "unreadable-frame";
81
+ "execution-failed": "execution-failed";
82
+ }>;
83
+ export type StatelessStepRefusal = z.infer<typeof StatelessStepRefusalSchema>;
63
84
  /**
64
85
  * Source enum for motion signals fed to the runner. Extensible — add
65
86
  * new variants here when new motion-trigger paths are wired in
@@ -606,6 +627,92 @@ export declare const pipelineRunnerCapability: {
606
627
  nativeFaceShortSidePx: z.ZodOptional<z.ZodNumber>;
607
628
  }, z.core.$strip>>;
608
629
  }, z.core.$strip>>, "mutation">;
630
+ /**
631
+ * Run ONE enrichment step against caller-supplied pixels, with NO camera
632
+ * session — no attach, no frame handle, no device affinity.
633
+ *
634
+ * ## Why this exists next to `runDetailSubtree` and not inside it
635
+ *
636
+ * `runDetailSubtree` resolves its step tree from the LIVE ATTACH STATE. That
637
+ * is correct for it: its reason to exist is a frame HANDLE, and a handle is
638
+ * only resolvable while a decode session is open. But it makes the method
639
+ * useless to anything walking history — cameras run `detectionMode:
640
+ * 'on-motion'` and detach ~30 s after motion stops, so a fleet-wide
641
+ * embedding rebuild found most cameras detached and rebuilt only whatever
642
+ * happened to be attached at that second (measured 2026-08-06: 1125 tracks
643
+ * scanned, 121 rebuilt, 601 refused as "camera is not attached").
644
+ *
645
+ * A caller that ships its own pixels needs none of that machinery. So this
646
+ * method takes the three things a step actually needs — an image, a box, a
647
+ * step id — resolves the step from the CATALOG rather than from an
648
+ * attachment, and runs it on whichever node the caller pinned.
649
+ *
650
+ * ## What it deliberately keeps
651
+ *
652
+ * The crop rectangle is derived by the SAME `deriveDetailCropRect` call the
653
+ * live detail plane uses, from the same cluster-wide convention
654
+ * ([D52](../../../docs/decisions/adr-0052.md)). `frameJpeg` is a FULL frame,
655
+ * never a pre-cut tile, for exactly the reason `runDetailSubtree` documents:
656
+ * a caller that cuts is a second feature space.
657
+ *
658
+ * ## What it deliberately drops
659
+ *
660
+ * No device jump and no `deviceKey`: the jump roster comes from the attach
661
+ * config, which does not exist here. The step runs on the node's default
662
+ * engine. This is a maintenance path, not a latency-sensitive one.
663
+ *
664
+ * ## Routing
665
+ *
666
+ * NOT device-bound. `sourceDeviceId` is DIAGNOSTIC — the camera whose track
667
+ * these pixels came from, so every log line on the executing node can carry
668
+ * `tags: { deviceId }`. It is deliberately not named `deviceId`: that field
669
+ * is a routing hint that would send the call to the camera's owning node,
670
+ * which is the placement constraint this method exists to remove. Callers
671
+ * choose the node with `nodePin(nodeId)`; unpinned, an unowned call is
672
+ * served hub-in-process like any other singleton.
673
+ */
674
+ readonly runStatelessStep: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
675
+ stepId: z.ZodString;
676
+ modelId: z.ZodString;
677
+ frameJpeg: z.ZodString;
678
+ bbox: z.ZodObject<{
679
+ x: z.ZodNumber;
680
+ y: z.ZodNumber;
681
+ w: z.ZodNumber;
682
+ h: z.ZodNumber;
683
+ }, z.core.$strip>;
684
+ className: z.ZodString;
685
+ sourceDeviceId: z.ZodNumber;
686
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
687
+ kind: z.ZodLiteral<"ran">;
688
+ nodeId: z.ZodString;
689
+ modelId: z.ZodString;
690
+ details: z.ZodArray<z.ZodObject<{
691
+ stepId: z.ZodString;
692
+ className: z.ZodString;
693
+ score: z.ZodNumber;
694
+ bbox: z.ZodOptional<z.ZodObject<{
695
+ x: z.ZodNumber;
696
+ y: z.ZodNumber;
697
+ w: z.ZodNumber;
698
+ h: z.ZodNumber;
699
+ }, z.core.$strip>>;
700
+ embedding: z.ZodOptional<z.ZodString>;
701
+ label: z.ZodOptional<z.ZodString>;
702
+ alignedCropJpeg: z.ZodOptional<z.ZodString>;
703
+ nativeFaceShortSidePx: z.ZodOptional<z.ZodNumber>;
704
+ }, z.core.$strip>>;
705
+ }, z.core.$strip>, z.ZodObject<{
706
+ kind: z.ZodLiteral<"refused">;
707
+ nodeId: z.ZodString;
708
+ reason: z.ZodEnum<{
709
+ "unknown-step": "unknown-step";
710
+ "model-not-servable": "model-not-servable";
711
+ "unreadable-frame": "unreadable-frame";
712
+ "execution-failed": "execution-failed";
713
+ }>;
714
+ detail: z.ZodString;
715
+ }, z.core.$strip>], "kind">, "mutation">;
609
716
  };
610
717
  };
611
718
  export type IPipelineRunnerProvider = InferProvider<typeof pipelineRunnerCapability>;
@@ -623,4 +730,15 @@ export type IPipelineRunnerProvider = InferProvider<typeof pipelineRunnerCapabil
623
730
  */
624
731
  export type RunDetailSubtreeInput = Parameters<IPipelineRunnerProvider['runDetailSubtree']>[0];
625
732
  export type RunDetailSubtreeResult = NonNullable<Awaited<ReturnType<IPipelineRunnerProvider['runDetailSubtree']>>>;
733
+ /**
734
+ * Named input/output types for `runStatelessStep`, derived the same way and for
735
+ * the same reason as the `runDetailSubtree` pair above — the method's input
736
+ * stays an inline `z.object({…})` literal so `scripts/lib/parse-cap.ts` keeps
737
+ * classifying it correctly. Here the classification wanted is the OPPOSITE one:
738
+ * there is no `deviceId: z.number(` in the body, so the method is NOT
739
+ * device-bound and never lands on `DeviceProxy` — placement is the caller's
740
+ * `nodePin`, not the camera's owner.
741
+ */
742
+ export type RunStatelessStepInput = Parameters<IPipelineRunnerProvider['runStatelessStep']>[0];
743
+ export type RunStatelessStepResult = Awaited<ReturnType<IPipelineRunnerProvider['runStatelessStep']>>;
626
744
  export { RunnerCameraConfigSchema, RunnerLocalLoadSchema, RunnerLocalMetricsSchema };
@@ -277,12 +277,12 @@ export declare const platformProbeCapability: {
277
277
  coreml: "coreml";
278
278
  openvino: "openvino";
279
279
  none: "none";
280
- tensorrt: "tensorrt";
281
- cuda: "cuda";
282
280
  videotoolbox: "videotoolbox";
283
- nvdec: "nvdec";
284
281
  vaapi: "vaapi";
285
282
  qsv: "qsv";
283
+ cuda: "cuda";
284
+ tensorrt: "tensorrt";
285
+ nvdec: "nvdec";
286
286
  d3d11va: "d3d11va";
287
287
  dxva2: "dxva2";
288
288
  amf: "amf";
@@ -1,13 +1,31 @@
1
1
  import { z } from 'zod';
2
- import { type InferNativeProvider } from './capability-definition.js';
3
2
  import { DeviceType } from '../device/device-type.js';
3
+ import { type InferNativeProvider } from './capability-definition.js';
4
4
  /**
5
- * Privacy mask = up to `maxRegions` SHAPES the camera blanks out (NOT a
6
- * cell grid). Reolink `<shelterList>` zones are rectangles; Hikvision
7
- * ISAPI `<RegionCoordinatesList>` zones are free polygons (this camera:
8
- * exactly 4 vertices, not necessarily axis-aligned). The cap composes the
9
- * shared rect|polygon subset of the MaskShape vocabulary. All coords are
10
- * normalized 0..1 (top-left origin).
5
+ * PRIVACY what the camera deliberately does not capture. Two planes:
6
+ *
7
+ * - **video**: up to `maxRegions` SHAPES the camera blanks out (NOT a cell
8
+ * grid). Reolink `<shelterList>` zones are rectangles; Hikvision ISAPI
9
+ * `<RegionCoordinatesList>` zones are free polygons (this camera: exactly
10
+ * 4 vertices, not necessarily axis-aligned). The cap composes the shared
11
+ * rect|polygon subset of the MaskShape vocabulary. All coords are
12
+ * normalized 0..1 (top-left origin).
13
+ * - **audio**: the camera's microphone. `setAudioEnabled(false)` stops the
14
+ * camera encoding an audio track at all, so EVERY consumer — live view,
15
+ * recording, the audio analyzer, an export — sees silent video. There is
16
+ * no server-side copy of this fact; the camera is the store and every read
17
+ * is a read-through, which is why a switch over it cannot drift
18
+ * ([D62](../../../../docs/decisions/adr-0062.md)).
19
+ *
20
+ * Both belong here for one reason: they are the two things an operator turns
21
+ * off when the answer to "what is this camera allowed to record" changes, and
22
+ * both are applied ON the device, before anything leaves it.
23
+ *
24
+ * **The audio flag has exactly one writer.** `stream-params` used to carry a
25
+ * per-profile `audio` in its patch schema — reachable from no UI and honoured
26
+ * by one provider — and it was removed when this landed. A second writer onto
27
+ * one device register is the shape of every knob this repo has shipped that
28
+ * disagreed with the one the reader read.
11
29
  */
12
30
  /** A privacy-mask region's geometry — rectangle or free polygon. */
13
31
  export declare const PrivacyMaskShapeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -41,7 +59,7 @@ export declare const PrivacyMaskRegionSchema: z.ZodObject<{
41
59
  }, z.core.$strip>>;
42
60
  }, z.core.$strip>], "kind">;
43
61
  }, z.core.$strip>;
44
- /** Current on-camera privacy-mask state — master enable + zones. */
62
+ /** Current on-camera privacy state — mask master enable + zones + microphone. */
45
63
  export declare const PrivacyMaskStatusSchema: z.ZodObject<{
46
64
  enabled: z.ZodBoolean;
47
65
  regions: z.ZodArray<z.ZodObject<{
@@ -61,9 +79,10 @@ export declare const PrivacyMaskStatusSchema: z.ZodObject<{
61
79
  }, z.core.$strip>>;
62
80
  }, z.core.$strip>], "kind">;
63
81
  }, z.core.$strip>>;
82
+ audioEnabled: z.ZodNullable<z.ZodBoolean>;
64
83
  lastFetchedAt: z.ZodNumber;
65
84
  }, z.core.$strip>;
66
- /** Per-camera availability. */
85
+ /** Per-camera availability. Probed, never assumed from the model name. */
67
86
  export declare const PrivacyMaskOptionsSchema: z.ZodObject<{
68
87
  maxRegions: z.ZodNumber;
69
88
  supportedShapes: z.ZodArray<z.ZodEnum<{
@@ -76,6 +95,7 @@ export declare const PrivacyMaskOptionsSchema: z.ZodObject<{
76
95
  min: z.ZodNumber;
77
96
  max: z.ZodNumber;
78
97
  }, z.core.$strip>>;
98
+ supportsAudioMute: z.ZodBoolean;
79
99
  }, z.core.$strip>;
80
100
  /** Partial change — every field optional. */
81
101
  export declare const PrivacyMaskPatchSchema: z.ZodObject<{
@@ -132,6 +152,7 @@ export declare const privacyMaskCapability: {
132
152
  min: z.ZodNumber;
133
153
  max: z.ZodNumber;
134
154
  }, z.core.$strip>>;
155
+ supportsAudioMute: z.ZodBoolean;
135
156
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
136
157
  readonly setMask: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
137
158
  deviceId: z.ZodNumber;
@@ -156,6 +177,24 @@ export declare const privacyMaskCapability: {
156
177
  }, z.core.$strip>>>;
157
178
  }, z.core.$strip>;
158
179
  }, z.core.$strip>, z.ZodVoid, "mutation">;
180
+ /**
181
+ * Turn the camera's microphone on or off, at the camera.
182
+ *
183
+ * Deliberately its OWN mutation rather than a field on
184
+ * {@link PrivacyMaskPatchSchema}: `patch.enabled` already means "the video
185
+ * mask master switch", and overloading it would make one boolean mean two
186
+ * unrelated things on the same call. It is also the only method here whose
187
+ * write leaves the device in a state a later `getStatus` reads back
188
+ * verbatim, which is what makes it safe as a switch authority.
189
+ *
190
+ * A camera whose `getOptions().supportsAudioMute` is false must REJECT
191
+ * this rather than silently accept it — a write nothing applies is exactly
192
+ * what the switch group exists to remove.
193
+ */
194
+ readonly setAudioEnabled: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
195
+ deviceId: z.ZodNumber;
196
+ enabled: z.ZodBoolean;
197
+ }, z.core.$strip>, z.ZodVoid, "mutation">;
159
198
  };
160
199
  readonly status: {
161
200
  readonly schema: z.ZodObject<{
@@ -177,6 +216,7 @@ export declare const privacyMaskCapability: {
177
216
  }, z.core.$strip>>;
178
217
  }, z.core.$strip>], "kind">;
179
218
  }, z.core.$strip>>;
219
+ audioEnabled: z.ZodNullable<z.ZodBoolean>;
180
220
  lastFetchedAt: z.ZodNumber;
181
221
  }, z.core.$strip>;
182
222
  readonly kind: "poll";
@@ -200,7 +240,27 @@ export declare const privacyMaskCapability: {
200
240
  }, z.core.$strip>>;
201
241
  }, z.core.$strip>], "kind">;
202
242
  }, z.core.$strip>>;
243
+ audioEnabled: z.ZodNullable<z.ZodBoolean>;
203
244
  lastFetchedAt: z.ZodNumber;
204
245
  }, z.core.$strip>;
205
246
  };
206
247
  export type IPrivacyMaskProvider = InferNativeProvider<typeof privacyMaskCapability>;
248
+ /**
249
+ * Collapse a camera's PER-PROFILE audio flags into the one answer
250
+ * {@link PrivacyMaskStatusSchema.shape.audioEnabled} promises.
251
+ *
252
+ * Both firmwares this cap talks to store the flag per stream profile, and
253
+ * both let those profiles disagree. The rule is `some`, not `every`: privacy
254
+ * is only satisfied when NOTHING is carrying sound, so a camera whose sub
255
+ * stream is still audible must read as `true` and be switchable off — not as
256
+ * `false` because the main stream happens to be muted already.
257
+ *
258
+ * An empty list is `null` ("this camera reported no audio flag at all"),
259
+ * never `false`.
260
+ *
261
+ * Lives here rather than in each provider so the rule the schema documents
262
+ * and the rule the providers apply cannot drift apart.
263
+ */
264
+ export declare function summarisePrivacyAudio(profiles: readonly {
265
+ readonly audioEnabled: boolean;
266
+ }[]): boolean | null;
@@ -109,6 +109,20 @@ export declare const ReadSegmentBytesResultSchema: z.ZodObject<{
109
109
  data: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
110
110
  }, z.core.$strip>;
111
111
  export type ReadSegmentBytesResult = z.infer<typeof ReadSegmentBytesResultSchema>;
112
+ /**
113
+ * One GOP of a finalized segment, cut by byte range through the segment's own
114
+ * `mfra` (D31 on the D42 feeder path). `data` is the `ftyp`+`moov` head plus
115
+ * the single `moof`+`mdat` covering the requested instant — standalone-
116
+ * demuxable, never the whole file. When the segment's index cannot be parsed
117
+ * the provider degrades INSIDE the mechanism to the whole segment (still one
118
+ * `data`, `gopStartMs` = the segment start) — a worse read, not another path.
119
+ */
120
+ export declare const ReadGopBytesResultSchema: z.ZodObject<{
121
+ data: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
122
+ gopStartMs: z.ZodNumber;
123
+ gopDurMs: z.ZodNumber;
124
+ }, z.core.$strip>;
125
+ export type ReadGopBytesResult = z.infer<typeof ReadGopBytesResultSchema>;
112
126
  export declare const recordingCapability: {
113
127
  readonly name: "recording";
114
128
  readonly scope: "system";
@@ -246,6 +260,19 @@ export declare const recordingCapability: {
246
260
  }, z.core.$strip>, z.ZodObject<{
247
261
  data: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
248
262
  }, z.core.$strip>, "query">;
263
+ /** Read the single GOP of segment `startMs` covering `epochMs`, by mfra
264
+ * byte range — the scrub-granular read (D31 letter on the feeder path).
265
+ * See {@link ReadGopBytesResultSchema} for the degradation contract. */
266
+ readonly readGopBytes: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
267
+ deviceId: z.ZodNumber;
268
+ profile: z.ZodString;
269
+ startMs: z.ZodNumber;
270
+ epochMs: z.ZodNumber;
271
+ }, z.core.$strip>, z.ZodObject<{
272
+ data: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
273
+ gopStartMs: z.ZodNumber;
274
+ gopDurMs: z.ZodNumber;
275
+ }, z.core.$strip>, "query">;
249
276
  readonly setDeviceConfig: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
250
277
  deviceId: z.ZodNumber;
251
278
  config: z.ZodObject<{
@@ -355,6 +382,7 @@ export declare const recordingCapability: {
355
382
  operator: "operator";
356
383
  retention: "retention";
357
384
  quota: "quota";
385
+ maintenance: "maintenance";
358
386
  }>>;
359
387
  }, z.core.$strip>, z.ZodObject<{
360
388
  floorMs: z.ZodNullable<z.ZodNumber>;
@@ -393,12 +421,14 @@ export declare const recordingCapability: {
393
421
  rescan: "rescan";
394
422
  "retention-run": "retention-run";
395
423
  relocate: "relocate";
424
+ "orphan-audit": "orphan-audit";
396
425
  }>;
397
426
  reason: z.ZodEnum<{
398
427
  manual: "manual";
399
428
  operator: "operator";
400
429
  retention: "retention";
401
430
  quota: "quota";
431
+ maintenance: "maintenance";
402
432
  }>;
403
433
  deviceId: z.ZodNullable<z.ZodNumber>;
404
434
  nodeId: z.ZodString;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { type InferProvider } from './capability-definition.js';
3
2
  import { DeviceType } from '../device/device-type.js';
3
+ import { type InferProvider } from './capability-definition.js';
4
4
  /**
5
5
  * A single device snapshot returned as base64 JPEG/PNG.
6
6
  *