@camstack/addon-post-analysis 1.2.282 → 1.2.284

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.
@@ -10136,10 +10136,17 @@ var ModelCatalogEntrySchema = object({
10136
10136
  inputChannels: number().int().positive().optional(),
10137
10137
  labels: array(LabelDefinitionSchema).readonly(),
10138
10138
  inputLayout: _enum(["nchw", "nhwc"]).optional(),
10139
+ /**
10140
+ * `'scrfd'` applies InsightFace's SCRFD input contract, `(x - 127.5) / 128`
10141
+ * (upstream `insightface/model_zoo/scrfd.py`), instead of the historical
10142
+ * plain `/255`. Measured against COCO GT: 188 → 196 faces found on the
10143
+ * `scrfd-2.5g` catalog entry (2026-09-26 model-replacement spike, §2.4-2).
10144
+ */
10139
10145
  inputNormalization: _enum([
10140
10146
  "zero-one",
10141
10147
  "imagenet",
10142
- "none"
10148
+ "none",
10149
+ "scrfd"
10143
10150
  ]).optional(),
10144
10151
  /**
10145
10152
  * The model already applies softmax IN-GRAPH — its raw output is a
@@ -10241,7 +10248,8 @@ var ModelConvertMetadataSchema = object({
10241
10248
  inputNormalization: _enum([
10242
10249
  "zero-one",
10243
10250
  "imagenet",
10244
- "none"
10251
+ "none",
10252
+ "scrfd"
10245
10253
  ]).optional(),
10246
10254
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
10247
10255
  outputFormat: _enum([
@@ -17956,6 +17964,9 @@ var NcSystemEventKindSchema = _enum([
17956
17964
  "device-battery-normal",
17957
17965
  "device-consumable-low",
17958
17966
  "device-consumable-normal",
17967
+ "device-tank-low",
17968
+ "device-tank-full",
17969
+ "device-tank-normal",
17959
17970
  "stream-online",
17960
17971
  "stream-offline",
17961
17972
  "node-online",
@@ -18016,6 +18027,18 @@ var NC_ALARM_SYSTEM_EVENT_KINDS = [
18016
18027
  "alarm-disarmed"
18017
18028
  ];
18018
18029
  /**
18030
+ * The two kinds a RULE's consumable threshold speaks about (D642). Named once:
18031
+ * the filter scoping (`systemEventFilterApplies`), the hub's threshold census
18032
+ * and both editors read it.
18033
+ */
18034
+ var NC_CONSUMABLE_SYSTEM_EVENT_KINDS = ["device-consumable-low", "device-consumable-normal"];
18035
+ /** A vacuum's tank alerts (D642) — raised on the provider's own verdict. */
18036
+ var NC_TANK_SYSTEM_EVENT_KINDS = [
18037
+ "device-tank-low",
18038
+ "device-tank-full",
18039
+ "device-tank-normal"
18040
+ ];
18041
+ /**
18019
18042
  * One coherent system-event condition. `kinds` is the required opt-in safety
18020
18043
  * gate; the remaining lists are optional narrowing filters relevant to the
18021
18044
  * selected kinds.
@@ -18049,8 +18072,27 @@ var NcSystemEventConditionSchema = object({
18049
18072
  */
18050
18073
  excludeDeviceIds: array(number().int()).min(1).optional(),
18051
18074
  nodeIds: array(string().min(1)).min(1).optional(),
18052
- packageNames: array(string().min(1)).min(1).optional()
18075
+ packageNames: array(string().min(1)).min(1).optional(),
18076
+ /**
18077
+ * At or below this remaining-life %, a consumable is LOW for THIS rule
18078
+ * (D642). Absent = {@link NC_CONSUMABLE_LOW_PERCENT_DEFAULT}; at most
18079
+ * {@link NC_CONSUMABLE_LOW_PERCENT_MAX}, so every episode can recover. Scoped to the
18080
+ * consumable kinds (`systemEventFilterApplies`) and to the device-events
18081
+ * family; ignored on every other kind.
18082
+ *
18083
+ * It is a property of the RULE because the operator decided so: a rule at
18084
+ * 25 must be told about a filter at 20 %, a rule at 10 must not. The hub
18085
+ * keeps one episode per (threshold, device, item) — its own hysteresis, its
18086
+ * own reminder — and a rule hears only the episode judged at ITS threshold,
18087
+ * exactly as an occupancy rule hears only the edge of its own count. A
18088
+ * provider's own `replace` verdict is low at every threshold.
18089
+ */
18090
+ consumableLowPercent: number().int().min(1).max(95).optional()
18053
18091
  });
