@camstack/system 1.2.299 → 1.2.301

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 (55) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/autotrack/index.js +1 -1
  8. package/dist/builtins/autotrack/index.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/camera-grid/index.js +1 -1
  12. package/dist/builtins/camera-grid/index.mjs +1 -1
  13. package/dist/builtins/console-logging/index.js +1 -1
  14. package/dist/builtins/console-logging/index.mjs +1 -1
  15. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  16. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  17. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  18. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  19. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  20. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  21. package/dist/builtins/hub-forwarder/index.js +1 -1
  22. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  23. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  24. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  25. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  26. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  27. package/dist/builtins/local-network/local-network.addon.js +1 -1
  28. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  29. package/dist/builtins/loki-logging/index.js +1 -1
  30. package/dist/builtins/loki-logging/index.mjs +1 -1
  31. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  32. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  33. package/dist/builtins/platform-probe/index.js +1 -1
  34. package/dist/builtins/platform-probe/index.mjs +1 -1
  35. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  36. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  37. package/dist/builtins/snapshot/index.js +1 -1
  38. package/dist/builtins/snapshot/index.mjs +1 -1
  39. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  40. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  41. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  42. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  43. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  44. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  45. package/dist/builtins/system-config/system-config.addon.js +1 -1
  46. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  47. package/dist/builtins/winston-logging/index.js +1 -1
  48. package/dist/builtins/winston-logging/index.mjs +1 -1
  49. package/dist/{dist-BoYDYdae.mjs → dist-C4qebjgF.mjs} +218 -11
  50. package/dist/{dist-B_U69lgJ.js → dist-Dz1Hoc8h.js} +218 -11
  51. package/dist/index.js +1 -1
  52. package/dist/index.mjs +1 -1
  53. package/dist/{retired-settings-keys-CffDz4qX.mjs → retired-settings-keys-CgCVRYZx.mjs} +1 -1
  54. package/dist/{retired-settings-keys-CVUkMN5T.js → retired-settings-keys-DjzlOaqH.js} +1 -1
  55. package/package.json +1 -1
@@ -691,7 +691,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
691
691
  return EventCategory;
692
692
  }({});
693
693
  //#endregion
694
- //#region ../types/dist/sleep-D_4W7xuQ.mjs
694
+ //#region ../types/dist/sleep-DU7mu4wb.mjs
695
695
  /**
696
696
  * The audio chunk plane's byte format, and the ONE expansion from a coded
697
697
  * window to float samples (D455).
@@ -16866,6 +16866,9 @@ var NcSystemEventKindSchema = zod.z.enum([
16866
16866
  "device-battery-normal",
16867
16867
  "device-consumable-low",
16868
16868
  "device-consumable-normal",
16869
+ "device-tank-low",
16870
+ "device-tank-full",
16871
+ "device-tank-normal",
16869
16872
  "stream-online",
16870
16873
  "stream-offline",
16871
16874
  "node-online",
@@ -16936,7 +16939,22 @@ var NcSystemEventConditionSchema = zod.z.object({
16936
16939
  */
16937
16940
  excludeDeviceIds: zod.z.array(zod.z.number().int()).min(1).optional(),
16938
16941
  nodeIds: zod.z.array(zod.z.string().min(1)).min(1).optional(),
16939
- packageNames: zod.z.array(zod.z.string().min(1)).min(1).optional()
16942
+ packageNames: zod.z.array(zod.z.string().min(1)).min(1).optional(),
16943
+ /**
16944
+ * At or below this remaining-life %, a consumable is LOW for THIS rule
16945
+ * (D642). Absent = {@link NC_CONSUMABLE_LOW_PERCENT_DEFAULT}; at most
16946
+ * {@link NC_CONSUMABLE_LOW_PERCENT_MAX}, so every episode can recover. Scoped to the
16947
+ * consumable kinds (`systemEventFilterApplies`) and to the device-events
16948
+ * family; ignored on every other kind.
16949
+ *
16950
+ * It is a property of the RULE because the operator decided so: a rule at
16951
+ * 25 must be told about a filter at 20 %, a rule at 10 must not. The hub
16952
+ * keeps one episode per (threshold, device, item) — its own hysteresis, its
16953
+ * own reminder — and a rule hears only the episode judged at ITS threshold,
16954
+ * exactly as an occupancy rule hears only the edge of its own count. A
16955
+ * provider's own `replace` verdict is low at every threshold.
16956
+ */
16957
+ consumableLowPercent: zod.z.number().int().min(1).max(95).optional()
16940
16958
  });
