@camstack/types 1.2.17 → 1.2.19

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 (36) hide show
  1. package/dist/addon.js +2 -2
  2. package/dist/addon.mjs +2 -2
  3. package/dist/capabilities/addons.cap.d.ts +2 -2
  4. package/dist/capabilities/device-manager.cap.d.ts +22 -0
  5. package/dist/capabilities/index.d.ts +2 -2
  6. package/dist/capabilities/llm-runtime.cap.d.ts +3 -3
  7. package/dist/capabilities/llm.cap.d.ts +4 -4
  8. package/dist/capabilities/motion.cap.d.ts +13 -1
  9. package/dist/capabilities/notification-rules.cap.d.ts +142 -0
  10. package/dist/capabilities/pipeline-analytics.cap.d.ts +70 -1
  11. package/dist/capabilities/pipeline-executor.cap.d.ts +2 -2
  12. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +6 -6
  13. package/dist/capabilities/recording-export.cap.d.ts +7 -7
  14. package/dist/capabilities/recording.cap.d.ts +1 -1
  15. package/dist/enums/event-category.d.ts +13 -0
  16. package/dist/enums.js +1 -1
  17. package/dist/enums.mjs +1 -1
  18. package/dist/{event-category-Cdyife4p.js → event-category-39bpf1r_.js} +13 -0
  19. package/dist/{event-category-BLcNejAE.mjs → event-category-Bz24uP1U.mjs} +13 -0
  20. package/dist/generated/addon-api.d.ts +7 -0
  21. package/dist/generated/method-access-map.d.ts +1 -1
  22. package/dist/generated/system-proxy.d.ts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +148 -5
  25. package/dist/index.mjs +145 -6
  26. package/dist/interfaces/addon.d.ts +10 -2
  27. package/dist/interfaces/readiness.d.ts +5 -1
  28. package/dist/interfaces/relocate.d.ts +2 -2
  29. package/dist/lifecycle/job.d.ts +2 -2
  30. package/dist/readiness/readiness-registry.d.ts +32 -2
  31. package/dist/{sleep-Ct4Is70g.mjs → sleep-BYyv9gUM.mjs} +31 -4
  32. package/dist/{sleep-yfPaamGa.js → sleep-mkNQLVPE.js} +31 -4
  33. package/dist/types/detection.d.ts +49 -1
  34. package/dist/types/engine-output.d.ts +19 -19
  35. package/dist/types/pipeline-step.d.ts +2 -2
  36. package/package.json +2 -2
@@ -265,18 +265,18 @@ declare const CameraMotionStatusSchema: z.ZodObject<{
265
265
  }, z.core.$strip>;
266
266
  /** Detection engine provisioning state (mirrors pipeline-executor provisioning states). */
267
267
  declare const CameraDetectionProvisioningStateSchema: z.ZodEnum<{
268
- ready: "ready";
269
268
  failed: "failed";
270
269
  idle: "idle";
270
+ ready: "ready";
271
271
  installing: "installing";
272
272
  verifying: "verifying";
273
273
  }>;
274
274
  /** Detection provisioning sub-block. */