18092
+ /** The consumable threshold a system-event condition judges at (D642). */
18093
+ function consumableLowPercentOf(condition) {
18094
+ return condition.consumableLowPercent ?? 15;
18095
+ }
18054
18096
  /** Hard ceiling on a window (24h). A snooze that could not expire would be an
18055
18097
  * outage the operator asked for once and forgot. */
18056
18098
  var NC_SNOOZE_MAX_MINUTES = 1440;
@@ -19328,6 +19370,18 @@ var NC_CONDITION_CATALOG = [
19328
19370
  value: "device-consumable-normal",
19329
19371
  label: "Consumable replaced"
19330
19372
  },
19373
+ {
19374
+ value: "device-tank-low",
19375
+ label: "Tank low (water, detergent)"
19376
+ },
19377
+ {
19378
+ value: "device-tank-full",
19379
+ label: "Tank full (dirty water, dust)"
19380
+ },
19381
+ {
19382
+ value: "device-tank-normal",
19383
+ label: "Tank back to normal"
19384
+ },
19331
19385
  {
19332
19386
  value: "export-completed",
19333
19387
  label: "Export completed"
@@ -24152,7 +24206,17 @@ var DetailResultSchema = object({
24152
24206
  /** Face short side (px) measured on the NATIVE crop surface. The `bbox`
24153
24207
  * above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
24154
24208
  * consumers MUST prefer this when present (2026-07-22 native-gate fix). */
24155
- nativeFaceShortSidePx: number().optional()
24209
+ nativeFaceShortSidePx: number().optional(),
24210
+ /**
24211
+ * The five facial landmarks of a `face` detail, in the SAME frame space as
24212
+ * `bbox` (D644). Additive and optional: post-analysis stores them beside the
24213
+ * face's source frame so a future alignment can be re-derived exactly; a
24214
+ * runner that predates the field sends none and the face is stored without.
24215
+ */
24216
+ landmarks: array(object({
24217
+ x: number(),
24218
+ y: number()
24219
+ })).optional()
24156
24220
  });
24157
24221
  /**
24158
24222
  * Why an executing node REFUSED a stateless step run (`runStatelessStep`).
@@ -29723,12 +29787,20 @@ reset: method(object({
29723
29787
  },
29724
29788
  runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: number() }),
29725
29789
  /**
29726
- * Runtime-state durability: **session** — the authority is the appliance; the provider re-reads the whole item array on connect.
29790
+ * Runtime-state durability: **restored** — nothing else holds the value
29791
+ * (D642). A consumable can often be read only in a device's wake window (the
29792
+ * Dreame mower's CMS counters answer only while it charges), so a restart
29793
+ * that wiped the slice left the panel empty and the alerts blind until the
29794
+ * next wake — 2026-09-26, mower 503 idle with `items: []`. A restored item is
29795
+ * the previous observation, not a claim about now; the provider overwrites it
29796
+ * the moment it reads the device again.
29727
29797
  *
29728
29798
  * See `RuntimeStateDurability`. Enforced by
29729
29799
  * `scripts/check-runtime-state-durability.ts`.
29730
29800
  */
29731
- durability: "session"
29801
+ durability: "restored",
29802
+ /** Clocks, not content: a re-read that changed no item costs no commit. */
29803
+ volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
29732
29804
  };