16941
16959
  /** Hard ceiling on a window (24h). A snooze that could not expire would be an
16942
16960
  * outage the operator asked for once and forgot. */
@@ -17081,6 +17099,16 @@ var NcCrossingSchema = zod.z.enum([
17081
17099
  "exit",
17082
17100
  "any"
17083
17101
  ]);
17102
+ /**
17103
+ * Which edge of a BOOLEAN sensor fires a device-event rule (D640).
17104
+ * - `raised` — the sensor went high: water detected, smoke, open, tampered.
17105
+ * - `cleared` — it went back: dry, clear, closed.
17106
+ * - absent — both edges, which is what every rule authored before this did.
17107
+ *
17108
+ * There is no third member for "both": absence already says it, and a value
17109
+ * that means the same as absence is a second way to write one rule.
17110
+ */
17111
+ var NcSensorTransitionSchema = zod.z.enum(["raised", "cleared"]);
17084
17112
  /** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
17085
17113
  var NcZoneConditionSchema = zod.z.object({
17086
17114
  ids: zod.z.array(zod.z.string().min(1)).min(1),
@@ -17270,6 +17298,20 @@ var NcConditionsSchema = zod.z.object({
17270
17298
  scene: NcSceneConditionSchema.optional(),
17271
17299
  /** Device scope — absent = all devices. */
17272
17300
  devices: zod.z.array(zod.z.number()).optional(),
17301
+ /**
17302
+ * Device EXCLUSION (D641) — "every device except these". Judged on the SAME
17303
+ * subject ids {@link devices} is judged on (the camera, the sensor that
17304
+ * fired, a linked set's sensor and row cameras), so a sensor fanned out per
17305
+ * linked camera is excluded exactly where an include would have tested it.
17306
+ * `min(1)`: an empty exclusion excludes nothing and is written as absent.
17307
+ *
17308
+ * Not for `system-event` rules — those carry their own
17309
+ * `systemEvent.excludeDeviceIds` (D636), and the hub refuses this key there.
17310
+ * Editors present the two lists as ONE field (All | Only these | All except
17311
+ * these); the engine evaluates each independently, so a legacy rule
17312
+ * carrying both still means "these, minus those".
17313
+ */
17314
+ devicesExclude: zod.z.array(zod.z.number()).min(1).optional(),
17273
17315
  /** Detector class names (any overlap with the record's class set). */
17274
17316
  classes: zod.z.array(zod.z.string().min(1)).optional(),
17275
17317
  /** Veto classes — any overlap fails the rule. */
