@camstack/types 1.2.280 → 1.2.282

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.
@@ -201,6 +201,59 @@ export interface NcRuleSectionSubject {
201
201
  readonly delivery: string;
202
202
  readonly conditions: NcRuleConditionsSubject;
203
203
  }
204
+ /**
205
+ * Which capability a device must carry to be OFFERED on a rule of this kind's
206
+ * device-scope picker (operator ruling, 2026-10-01). `null` means "no
207
+ * capability filter for this kind" — either every device applies (the system
208
+ * families, each already a separate concern; see
209
+ * `docs/architecture/notifications.md`'s D637 `deviceIds` table) or `mixed`,
210
+ * which authors nothing.
211
+ *
212
+ * DERIVED, never a hand-picked list:
213
+ * - `sensor` reads `EVENTFUL_CAP_NAMES` — the SAME cap table the engine
214
+ * itself turns a linked device's bound caps into sensor event kinds with
215
+ * (`EVENT_KIND_BY_CAP`). A device this picker offers for a sensor rule is
216
+ * exactly a device the rule's `sensorKinds` condition could ever name.
217
+ * - `detection` (which a package-event rule is — there is no separate
218
+ * `package` kind, D637) / `occupancy` read the one pipeline cap a camera
219
+ * needs to produce the detections / counts / parcels those kinds match on.
220
+ * - `sound` reads the one cap a device needs to produce the audio metrics a
221
+ * sound rule's sampling window is built from.
222
+ * - `device-events` / `system` / `alarm` / `mixed` are `null`: a device
223
+ * event rule's `deviceIds` legitimately spans every device type (liveness,
224
+ * battery, consumable, `detection-blind`), a system rule has no device
225
+ * scope at all (dropped from the editor's tabs), and `alarm`'s `deviceIds`
226
+ * is a reference to whichever camera's rule set it off — not a scope this
227
+ * picker authors.
228
+ *
229
+ * Callers resolve the ids via `deviceManager.listDeviceIdsByCaps` (max 16
230
+ * names — `EVENTFUL_CAP_NAMES` is exactly 16) and must treat an unanswered
231
+ * read as "unknown", never as "no devices" (D315): this function only names
232
+ * WHICH caps to ask for, not what to show while the answer is pending.
233
+ */
234
+ export declare function ruleDeviceCompatCapNames(kind: NcRuleKind): readonly string[] | null;
235
+ /**
236
+ * The capability every CAMERA carries: `camera-streams` is a `defaultActive`
237
+ * wrapper bound to every `Camera`-type device (`camera-streams.cap.ts`).
238
+ * Named once, because a sensor rule's compatible set needs it (below).
239
+ */
240
+ export declare const NC_CAMERA_SCOPE_CAP_NAME = "camera-streams";
241
+ /**
242
+ * Every capability QUERY whose union is the set of devices a rule of this kind
243
+ * may be SCOPED to (`conditions.devices`) — what the save-time guard and the
244
+ * admin's Devices tab ask `deviceManager.listDeviceIdsByCaps`, one call per
245
+ * entry. `null` exactly where {@link ruleDeviceCompatCapNames} is `null`.
246
+ *
247
+ * Several queries rather than one list because `listDeviceIdsByCaps` takes at
248
+ * most 16 names and `EVENTFUL_CAP_NAMES` is already exactly 16.
249
+ *
250
+ * A `sensor` rule's set is the eventful devices PLUS every camera (fix round
251
+ * 1, 2026-10-01): the engine matches a sensor rule scoped to a CAMERA — a
252
+ * per-camera row carries the camera's id, and a linked set matches on
253
+ * `rowCameraIds` (D630 §6) — so a camera-scoped sensor rule is legitimate and
254
+ * a guard that refused it would make every such stored rule un-editable.
255
+ */
256
+ export declare function ruleDeviceCompatCapQueries(kind: NcRuleKind): readonly (readonly string[])[] | null;
204
257
  /**
205
258
  * Which kind of rule is this?
206
259
  *
@@ -279,7 +332,7 @@ export declare function droppedConditionsForKind(conditions: NcAuthoredCondition
279
332
  * the stored system rules that span families. `mixed` is a real, owning section
280
333
  * (a rule must be listed somewhere) that nothing can CREATE into.
281
334
  */
282
- export type NcRuleSectionKey = 'all' | 'detection' | 'audio' | 'occupancy' | 'device-events' | 'system' | 'alarm' | 'mixed';
335
+ export type NcRuleSectionKey = 'all' | 'detection' | 'sensor' | 'audio' | 'occupancy' | 'device-events' | 'system' | 'alarm' | 'mixed';
283
336
  export interface NcRuleSection {
284
337
  readonly key: NcRuleSectionKey;
285
338
  /** English fallback; the viewer maps `key` onto an i18n key. */
@@ -308,15 +361,20 @@ export declare function isOccupancyRule(subject: NcRuleSectionSubject): boolean;
308
361
  * `all` always matches — a section that hides a rule is how an operator
309
362
  * concludes it was deleted. The others PARTITION the list: sound and
310
363
  * occupancy are claimed by their condition, a system-event rule by its trigger
311
- * and then by the family of its event kinds (or `mixed`, D637), and
312
- * everything left over — including a trigger this build has never heard of —
313
- * counts as a detection rule so it stays visible somewhere.
314
- *
315
- * Keyed on the CONDITION for two of them, because the trigger alone cannot
316
- * answer: a sound rule is `immediate` and an occupancy rule is `device-event`,
317
- * and in each case the condition is the discriminator the engine itself uses.
318
- * A section keyed on delivery would put both back in the pile they are
319
- * invisible in.
364
+ * and then by the family of its event kinds (or `mixed`, D637), `sensor`
365
+ * claims the `device-event` trigger that occupancy did not (operator ruling,
366
+ * 2026-10-01 — a doorbell press used to fall into `detection` for want of its
367
+ * own section, which is the "everything mixed together" the viewer's
368
+ * `ruleKindOf`-based list had already fixed and the admin's section strip had
369
+ * not), and everything left over — including a trigger this build has never
370
+ * heard of — counts as a detection rule so it stays visible somewhere.
371
+ *
372
+ * Keyed on the CONDITION for sound and occupancy, because the trigger alone
373
+ * cannot answer: a sound rule is `immediate` and an occupancy rule is
374
+ * `device-event`, and in each case the condition is the discriminator the
375
+ * engine itself uses. `sensor` IS keyed on the trigger, same as `ruleKindOf`'s
376
+ * `'sensor'` kind — a device-event subject with no occupancy condition is a
377
+ * sensor rule, full stop.
320
378
  */
321
379
  export declare function ruleMatchesSection(subject: NcRuleSectionSubject, section: NcRuleSectionKey): boolean;
322
380
  /** The ONE real section a rule lives in — `all` holds everything and is not it. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.280",
3
+ "version": "1.2.282",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",