29733
29805
  /**
29734
29806
  * Door / window / opening / garage / valve contact sensor. Boolean
@@ -50716,12 +50788,55 @@ function audioModeOf(value) {
50716
50788
  return null;
50717
50789
  }
50718
50790
  new Set(["devices", "classes"]);
50719
- /** Every filter, for the callers that must cover all four (guards, tests). */
50791
+ /**
50792
+ * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
50793
+ * consumed by the rule ENGINE and by every rule EDITOR.
50794
+ *
50795
+ * ── The failure this file exists for ───────────────────────────────────────
50796
+ * `NcSystemEventConditionSchema` carries four optional narrowing lists
50797
+ * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
50798
+ * `kinds` gate. They are not four filters over one vocabulary: each belongs to
50799
+ * a FAMILY of kinds and is meaningless outside it. A node going away has no
50800
+ * device type; a completed export has no package; `stream-offline` deliberately
50801
+ * carries no device type at all (a stream belongs to a camera by construction).
50802
+ *
50803
+ * The engine applied all four to every kind, so a filter from one family failed
50804
+ * a kind from another family CLOSED. The operator's live rule "Eventi di
50805
+ * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
50806
+ * way to say "only my cameras" about the two liveness kinds — and NINE of the
50807
+ * eleven silently stopped being deliverable. Four days of history contained
50808
+ * `device-online` and `device-offline` and nothing else, across a window in
50809
+ * which agents were restarted and addons were updated.
50810
+ *
50811
+ * Both editors already computed this scoping, to decide which filter boxes to
50812
+ * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
50813
+ * to these device TYPES"). Only the engine disagreed, and it disagreed in the
50814
+ * destructive direction. So the rule is stated ONCE, here, and the engine and
50815
+ * the editors are readers of it rather than three independent authors.
50816
+ *
50817
+ * ── The direction ─────────────────────────────────────────────────────────
50818
+ * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
50819
+ * hides a box has already told the operator this filter does not speak about
50820
+ * these kinds, so honouring it as an exclusion contradicts the only
50821
+ * explanation the operator was ever given. Inside its family the filter still
50822
+ * narrows, and still fails CLOSED on a subject that cannot produce the identity
50823
+ * it tests (a device the mirror cannot name is not evidence of a camera).
50824
+ */
50825
+ /**
50826
+ * Every filter, for the callers that must cover all of them (guards, tests).
50827
+ *
50828
+ * `consumableLowPercent` (D642) is not a list but it is a filter in exactly
50829
+ * this sense: it belongs to a family of kinds (the consumable pair) and the
50830
+ * engine consults it only there. It differs in one way the readers must know —
50831
+ * its ABSENCE is not "no narrowing" but the default threshold, because a
50832
+ * consumable episode is always judged at SOME threshold.
50833
+ */
50720
50834
  var NC_SYSTEM_EVENT_FILTER_KEYS = [
50721
50835
  "deviceIds",
50722
50836
  "deviceTypes",
50723
50837
  "nodeIds",
50724
- "packageNames"
50838
+ "packageNames",
50839
+ "consumableLowPercent"
50725
50840
  ];