@@ -17403,6 +17445,16 @@ var NcConditionsSchema = zod.z.object({
17403
17445
  */
17404
17446
  sensorKinds: zod.z.array(zod.z.string().min(1)).optional(),
17405
17447
  /**
17448
+ * DEVICE-EVENT only (D640). Fire on one edge of a boolean sensor —
17449
+ * {@link NcSensorTransitionSchema}. Which field of the slice means "raised"
17450
+ * is `@camstack/types` → `notification/sensor-raised.ts`. A reading the
17451
+ * engine cannot place (a kind with no raise, an unreadable slice) PASSES:
17452
+ * the condition fails open towards notifying, never towards silence. Editors
17453
+ * offer it only when every chosen {@link sensorKinds} member has a raise
17454
+ * (`sensorTransitionOffered`), and the hub refuses it on any other delivery.
17455
+ */
17456
+ sensorTransition: NcSensorTransitionSchema.optional(),
17457
+ /**
17406
17458
  * PACKAGE-EVENT only. Which package phase fires the rule — `delivered`
17407
17459
  * (a parked parcel appeared), `picked-up` (it departed), or `both`. Fails
17408
17460
  * when the subject's phase does not match (a subject always carries a phase
@@ -18023,6 +18075,7 @@ var NcConditionDescriptorSchema = zod.z.object({
18023
18075
  /** Editor widget the UI renders — never hardcode per-condition forms. */
18024
18076
  valueType: zod.z.enum([
18025
18077
  "deviceIdList",
18078
+ "deviceIdExcludeList",
18026
18079
  "stringList",
18027
18080
  "number01",
18028
18081
  "number",
@@ -18033,6 +18086,7 @@ var NcConditionDescriptorSchema = zod.z.object({
18033
18086
  "plateMatcher",
18034
18087
  "packagePhase",
18035
18088
  "crossingSelect",
18089
+ "sensorTransition",
18036
18090
  "polygonDraw",
18037
18091
  "occupancy",
18038
18092
  "audio",
@@ -18183,6 +18237,39 @@ var NcHistoryFilterSchema = zod.z.object({
18183
18237
  limit: zod.z.number().int().min(1).max(500).default(100)
18184
18238
  });
18185
18239
  /**
18240
+ * The newest delivery row of ONE rule — the "Last run" of a rules table.
18241
+ *
18242
+ * A projection of the same outbox rows `getHistory` returns, so it records
18243
+ * DELIVERIES only: a throttled or unmatched evaluation never produced a row
18244
+ * and is not a run here. When one fire reached several targets (several rows
18245
+ * at the same `lastAt`), `status` is the least successful of them
18246
+ * (`dead` > `pending` > `sent`): "the last run delivered" must be true for
18247
+ * every target it names.
18248
+ */
18249
+ var NcRuleLastRunSchema = zod.z.object({
18250
+ ruleId: zod.z.string(),
18251
+ /** Fire time of the newest row (`createdAt`, epoch ms). */
18252
+ lastAt: zod.z.number(),
18253
+ status: NcHistoryStatusSchema,
18254
+ /** The camera/device of that row (a digest row files under its first camera). */
18255
+ deviceId: zod.z.number()
18256
+ });
18257
+ /**
18258
+ * Every rule's last run, in one answer.
18259
+ *
18260
+ * A rule ABSENT from `runs` produced no delivery inside `horizonMs` — how far
18261
+ * back this answer looked, in ms before the hub's now. It is the outbox prune
18262
+ * window (7 days by default, operator-configurable), NARROWED when the read hit
18263
+ * its row bound: the answer never claims a window it did not read. `null` means
18264
+ * the operator keeps the outbox forever AND the read reached its end, so absent
18265
+ * means "never on record". A UI derives its "not in the last N days" from this
18266
+ * value, never from a constant — and only when the call ANSWERED (D315).
18267
+ */
18268
+ var NcRuleLastRunsSchema = zod.z.object({
18269
+ runs: zod.z.array(NcRuleLastRunSchema),
18270
+ horizonMs: zod.z.number().nonnegative().nullable()
18271
+ });
18272
+ /**
18186
18273
  * What a snooze covers. Broader scopes win when several overlap, so one window
18187
18274
  * leaves ONE digest rather than a rule snooze and a whole-feed snooze both
18188
18275
  * summarising the same silence.
@@ -18368,6 +18455,14 @@ var NcAlarmModeCoverageSchema = zod.z.object({
18368
18455
  /** Ids named by the covering rules. A SUBSET when `allDevices` is true. */
18369
18456
  deviceIds: zod.z.array(zod.z.number().int()),
18370
18457
  /**
18458
+ * D641: the ids NOT covered although `allDevices` is true — every unscoped
18459
+ * covering rule EXCLUDES them (`conditions.devicesExclude`) and no named rule
18460
+ * covers them. Always `[]` when `allDevices` is false. Excluded by the rules,
18461
+ * which is not the same as skipped by a switch: never in `skippedDevices`.
18462
+ * Defaulted so an answer computed before this field parses as "none".
18463
+ */
18464
+ allDevicesExcept: zod.z.array(zod.z.number().int()).default([]),
18465
+ /**
18371
18466
  * Devices this mode NAMES but cannot actually arm, each with the switch that
18372
18467
  * excludes it.
18373
18468
  *
@@ -18591,6 +18686,15 @@ var notificationRulesCapability = {
18591
18686
  */
18592
18687
  getHistory: method(zod.z.object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), zod.z.object({ entries: zod.z.array(NcHistoryEntrySchema) }), { auth: "admin" }),
18593
18688
  /**
18689
+ * The newest delivery of every rule, in ONE bounded read of the outbox —
18690
+ * the "Last run" column. Never a `getHistory` per rule. A rule with no
18691
+ * delivery inside `horizonMs` is absent from `runs`; see
18692
+ * {@link NcRuleLastRunsSchema} for what absent means. A store that cannot
18693
+ * answer FAILS the call rather than answering "nothing ran". Admin-only,
18694
+ * like `getHistory`, of which it is a projection.
18695
+ */
18696
+ getRuleLastRuns: method(zod.z.object({}), NcRuleLastRunsSchema, { auth: "admin" }),
18697
+ /**
18594
18698
  * Mint a fresh, externally-reachable URL for one artefact a history row
18595
18699
  * named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
18596
18700
  * signed-link mechanism the dispatcher uses to attach media to an
@@ -24569,7 +24673,11 @@ function buildDescriptor(capName, kind) {
24569
24673
  icon: legacyIcon(t.iconId)
24570
24674
  };
24571
24675
  }
24572
- Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
24676
+ /**
24677
+ * Sensor / control cap name → static event-kind descriptor. A linked device
24678
+ * contributes one entry per bound cap present in this map.
24679
+ */
24680
+ var EVENT_KIND_BY_CAP = Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
24573
24681
  /**
24574
24682
  * server-management — per-NODE singleton capability for a node's ROOT
24575
24683
  * package lifecycle (runtime-updatable node packages).
@@ -29878,12 +29986,20 @@ reset: method(zod.z.object({
29878
29986
  },
29879
29987
  runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: zod.z.number() }),
29880
29988
  /**
29881
- * Runtime-state durability: **session** — the authority is the appliance; the provider re-reads the whole item array on connect.
29989
+ * Runtime-state durability: **restored** — nothing else holds the value
29990
+ * (D642). A consumable can often be read only in a device's wake window (the
29991
+ * Dreame mower's CMS counters answer only while it charges), so a restart
29992
+ * that wiped the slice left the panel empty and the alerts blind until the
29993
+ * next wake — 2026-09-26, mower 503 idle with `items: []`. A restored item is
29994
+ * the previous observation, not a claim about now; the provider overwrites it
29995
+ * the moment it reads the device again.
29882
29996
  *
29883
29997
  * See `RuntimeStateDurability`. Enforced by
29884
29998
  * `scripts/check-runtime-state-durability.ts`.
29885
29999
  */
29886
- durability: "session"
30000
+ durability: "restored",
30001
+ /** Clocks, not content: a re-read that changed no item costs no commit. */
30002
+ volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
29887
30003
  };
29888
30004
  /**
29889
30005
  * Door / window / opening / garage / valve contact sensor. Boolean
@@ -47166,6 +47282,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
47166
47282
  addonId: null,
47167
47283
  access: "view"
47168
47284
  },
47285
+ "notificationRules.getRuleLastRuns": {
47286
+ capName: "notification-rules",
47287
+ capScope: "system",
47288
+ addonId: null,
47289
+ access: "view"
47290
+ },
47169
47291
  "notificationRules.getTemplateCatalog": {
47170
47292
  capName: "notification-rules",
47171
47293
  capScope: "system",
@@ -52712,7 +52834,7 @@ Object.freeze({
52712
52834
  });
52713
52835
  /**
52714
52836
  * Per-cap runtime-state policy, projected from every `*.cap.ts` that declares
52715
- * `runtimeState`. 69 caps: 36 `restored`, 33 `session`.
52837
+ * `runtimeState`. 69 caps: 37 `restored`, 32 `session`.
52716
52838
  *
52717
52839
  * A cap absent from this map has no runtime-state slice at all. A cap PRESENT
52718
52840
  * with `durability: 'session'` has one and has decided not to keep it.
@@ -52771,8 +52893,8 @@ var RUNTIME_STATE_POLICY = {
52771
52893
  volatileFields: ["lastChangedAt"]
52772
52894
  },
52773
52895
  "consumables": {
52774
- durability: "session",
52775
- volatileFields: []
52896
+ durability: "restored",
52897
+ volatileFields: ["lastChangedAt", "lastFetchedAt"]
52776
52898
  },
52777
52899
  "contact": {
52778
52900
  durability: "restored",
@@ -53062,12 +53184,55 @@ var NC_AUDIO_DEFAULTS = {
53062
53184
  samplingSeconds: 10
53063
53185
  };
53064
53186
  new Set(["devices", "classes"]);
53065
- /** Every filter, for the callers that must cover all four (guards, tests). */
53187
+ /**
53188
+ * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
53189
+ * consumed by the rule ENGINE and by every rule EDITOR.
53190
+ *
53191
+ * ── The failure this file exists for ───────────────────────────────────────
53192
+ * `NcSystemEventConditionSchema` carries four optional narrowing lists
53193
+ * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
53194
+ * `kinds` gate. They are not four filters over one vocabulary: each belongs to
53195
+ * a FAMILY of kinds and is meaningless outside it. A node going away has no
53196
+ * device type; a completed export has no package; `stream-offline` deliberately
53197
+ * carries no device type at all (a stream belongs to a camera by construction).
53198
+ *
53199
+ * The engine applied all four to every kind, so a filter from one family failed
53200
+ * a kind from another family CLOSED. The operator's live rule "Eventi di
53201
+ * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
53202
+ * way to say "only my cameras" about the two liveness kinds — and NINE of the
53203
+ * eleven silently stopped being deliverable. Four days of history contained
53204
+ * `device-online` and `device-offline` and nothing else, across a window in
53205
+ * which agents were restarted and addons were updated.
53206
+ *
53207
+ * Both editors already computed this scoping, to decide which filter boxes to
53208
+ * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
53209
+ * to these device TYPES"). Only the engine disagreed, and it disagreed in the
53210
+ * destructive direction. So the rule is stated ONCE, here, and the engine and
53211
+ * the editors are readers of it rather than three independent authors.
53212
+ *
53213
+ * ── The direction ─────────────────────────────────────────────────────────
53214
+ * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
53215
+ * hides a box has already told the operator this filter does not speak about
53216
+ * these kinds, so honouring it as an exclusion contradicts the only
53217
+ * explanation the operator was ever given. Inside its family the filter still
53218
+ * narrows, and still fails CLOSED on a subject that cannot produce the identity
53219
+ * it tests (a device the mirror cannot name is not evidence of a camera).
53220
+ */
53221
+ /**
53222
+ * Every filter, for the callers that must cover all of them (guards, tests).
53223
+ *
53224
+ * `consumableLowPercent` (D642) is not a list but it is a filter in exactly
53225
+ * this sense: it belongs to a family of kinds (the consumable pair) and the
53226
+ * engine consults it only there. It differs in one way the readers must know —
53227
+ * its ABSENCE is not "no narrowing" but the default threshold, because a
53228
+ * consumable episode is always judged at SOME threshold.
53229
+ */
53066
53230
  var NC_SYSTEM_EVENT_FILTER_KEYS = [
53067
53231
  "deviceIds",
53068
53232
  "deviceTypes",
53069
53233
  "nodeIds",
53070
- "packageNames"
53234
+ "packageNames",
53235
+ "consumableLowPercent"
53071
53236
  ];
53072
53237
  new Map(Object.entries({
53073
53238
  "device-online": "device-events",
@@ -53078,6 +53243,9 @@ new Map(Object.entries({
53078
53243
  "device-battery-normal": "device-events",
53079
53244
  "device-consumable-low": "device-events",
53080
53245
  "device-consumable-normal": "device-events",
53246
+ "device-tank-low": "device-events",
53247
+ "device-tank-full": "device-events",
53248
+ "device-tank-normal": "device-events",
53081
53249
  "stream-online": "device-events",
53082
53250
  "stream-offline": "device-events",
53083
53251
  "detection-blind": "device-events",
@@ -53108,10 +53276,48 @@ new Map(Object.entries({
53108
53276
  }));
53109
53277
  [...NC_SYSTEM_EVENT_FILTER_KEYS];
53110
53278
  NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
53279
+ /**
53280
+ * WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
53281
+ * persists (D640 "a sensor rule fires on the raise, the clear, or both").
53282
+ *
53283
+ * A device-event rule over a flood sensor notified on BOTH edges: water
53284
+ * detected, and back to dry. `NcConditions.sensorTransition` lets the rule
53285
+ * name one edge; this file answers, for one `SensorEvent`, which edge it is.
53286
+ *
53287
+ * NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
53288
+ * already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
53289
+ * (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
53290
+ * table), and a sensor event names its kind, not its cap. So the table here is
53291
+ * DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
53292
+ * Only kinds whose taxonomy category is `sensor` take part — a switch has an
53293
+ * `on` boolean too, but "it triggers / it clears" is not a sentence about a
53294
+ * light, and offering it there would be a knob with a misleading label.
53295
+ * `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
53296
+ * absent from the source table, so it is absent here.
53297
+ *
53298
+ * `undefined` = never guessed: a kind with no raise (a doorbell press, a
53299
+ * button, a cover), or a slice whose field is missing or not a boolean. The
53300
+ * engine then does NOT filter — a flood alert must not go silent because one
53301
+ * read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
53302
+ *
53303
+ * Pure, RN-safe: the viewer imports the support rule from here.
53304
+ */
53305
+ /** Event kind → the boolean field of its cap slice that means "raised". */
53306
+ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
53307
+ const field = SOURCE_CAP_ACTIVE_FIELD[capName];
53308
+ if (field === void 0 || descriptor.category !== "sensor") return [];
53309
+ return [[descriptor.kind, field]];
53310
+ })));
53311
+ Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
53111
53312
  var RULE_BODY_ONLY = ["body"];
53112
53313
  var RULE_TEXT = ["title", "body"];
53113
53314
  var BATTERY = ["device-battery-low", "device-battery-normal"];
53114
53315
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
53316
+ var TANK = [
53317
+ "device-tank-low",
53318
+ "device-tank-full",
53319
+ "device-tank-normal"
53320
+ ];
53115
53321
  var UPDATES = [
53116
53322
  "addon-update-available",
53117
53323
  "server-update-available",
@@ -53137,12 +53343,13 @@ var DEVICE_EVENTS = [
53137
53343
  "device-enabled",
53138
53344
  ...BATTERY,
53139
53345
  ...CONSUMABLE,
53346
+ ...TANK,
53140
53347
  "stream-online",
53141
53348
  "stream-offline",
53142
53349
  "detection-blind",
53143
53350
  ...ALARM
53144
53351
  ];
53145
- [...DEVICE_EVENTS], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_BODY_ONLY], [...RULE_TEXT], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...BATTERY, ...CONSUMABLE], [...RULE_TEXT], [...CONSUMABLE], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT];
53352
+ [...DEVICE_EVENTS], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_BODY_ONLY], [...RULE_TEXT], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...BATTERY, ...CONSUMABLE], [...RULE_TEXT], [...CONSUMABLE], [...RULE_TEXT], [...TANK], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT];
53146
53353
  /**
53147
53354
  * TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
53148
53355
  *
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-B_U69lgJ.js");
3
+ const require_dist = require("./dist-Dz1Hoc8h.js");
4
4
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
5
5
  require("./builtins/alerts/index.js");
6
6
  const require_formatter = require("./formatter-DqAKDlvN.js");
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { At as logLevelAtMost, Bn as EventCategory$1, Cn as asJsonObject$1, Ct as kebabToCamel, Dn as emitDownForOwnedCaps, En as createEvent, Et as lifecycleJobSchema, Fn as parseJsonUnknown, Ht as procedureAuthKey, In as readinessKey, Ln as resolveCapMount, Pn as parseJsonObject, R as addonSettingsCapability, Rn as scopeKey, Rt as objectInputDeclaresAddonId, St as isVoidInput, T as RUNTIME_DEFAULTS, Tn as asString$1, Xt as scopesAllowDeviceCap, Yt as scopesAllowAddon, _ as LOG_LEVEL_RANK, _t as isCollectionArrayMethod, b as METHOD_ACCESS_MAP, bn as ReadinessRegistry, dn as errMsg$1, dt as extractNestedAddonId, gn as DEVICE_STATUS_METHOD, gt as isArrayOutputSchema, hn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, jt as looseSchema, kn as expandCapMethods, mn as DATAPLANE_SECRET_HEADER$1, qt as resolveMethodAuth, t as ALL_CAPABILITY_DEFINITIONS, wn as asNumber, xn as ReadinessTimeoutError, yt as isObjectInput, zt as objectInputDeclaresRequiredDeviceId } from "./dist-BoYDYdae.mjs";
2
+ import { At as logLevelAtMost, Bn as EventCategory$1, Cn as asJsonObject$1, Ct as kebabToCamel, Dn as emitDownForOwnedCaps, En as createEvent, Et as lifecycleJobSchema, Fn as parseJsonUnknown, Ht as procedureAuthKey, In as readinessKey, Ln as resolveCapMount, Pn as parseJsonObject, R as addonSettingsCapability, Rn as scopeKey, Rt as objectInputDeclaresAddonId, St as isVoidInput, T as RUNTIME_DEFAULTS, Tn as asString$1, Xt as scopesAllowDeviceCap, Yt as scopesAllowAddon, _ as LOG_LEVEL_RANK, _t as isCollectionArrayMethod, b as METHOD_ACCESS_MAP, bn as ReadinessRegistry, dn as errMsg$1, dt as extractNestedAddonId, gn as DEVICE_STATUS_METHOD, gt as isArrayOutputSchema, hn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, jt as looseSchema, kn as expandCapMethods, mn as DATAPLANE_SECRET_HEADER$1, qt as resolveMethodAuth, t as ALL_CAPABILITY_DEFINITIONS, wn as asNumber, xn as ReadinessTimeoutError, yt as isObjectInput, zt as objectInputDeclaresRequiredDeviceId } from "./dist-C4qebjgF.mjs";
3
3
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
4
4
  import "./builtins/alerts/index.mjs";
5
5
  import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
@@ -1,4 +1,4 @@
1
- import { Cn as asJsonObject } from "./dist-BoYDYdae.mjs";
1
+ import { Cn as asJsonObject } from "./dist-C4qebjgF.mjs";
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-B_U69lgJ.js");
1
+ const require_dist = require("./dist-Dz1Hoc8h.js");
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.299",
3
+ "version": "1.2.301",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",