275
275
  declare const CameraDetectionProvisioningSchema: z.ZodObject<{
276
276
  state: z.ZodEnum<{
277
- ready: "ready";
278
277
  failed: "failed";
279
278
  idle: "idle";
279
+ ready: "ready";
280
280
  installing: "installing";
281
281
  verifying: "verifying";
282
282
  }>;
@@ -306,9 +306,9 @@ declare const CameraDetectionStatusSchema: z.ZodObject<{
306
306
  avgInferenceMs: z.ZodNumber;
307
307
  provisioning: z.ZodObject<{
308
308
  state: z.ZodEnum<{
309
- ready: "ready";
310
309
  failed: "failed";
311
310
  idle: "idle";
311
+ ready: "ready";
312
312
  installing: "installing";
313
313
  verifying: "verifying";
314
314
  }>;
@@ -419,9 +419,9 @@ declare const CameraStatusSchema: z.ZodObject<{
419
419
  avgInferenceMs: z.ZodNumber;
420
420
  provisioning: z.ZodObject<{
421
421
  state: z.ZodEnum<{
422
- ready: "ready";
423
422
  failed: "failed";
424
423
  idle: "idle";
424
+ ready: "ready";
425
425
  installing: "installing";
426
426
  verifying: "verifying";
427
427
  }>;
@@ -1149,9 +1149,9 @@ export declare const pipelineOrchestratorCapability: {
1149
1149
  avgInferenceMs: z.ZodNumber;
1150
1150
  provisioning: z.ZodObject<{
1151
1151
  state: z.ZodEnum<{
1152
- ready: "ready";
1153
1152
  failed: "failed";
1154
1153
  idle: "idle";
1154
+ ready: "ready";
1155
1155
  installing: "installing";
1156
1156
  verifying: "verifying";
1157
1157
  }>;
@@ -1259,9 +1259,9 @@ export declare const pipelineOrchestratorCapability: {
1259
1259
  avgInferenceMs: z.ZodNumber;
1260
1260
  provisioning: z.ZodObject<{
1261
1261
  state: z.ZodEnum<{
1262
- ready: "ready";
1263
1262
  failed: "failed";
1264
1263
  idle: "idle";
1264
+ ready: "ready";
1265
1265
  installing: "installing";
1266
1266
  verifying: "verifying";
1267
1267
  }>;
@@ -40,9 +40,9 @@ export declare const ExportOptionsSchema: z.ZodObject<{
40
40
  }, z.core.$strip>;
41
41
  export type ExportOptions = z.infer<typeof ExportOptionsSchema>;
42
42
  export declare const ExportStateSchema: z.ZodEnum<{
43
- ready: "ready";
44
43
  queued: "queued";
45
44
  failed: "failed";
45
+ ready: "ready";
46
46
  deleted: "deleted";
47
47
  rendering: "rendering";
48
48
  expired: "expired";
@@ -67,9 +67,9 @@ export declare const ExportRecordSchema: z.ZodObject<{
67
67
  title: z.ZodOptional<z.ZodString>;
68
68
  }, z.core.$strip>;
69
69
  state: z.ZodEnum<{
70
- ready: "ready";
71
70
  queued: "queued";
72
71
  failed: "failed";
72
+ ready: "ready";
73
73
  deleted: "deleted";
74
74
  rendering: "rendering";
75
75
  expired: "expired";
@@ -131,9 +131,9 @@ export declare const recordingExportCapability: {
131
131
  title: z.ZodOptional<z.ZodString>;
132
132
  }, z.core.$strip>;
133
133
  state: z.ZodEnum<{
134
- ready: "ready";
135
134
  queued: "queued";
136
135
  failed: "failed";
136
+ ready: "ready";
137
137
  deleted: "deleted";
138
138
  rendering: "rendering";
139
139
  expired: "expired";
@@ -168,9 +168,9 @@ export declare const recordingExportCapability: {
168
168
  title: z.ZodOptional<z.ZodString>;
169
169
  }, z.core.$strip>;
170
170
  state: z.ZodEnum<{
171
- ready: "ready";
172
171
  queued: "queued";
173
172
  failed: "failed";
173
+ ready: "ready";
174
174
  deleted: "deleted";
175
175
  rendering: "rendering";
176
176
  expired: "expired";
@@ -204,9 +204,9 @@ export declare const recordingExportCapability: {
204
204
  title: z.ZodOptional<z.ZodString>;
205
205
  }, z.core.$strip>;
206
206
  state: z.ZodEnum<{
207
- ready: "ready";
208
207
  queued: "queued";
209
208
  failed: "failed";
209
+ ready: "ready";
210
210
  deleted: "deleted";
211
211
  rendering: "rendering";
212
212
  expired: "expired";
@@ -241,9 +241,9 @@ export declare const recordingExportCapability: {
241
241
  title: z.ZodOptional<z.ZodString>;
242
242
  }, z.core.$strip>;
243
243
  state: z.ZodEnum<{
244
- ready: "ready";
245
244
  queued: "queued";
246
245
  failed: "failed";
246
+ ready: "ready";
247
247
  deleted: "deleted";
248
248
  rendering: "rendering";
249
249
  expired: "expired";
@@ -278,9 +278,9 @@ export declare const recordingExportCapability: {
278
278
  title: z.ZodOptional<z.ZodString>;
279
279
  }, z.core.$strip>;
280
280
  state: z.ZodEnum<{
281
- ready: "ready";
282
281
  queued: "queued";
283
282
  failed: "failed";
283
+ ready: "ready";
284
284
  deleted: "deleted";
285
285
  rendering: "rendering";
286
286
  expired: "expired";
@@ -478,9 +478,9 @@ export declare const recordingCapability: {
478
478
  readonly getRelocateStatus: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
479
479
  jobId: z.ZodString;
480
480
  state: z.ZodEnum<{
481
- running: "running";
482
481
  done: "done";
483
482
  failed: "failed";
483
+ running: "running";
484
484
  cancelled: "cancelled";
485
485
  }>;
486
486
  fromLocationId: z.ZodString;
@@ -267,6 +267,19 @@ export declare enum EventCategory {
267
267
  * without filtering on `capName`.
268
268
  */
269
269
  DeviceStateChanged = "device.state-changed",
270
+ /**
271
+ * Frame occupancy for a camera CHANGED — a tracked object was gained or
272
+ * lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
273
+ *
274
+ * Emitted only on a change, so a steady scene is silent. It exists so a
275
+ * client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
276
+ * one live badge with no push signal at all, and it cost a request every
277
+ * four seconds per visible camera.
278
+ *
279
+ * Like every event it is telemetry and may be dropped ([D8]) — a consumer
280
+ * keeps a slow reconcile rather than trusting it alone.
281
+ */
282
+ ZoneAnalyticsOccupancyChanged = "zone-analytics.occupancy-changed",
270
283
  /**
271
284
  * Cap event fired by every device that registers the `battery`
272
285
  * capability. Mirrors the cap definition's `onStatusChanged`. Carries
package/dist/enums.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_event_category = require("./event-category-Cdyife4p.js");
2
+ const require_event_category = require("./event-category-39bpf1r_.js");
3
3
  //#region src/enums/event-source-type.ts
4
4
  var EventSourceType = /* @__PURE__ */ function(EventSourceType) {
5
5
  EventSourceType["Addon"] = "addon";
package/dist/enums.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as EventCategory } from "./event-category-BLcNejAE.mjs";
1
+ import { t as EventCategory } from "./event-category-Bz24uP1U.mjs";
2
2
  //#region src/enums/event-source-type.ts
3
3
  var EventSourceType = /* @__PURE__ */ function(EventSourceType) {
4
4
  EventSourceType["Addon"] = "addon";
@@ -269,6 +269,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
269
269
  */
270
270
  EventCategory["DeviceStateChanged"] = "device.state-changed";
271
271
  /**
272
+ * Frame occupancy for a camera CHANGED — a tracked object was gained or
273
+ * lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
274
+ *
275
+ * Emitted only on a change, so a steady scene is silent. It exists so a
276
+ * client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
277
+ * one live badge with no push signal at all, and it cost a request every
278
+ * four seconds per visible camera.
279
+ *
280
+ * Like every event it is telemetry and may be dropped ([D8]) — a consumer
281
+ * keeps a slow reconcile rather than trusting it alone.
282
+ */
283
+ EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
284
+ /**
272
285
  * Cap event fired by every device that registers the `battery`
273
286
  * capability. Mirrors the cap definition's `onStatusChanged`. Carries
274
287
  * `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
@@ -269,6 +269,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
269
269
  */
270
270
  EventCategory["DeviceStateChanged"] = "device.state-changed";
271
271
  /**
272
+ * Frame occupancy for a camera CHANGED — a tracked object was gained or
273
+ * lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
274
+ *
275
+ * Emitted only on a change, so a steady scene is silent. It exists so a
276
+ * client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
277
+ * one live badge with no push signal at all, and it cost a request every
278
+ * four seconds per visible camera.
279
+ *
280
+ * Like every event it is telemetry and may be dropped ([D8]) — a consumer
281
+ * keeps a slow reconcile rather than trusting it alone.
282
+ */
283
+ EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
284
+ /**
272
285
  * Cap event fired by every device that registers the `battery`
273
286
  * capability. Mirrors the cap definition's `onStatusChanged`. Carries
274
287
  * `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
@@ -2309,6 +2309,13 @@ export type AppRouter = TrpcCoreRouter<{
2309
2309
  output: z.infer<typeof deviceManagerCapability.methods.getDeviceStatusAggregate.output>;
2310
2310
  meta: object;
2311
2311
  }>;
2312
+ getDeviceStatusAggregateBatch: TRPCQueryProcedure<{
2313
+ input: {
2314
+ [x: string]: unknown;
2315
+ } & z.input<typeof deviceManagerCapability.methods.getDeviceStatusAggregateBatch.input>;
2316
+ output: z.infer<typeof deviceManagerCapability.methods.getDeviceStatusAggregateBatch.output>;
2317
+ meta: object;
2318
+ }>;
2312
2319
  }>>;
2313
2320
  deviceOps: TRPCBuiltRouter<{
2314
2321
  ctx: TrpcContext;
@@ -6,7 +6,7 @@
6
6
  * scope+access check inside `protectedProcedure` (see
7
7
  * `server/backend/src/api/trpc/trpc.middleware.ts`).
8
8
  *
9
- * Coverage: 825 method paths across 117 capabilities.
9
+ * Coverage: 826 method paths across 117 capabilities.
10
10
  */
11
11
  import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
12
12
  export interface MethodAccessRecord {
@@ -63,7 +63,7 @@ export interface SystemProxy {
63
63
  readonly decoder: Pick<InferProvider<typeof decoderCapability>, 'supportsCodec' | 'getInfo' | 'createSession' | 'destroySession' | 'pushPacket' | 'openStream' | 'pullFrames' | 'pullHandles' | 'getFrame' | 'getShmStats' | 'updateConfig' | 'getStats' | 'listActiveSessions' | 'reprobeHwaccel'>;
64
64
  readonly deviceAdoption: Pick<InferProvider<typeof deviceAdoptionCapability>, 'listCandidateFilters' | 'listCandidates' | 'getCandidate' | 'refresh' | 'adopt' | 'release' | 'resync'>;
65
65
  readonly deviceExport: Pick<InferProvider<typeof deviceExportCapability>, 'getStatus' | 'listSupportedDeviceKinds' | 'listExposedDevices' | 'exposeDevice' | 'unexposeDevice'>;
66
- readonly deviceManager: Pick<InferProvider<typeof deviceManagerCapability>, 'allocateDeviceId' | 'registerDevice' | 'removeDevice' | 'persistConfig' | 'getRoleDisplayDefaults' | 'setRoleDisplayDefaults' | 'listLocations' | 'addLocation' | 'removeLocation' | 'listPersistedByAddon' | 'listAll' | 'getChildren' | 'removeByIntegration' | 'listWrappersForCap' | 'listBindableCapsForDeviceType' | 'discoverDevices' | 'adoptDevice' | 'getCreationSchema' | 'createDevice' | 'testCreationField' | 'adoptionListCandidateFilters' | 'adoptionListCandidates' | 'adoptionRefresh' | 'adoptionAdopt' | 'adoptionRelease' | 'adoptionResync' | 'discoveryProviders' | 'discoverAllProviders' | 'discoverProvider' | 'providerCreationType' | 'providerDiscoveryParamsSchema'>;
66
+ readonly deviceManager: Pick<InferProvider<typeof deviceManagerCapability>, 'allocateDeviceId' | 'registerDevice' | 'removeDevice' | 'persistConfig' | 'getRoleDisplayDefaults' | 'setRoleDisplayDefaults' | 'listLocations' | 'addLocation' | 'removeLocation' | 'listPersistedByAddon' | 'listAll' | 'getChildren' | 'removeByIntegration' | 'listWrappersForCap' | 'listBindableCapsForDeviceType' | 'discoverDevices' | 'adoptDevice' | 'getCreationSchema' | 'createDevice' | 'testCreationField' | 'adoptionListCandidateFilters' | 'adoptionListCandidates' | 'adoptionRefresh' | 'adoptionAdopt' | 'adoptionRelease' | 'adoptionResync' | 'discoveryProviders' | 'discoverAllProviders' | 'discoverProvider' | 'providerCreationType' | 'providerDiscoveryParamsSchema' | 'getDeviceStatusAggregateBatch'>;
67
67
  readonly deviceProvider: Pick<InferProvider<typeof deviceProviderCapability>, 'start' | 'stop' | 'getStatus' | 'getDevices' | 'supportsDiscovery' | 'discoverDevices' | 'getDiscoveryParamsSchema' | 'getManualCreationType' | 'adoptDiscoveredDevice' | 'supportsManualCreation' | 'getChildCreationSchema' | 'createDevice' | 'testCreationField'>;
68
68
  readonly deviceState: Pick<InferProvider<typeof deviceStateCapability>, 'getAllSnapshots'>;
69
69
  readonly faceGallery: Pick<InferProvider<typeof faceGalleryCapability>, 'listIdentities' | 'createIdentity' | 'renameIdentity' | 'deleteIdentity' | 'listIdentitySamples' | 'removeSample' | 'listRecentFaces' | 'getFaceMedia' | 'assignFace' | 'unassignFace' | 'deleteFace' | 'assignFaces' | 'unassignFaces' | 'suggestFaceClusters'>;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export * from './types/config.js';
8
8
  export * from './types/entities.js';
9
9
  export * from './types/models.js';
10
10
  export * from './types/model-variant-groups.js';
11
- export type { EngineOutput, LetterboxMeta, ModelInputMeta } from './types/engine-output.js';
11
+ export type { EngineOutput } from './types/engine-output.js';
12
12
  export * from './types/pipeline.js';
13
13
  export * from './types/pipeline-step.js';
14
14
  export type { CameraPipelineConfig, PipelineTemplate as CameraPipelineTemplate, } from './types/camera-pipeline.js';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-yfPaamGa.js");
3
- const require_event_category = require("./event-category-Cdyife4p.js");
2
+ const require_sleep = require("./sleep-mkNQLVPE.js");
3
+ const require_event_category = require("./event-category-39bpf1r_.js");
4
4
  const require_enums = require("./enums.js");
5
5
  const require_err_msg = require("./err-msg-COpsHMw2.js");
6
6
  let zod = require("zod");
@@ -4758,6 +4758,29 @@ var NcOccupancyConditionSchema = zod.z.object({
4758
4758
  count: zod.z.number().int().min(0).default(1),
4759
4759
  sustainSeconds: zod.z.number().int().min(0).max(3600).default(15)
4760
4760
  });
4761
+ /**
4762
+ * Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
4763
+ *
4764
+ * The values are not symmetric, and deliberately so — the absent value has to
4765
+ * mean exactly what every rule authored before this condition existed already
4766
+ * does:
4767
+ * - `enter` — entries and every NON-crossing record (movement state,
4768
+ * package, sensor). Exits are rejected. **This is the absent behaviour**:
4769
+ * an operator who never asked for exits must not start receiving them.
4770
+ * - `exit` — ONLY an exit crossing. A record that is not a crossing at all
4771
+ * fails closed, because "the car left the drive" is a question about a
4772
+ * boundary, not about a detection.
4773
+ * - `any` — no direction filter; entries, exits and non-crossings alike.
4774
+ *
4775
+ * A rule asking for a direction should normally also scope `zones`, which the
4776
+ * engine evaluates against the crossed zone as well as the current membership
4777
+ * (an exit's membership no longer contains the zone it just left).
4778
+ */
4779
+ var NcCrossingSchema = zod.z.enum([
4780
+ "enter",
4781
+ "exit",
4782
+ "any"
4783
+ ]);
4761
4784
  /** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
4762
4785
  var NcZoneConditionSchema = zod.z.object({
4763
4786
  ids: zod.z.array(zod.z.string().min(1)).min(1),
@@ -4782,6 +4805,13 @@ var NcConditionsSchema = zod.z.object({
4782
4805
  /** Veto zones — any hit fails the rule. */
4783
4806
  zonesExclude: zod.z.array(zod.z.string().min(1)).optional(),
4784
4807
  /**
4808
+ * Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
4809
+ * and a closed track carries none, so a `track-end` rule asking for one
4810
+ * fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
4811
+ * which is exactly today's behaviour. See {@link NcCrossingSchema}.
4812
+ */
4813
+ crossing: NcCrossingSchema.optional(),
4814
+ /**
4785
4815
  * Exact (case-insensitive) match on the record's collapsed `label`
4786
4816
  * (identity name / plate text / subclass).
4787
4817
  */
@@ -4970,11 +5000,31 @@ var NcMediaPolicySchema = zod.z.object({
4970
5000
  */
4971
5001
  profile: require_sleep.CamProfileSchema.optional()
4972
5002
  });
5003
+ /**
5004
+ * Cooldown GRANULARITY over the subject's class — how much a fired
5005
+ * notification suppresses.
5006
+ * - `shared` (default, and the absent value) — one window for the whole
5007
+ * rule/scope: a cat silences the next dog for `cooldownSec`.
5008
+ * - `per-class` — an independent window per detected class, so cat→dog fires
5009
+ * at once and cat→cat still waits.
5010
+ *
5011
+ * AUDIO subjects are ALWAYS per-class regardless of this setting: a scream
5012
+ * must not be swallowed by a bark's window (the precedent this generalizes —
5013
+ * see `cooldownKey` in the rule engine).
5014
+ */
5015
+ var NcThrottleGranularitySchema = zod.z.enum(["shared", "per-class"]);
4973
5016
  /** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
4974
5017
  var NcThrottleSchema = zod.z.object({
4975
5018
  cooldownSec: zod.z.number().int().min(0).max(86400).default(60),
4976
5019
  /** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
4977
- scope: zod.z.enum(["rule", "rule-device"]).default("rule-device")
5020
+ scope: zod.z.enum(["rule", "rule-device"]).default("rule-device"),
5021
+ /**
5022
+ * Class granularity of the cooldown key. Optional rather than defaulted:
5023
+ * a Zod default does NOT run on the addon→addon cap path, so a persisted
5024
+ * rule authored before this field simply carries none — and the engine
5025
+ * reads absent as `shared`, the pre-existing behaviour.
5026
+ */
5027
+ granularity: NcThrottleGranularitySchema.optional()
4978
5028
  });
4979
5029
  /** Client-supplied rule fields (server stamps id/createdBy/createdAt/updatedAt). */
4980
5030
  var NcRuleInputSchema = zod.z.object({
@@ -5082,6 +5132,7 @@ var NcConditionDescriptorSchema = zod.z.object({
5082
5132
  "schedule",
5083
5133
  "plateMatcher",
5084
5134
  "packagePhase",
5135
+ "crossingSelect",
5085
5136
  "polygonDraw",
5086
5137
  "occupancy"
5087
5138
  ]),
@@ -5186,6 +5237,16 @@ var NC_CONDITION_CATALOG = [
5186
5237
  ],
5187
5238
  phase: "P1"
5188
5239
  },
5240
+ {
5241
+ id: "crossing",
5242
+ group: "zones",
5243
+ label: "Zone crossing",
5244
+ valueType: "crossingSelect",
5245
+ operator: "in",
5246
+ appliesTo: ["immediate"],
5247
+ phase: "P1",
5248
+ description: "Direction of the zone crossing: enter (the default, and what every rule authored before this did) / exit / any. An exit rule matches only crossings."
5249
+ },
5189
5250
  {
5190
5251
  id: "labelEquals",
5191
5252
  group: "label",
@@ -10402,6 +10463,18 @@ var motionCapability = {
10402
10463
  name: "motion",
10403
10464
  scope: "device",
10404
10465
  mode: "singleton",
10466
+ /**
10467
+ * Providers register per-device natives via `ctx.registerNativeCap`
10468
+ * (Hikvision/Reolink/Amcrest/Wyze/HA/Homematic/Alexa/Matter) — there is
10469
+ * NO system singleton provider. Without this flag `resolveCapMount`
10470
+ * derived `{ kind: 'singleton' }`, so `motion.getStatus`/`isDetected`
10471
+ * resolved via `registry.getSingleton('motion')` (always null) and every
10472
+ * call 412'd "provider not available" while bindings listed a live
10473
+ * `motion` native (2026-08-02). The flag routes the router through
10474
+ * `requireDeviceScoped` → `getProviderForDevice`, like `motion-trigger`,
10475
+ * `snapshot` and every other per-device native cap.
10476
+ */
10477
+ deviceNative: true,
10405
10478
  deviceTypes: [require_sleep.DeviceType.Camera, require_sleep.DeviceType.Sensor],
10406
10479
  methods: {
10407
10480
  /**
@@ -14586,7 +14659,8 @@ function createSystemProxy(api) {
14586
14659
  discoverAllProviders: (input) => dispatch("deviceManager", "discoverAllProviders", "mutation", input),
14587
14660
  discoverProvider: (input) => dispatch("deviceManager", "discoverProvider", "mutation", input),
14588
14661
  providerCreationType: (input) => dispatch("deviceManager", "providerCreationType", "query", input),
14589
- providerDiscoveryParamsSchema: (input) => dispatch("deviceManager", "providerDiscoveryParamsSchema", "query", input)
14662
+ providerDiscoveryParamsSchema: (input) => dispatch("deviceManager", "providerDiscoveryParamsSchema", "query", input),
14663
+ getDeviceStatusAggregateBatch: (input) => dispatch("deviceManager", "getDeviceStatusAggregateBatch", "query", input)
14590
14664
  },
14591
14665
  deviceProvider: {
14592
14666
  start: (input) => dispatch("deviceProvider", "start", "mutation", input),
@@ -18603,7 +18677,29 @@ var deviceManagerCapability = {
18603
18677
  getDeviceStatusAggregate: require_sleep.method(zod.z.object({
18604
18678
  deviceId: zod.z.number(),
18605
18679
  caps: zod.z.array(zod.z.string()).readonly().optional()
18606
- }), zod.z.record(zod.z.string(), zod.z.unknown().nullable()))
18680
+ }), zod.z.record(zod.z.string(), zod.z.unknown().nullable())),
18681
+ /**
18682
+ * The same aggregate, for a LIST of devices in one round-trip.
18683
+ *
18684
+ * The viewer's camera list is the caller this exists for. Each card asked
18685
+ * for its own badges — battery here, recording mode there — so a ten-camera
18686
+ * install issued N separate procedures per reconcile, each its own message
18687
+ * on the one WebSocket that also carries the WebRTC signalling (the client
18688
+ * has no `httpBatchLink`, so there is no transport-level batching to lean
18689
+ * on: collapsing has to happen at the procedure level, which is here).
18690
+ *
18691
+ * Keyed by device id as a STRING — a JSON object cannot key by number, and
18692
+ * pretending otherwise is how a record survives the wire only in tests.
18693
+ * The per-device value is exactly what `getDeviceStatusAggregate` returns,
18694
+ * so a caller can move between the two without reshaping anything.
18695
+ *
18696
+ * `caps` matters more here than in the single call: a client that needs two
18697
+ * caps should not pay for every status-carrying cap × every device.
18698
+ */
18699
+ getDeviceStatusAggregateBatch: require_sleep.method(zod.z.object({
18700
+ deviceIds: zod.z.array(zod.z.number()).readonly(),
18701
+ caps: zod.z.array(zod.z.string()).readonly().optional()
18702
+ }), zod.z.record(zod.z.string(), zod.z.record(zod.z.string(), zod.z.unknown().nullable())))
18607
18703
  }
18608
18704
  };
18609
18705
  //#endregion
@@ -20377,6 +20473,37 @@ var MotionEventSchema = zod.z.object({
20377
20473
  * Absent on legacy rows ⇒ treat as `pipeline`.
20378
20474
  */
20379
20475
  var DetectionSourceSchema = zod.z.enum(["pipeline", "onboard"]);
20476
+ /**
20477
+ * Which WAY a subject crossed a zone boundary. An entry and an exit are two
20478
+ * different notifications ("the parcel arrived" / "the car left the drive"),
20479
+ * and until this existed they were indistinguishable on the persisted record —
20480
+ * which is why exits were computed and dropped at the emit boundary rather
20481
+ * than doubling every zone-scoped rule.
20482
+ */
20483
+ var ZoneCrossingDirectionSchema = zod.z.enum(["enter", "exit"]);
20484
+ /**
20485
+ * The confirmed zone crossing that produced an object event. Present ONLY on
20486
+ * an event emitted BY a crossing (`zone.enter` / `zone.exit`); a movement-state
20487
+ * event (`object.entering` / `leaving` / `stationary` / `loitering`) and an
20488
+ * appearance event carry none, so a rule asking for a direction fails closed
20489
+ * on them.
20490
+ *
20491
+ * Exactly ONE crossing per event: the emitter turns each confirmed crossing
20492
+ * into its own event, so a frame in which a track enters A while leaving B
20493
+ * produces two events with two directions — never one ambiguous row.
20494
+ *
20495
+ * `zoneId` is load-bearing for an EXIT: the event's `zones` list is the
20496
+ * membership the box has NOW, and by definition it no longer contains the zone
20497
+ * that was just left. Without the id here, a zone-scoped rule could never match
20498
+ * the exit it asked for.
20499
+ */
20500
+ var ZoneCrossingSchema = zod.z.object({
20501
+ direction: ZoneCrossingDirectionSchema,
20502
+ /** Admin zone id crossed. */
20503
+ zoneId: zod.z.string(),
20504
+ /** Zone display name at crossing time (falls back to the id). */
20505
+ zoneName: zod.z.string().optional()
20506
+ });
20380
20507
  var ObjectEventSchema = zod.z.object({
20381
20508
  ...BaseEventFields,
20382
20509
  kind: zod.z.literal("object"),
@@ -20403,6 +20530,12 @@ var ObjectEventSchema = zod.z.object({
20403
20530
  zones: zod.z.array(zod.z.string()).readonly().optional(),
20404
20531
  /** Omitted in slim projection. */
20405
20532
  state: TrackStateSchema.optional(),
20533
+ /**
20534
+ * The zone crossing this event IS, when it is one. Absent on every other
20535
+ * event kind (movement state, appearance, package) — see
20536
+ * {@link ZoneCrossingSchema}. Omitted in slim projection.
20537
+ */
20538
+ zoneCrossing: ZoneCrossingSchema.optional(),
20406
20539
  /** Detection-frame dimensions in pixels — let consumers normalize the
20407
20540
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
20408
20541
  frameWidth: zod.z.number().optional(),
@@ -28799,6 +28932,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
28799
28932
  addonId: null,
28800
28933
  access: "view"
28801
28934
  },
28935
+ "deviceManager.getDeviceStatusAggregateBatch": {
28936
+ capName: "device-manager",
28937
+ capScope: "system",
28938
+ addonId: null,
28939
+ access: "view"
28940
+ },
28802
28941
  "deviceManager.getLinkedDevices": {
28803
28942
  capName: "device-manager",
28804
28943
  capScope: "system",
@@ -33789,6 +33928,7 @@ exports.NativeObjectDetectionRuntimeStateSchema = NativeObjectDetectionRuntimeSt
33789
33928
  exports.NativeObjectDetectionStatusSchema = NativeObjectDetectionStatusSchema;
33790
33929
  exports.NcConditionDescriptorSchema = NcConditionDescriptorSchema;
33791
33930
  exports.NcConditionsSchema = NcConditionsSchema;
33931
+ exports.NcCrossingSchema = NcCrossingSchema;
33792
33932
  exports.NcDeliverySchema = NcDeliverySchema;
33793
33933
  exports.NcHistoryEntrySchema = NcHistoryEntrySchema;
33794
33934
  exports.NcHistoryFilterSchema = NcHistoryFilterSchema;
@@ -33808,6 +33948,7 @@ exports.NcScheduleWindowSchema = NcScheduleWindowSchema;
33808
33948
  exports.NcTaxonomyEntrySchema = NcTaxonomyEntrySchema;
33809
33949
  exports.NcTaxonomySchema = NcTaxonomySchema;
33810
33950
  exports.NcTestResultSchema = NcTestResultSchema;
33951
+ exports.NcThrottleGranularitySchema = NcThrottleGranularitySchema;
33811
33952
  exports.NcThrottleSchema = NcThrottleSchema;
33812
33953
  exports.NcZoneConditionSchema = NcZoneConditionSchema;
33813
33954
  exports.NetworkAccessStatusSchema = NetworkAccessStatusSchema;
@@ -34061,6 +34202,8 @@ exports.WidgetMetadataSchema = WidgetMetadataSchema;
34061
34202
  exports.WidgetRemoteSchema = WidgetRemoteSchema;
34062
34203
  exports.WidgetSizeEnum = WidgetSizeEnum;
34063
34204
  exports.YAMNET_TO_MACRO = YAMNET_TO_MACRO;
34205
+ exports.ZoneCrossingDirectionSchema = ZoneCrossingDirectionSchema;
34206
+ exports.ZoneCrossingSchema = ZoneCrossingSchema;
34064
34207
  exports.ZoneKindEnum = ZoneKindEnum;
34065
34208
  exports.ZoneRuleModeEnum = ZoneRuleModeEnum;
34066
34209
  exports.ZoneRuleSchema = ZoneRuleSchema;