50726
50841
  /**
50727
50842
  * Does `filter` say anything about `kind`?
@@ -50735,6 +50850,7 @@ function systemEventFilterApplies(kind, filter) {
50735
50850
  case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
50736
50851
  case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated";
50737
50852
  case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
50853
+ case "consumableLowPercent": return NC_CONSUMABLE_SYSTEM_EVENT_KINDS.includes(kind);
50738
50854
  }
50739
50855
  }
50740
50856
  /**
@@ -50770,6 +50886,9 @@ var NC_SYSTEM_EVENT_FAMILY = {
50770
50886
  "device-battery-normal": "device-events",
50771
50887
  "device-consumable-low": "device-events",
50772
50888
  "device-consumable-normal": "device-events",
50889
+ "device-tank-low": "device-events",
50890
+ "device-tank-full": "device-events",
50891
+ "device-tank-normal": "device-events",
50773
50892
  "stream-online": "device-events",
50774
50893
  "stream-offline": "device-events",
50775
50894
  "detection-blind": "device-events",
@@ -50801,7 +50920,7 @@ var NC_SYSTEM_EVENT_FAMILY = {
50801
50920
  new Map(Object.entries(NC_SYSTEM_EVENT_FAMILY));
50802
50921
  var NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = [...NC_SYSTEM_EVENT_FILTER_KEYS, "excludeDeviceIds"];
50803
50922
  /**
50804
- * The filters a family may carry. The four base filters are the union of
50923
+ * The filters a family may carry. The base filters are the union of
50805
50924
  * `systemEventFilterApplies` over the family's kinds (the spec pins that
50806
50925
  * equality). `excludeDeviceIds` is a device-events filter only: an alarm is
50807
50926
  * narrowed to the camera that triggered it and excludes nothing.
@@ -50810,7 +50929,8 @@ var NC_SYSTEM_EVENT_FAMILY_FILTERS = {
50810
50929
  "device-events": [
50811
50930
  "deviceIds",
50812
50931
  "excludeDeviceIds",
50813
- "deviceTypes"
50932
+ "deviceTypes",
50933
+ "consumableLowPercent"
50814
50934
  ],
50815
50935
  system: ["nodeIds", "packageNames"],
50816
50936
  alarm: ["deviceIds"]
@@ -50845,6 +50965,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
50845
50965
  label: "Consumables",
50846
50966
  kinds: ["device-consumable-low", "device-consumable-normal"]
50847
50967
  },
50968
+ {
50969
+ id: "tanks",
50970
+ family: "device-events",
50971
+ label: "Tanks",
50972
+ kinds: [
50973
+ "device-tank-low",
50974
+ "device-tank-full",
50975
+ "device-tank-normal"
50976
+ ]
50977
+ },
50848
50978
  {
50849
50979
  id: "detection-blind",
50850
50980
  family: "device-events",
@@ -51088,6 +51218,11 @@ var RULE_BODY_ONLY = ["body"];
51088
51218
  var RULE_TEXT = ["title", "body"];
51089
51219
  var BATTERY = ["device-battery-low", "device-battery-normal"];
51090
51220
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
51221
+ var TANK = [
51222
+ "device-tank-low",
51223
+ "device-tank-full",
51224
+ "device-tank-normal"
51225
+ ];
51091
51226
  var UPDATES = [
51092
51227
  "addon-update-available",
51093
51228
  "server-update-available",
@@ -51113,6 +51248,7 @@ var DEVICE_EVENTS = [
51113
51248
  "device-enabled",
51114
51249
  ...BATTERY,
51115
51250
  ...CONSUMABLE,
51251
+ ...TANK,
51116
51252
  "stream-online",
51117
51253
  "stream-offline",
51118
51254
  "detection-blind",
@@ -51410,6 +51546,17 @@ var NC_TEMPLATE_VARS = [
51410
51546
  kinds: ["system"],
51411
51547
  systemEventKinds: [...CONSUMABLE]
51412
51548
  },
51549
+ {
51550
+ name: "tank",
51551
+ label: "Tank",
51552
+ description: "Which tank: clean water, dirty water, detergent or dust bin.",
51553
+ example: "clean water",
51554
+ group: "system",
51555
+ families: ["rule"],
51556
+ fields: [...RULE_TEXT],
51557
+ kinds: ["system"],
51558
+ systemEventKinds: [...TANK]
51559
+ },
51413
51560
  {
51414
51561
  name: "profile",
51415
51562
  label: "Stream profile",
@@ -51802,6 +51949,38 @@ var NC_TEMPLATE_VARS = [
51802
51949
  fields: [...RULE_TEXT]
51803
51950
  }
51804
51951
  ];
51952
+ /**
51953
+ * System-event kinds the SERVED catalog holds back (D642): the kinds the hub
51954
+ * produces before the installed viewers can parse them.
51955
+ *
51956
+ * The viewer parses `getTemplateCatalog` WHOLE, with its own strict
51957
+ * `NcSystemEventKindSchema` on every descriptor's `systemEventKinds`, so one
51958
+ * kind it does not know — in `{{deviceName}}`, which every device event names —
51959
+ * empties every {{var}} picker on every phone (the same trap
51960
+ * `NcTemplateVarKindSchema` froze the rule kinds for). The in-process catalog
51961
+ * keeps them: the producer parity and the preview render read it.
51962
+ *
51963
+ * SELF-EXPIRING: `scripts/check-nc-mirrors-in-sync.ts` reads this list as the
51964
+ * viewer's allowance and fails the day the viewer mirrors one of these kinds —
51965
+ * delete it from here then, and the served catalog names it again.
51966
+ */
51967
+ var NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS = [
51968
+ "device-tank-low",
51969
+ "device-tank-full",
51970
+ "device-tank-normal"
51971
+ ];
51972
+ /**
51973
+ * The catalog as `getTemplateCatalog` SERVES it: every descriptor, with the
51974
+ * held-back kinds removed from its `systemEventKinds`. A descriptor that named
51975
+ * only held-back kinds is served with an empty list — offered to no system
51976
+ * rule an installed viewer can author, which is exactly true.
51977
+ */
51978
+ function servedTemplateVars() {
51979
+ return NC_TEMPLATE_VARS.map((d) => d.systemEventKinds === void 0 ? d : {
51980
+ ...d,
51981
+ systemEventKinds: d.systemEventKinds.filter((kind) => !NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS.includes(kind))
51982
+ });
51983
+ }
51805
51984
  /** The caption fields see a fixed, smaller vocabulary (`timelapsePreviewText`,
51806
51985
  * `summaryCaptionText`). Declared here rather than as `fields` on every
51807
51986
  * descriptor so the whole rule stays in one line of code. */
@@ -53068,6 +53247,12 @@ Object.defineProperty(exports, "NC_CONDITION_CATALOG", {
53068
53247
  return NC_CONDITION_CATALOG;
53069
53248
  }
53070
53249
  });
53250
+ Object.defineProperty(exports, "NC_CONSUMABLE_SYSTEM_EVENT_KINDS", {
53251
+ enumerable: true,
53252
+ get: function() {
53253
+ return NC_CONSUMABLE_SYSTEM_EVENT_KINDS;
53254
+ }
53255
+ });
53071
53256
  Object.defineProperty(exports, "NC_DEFAULT_SNOOZE_MINUTES", {
53072
53257
  enumerable: true,
53073
53258
  get: function() {
@@ -53086,6 +53271,12 @@ Object.defineProperty(exports, "NC_SNOOZE_MAX_MINUTES", {
53086
53271
  return NC_SNOOZE_MAX_MINUTES;
53087
53272
  }
53088
53273
  });
53274
+ Object.defineProperty(exports, "NC_TANK_SYSTEM_EVENT_KINDS", {
53275
+ enumerable: true,
53276
+ get: function() {
53277
+ return NC_TANK_SYSTEM_EVENT_KINDS;
53278
+ }
53279
+ });
53089
53280
  Object.defineProperty(exports, "NC_TAXONOMY", {
53090
53281
  enumerable: true,
53091
53282
  get: function() {
@@ -53368,6 +53559,12 @@ Object.defineProperty(exports, "canonicalHash", {
53368
53559
  return canonicalHash;
53369
53560
  }
53370
53561
  });
53562
+ Object.defineProperty(exports, "consumableLowPercentOf", {
53563
+ enumerable: true,
53564
+ get: function() {
53565
+ return consumableLowPercentOf;
53566
+ }
53567
+ });
53371
53568
  Object.defineProperty(exports, "cosineSimilarity", {
53372
53569
  enumerable: true,
53373
53570
  get: function() {
@@ -53638,6 +53835,12 @@ Object.defineProperty(exports, "sensorRaisedOf", {
53638
53835
  return sensorRaisedOf;
53639
53836
  }
53640
53837
  });
53838
+ Object.defineProperty(exports, "servedTemplateVars", {
53839
+ enumerable: true,
53840
+ get: function() {
53841
+ return servedTemplateVars;
53842
+ }
53843
+ });
53641
53844
  Object.defineProperty(exports, "sleep", {
53642
53845
  enumerable: true,
53643
53846
  get: function() {