@camstack/addon-model-studio 1.1.283 → 1.1.285

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 (19) hide show
  1. package/THIRD_PARTY_MODELS.md +2 -2
  2. package/dist/{MotionZonesSettings-BWAI7HWB.mjs → MotionZonesSettings-BWIjI_mB.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-CdooyIuO.mjs → PrivacyMaskSettings-BuSCnSs6.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-B16rZSlJ.mjs → SceneMonitorEditor-D6DomEv3.mjs} +3 -3
  5. package/dist/_stub.js +12 -12
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-B_TQF1Vq.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-D4_cFV_R.mjs} +4 -4
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-8XY35EWj.mjs +26 -0
  8. package/dist/{hostInit-DpZ13Hyp.mjs → hostInit-SeST1uzI.mjs} +3 -3
  9. package/dist/model-studio.addon.js +237 -61
  10. package/dist/model-studio.addon.mjs +237 -61
  11. package/dist/{player-overlays-CXrX1-YL.mjs → player-overlays-DZwcDBXd.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-DXfPuDT3.mjs → responsive-B15MRUZC.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-Dz6o2ZDO.mjs → scene-monitor-copy-JIcLgE--.mjs} +1 -1
  15. package/dist/{square-BPjfdvzl.mjs → square-E31fCPCW.mjs} +1 -1
  16. package/dist/{trash-2-_NoItStt.mjs → trash-2-DBIIPVno.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-EdzqlJkG.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Dcfz5AcL.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B_Vs5gXw.mjs +0 -26
@@ -394,7 +394,7 @@ function buildScryptedRegistryDescriptor(entry) {
394
394
  };
395
395
  }
396
396
  //#endregion
397
- //#region ../types/dist/event-category-DOl51-Ij.mjs
397
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
398
398
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
399
399
  EventCategory["SystemBoot"] = "system.boot";
400
400
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -711,6 +711,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
711
711
  */
712
712
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
713
713
  /**
714
+ * A camera's motion source has fired constantly with no subject for an hour
715
+ * (motion duty or session count over the bar, zero detections) — it is not
716
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
717
+ * {@link PipelineMotionCalm}.
718
+ */
719
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
720
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
721
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
722
+ /**
714
723
  * Per-camera pipeline config was mutated by the orchestrator
715
724
  * (3-level settings change via `setAgentAddonDefaults` /
716
725
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -1082,6 +1091,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1082
1091
  EventCategory["BackupRestored"] = "backup.restored";
1083
1092
  EventCategory["NotificationDispatched"] = "notification.dispatched";
1084
1093
  EventCategory["NotificationFailed"] = "notification.failed";
1094
+ /**
1095
+ * A notification rule that cannot work (D905): its stored row does not load,
1096
+ * or it still names a device / delivery target the prune CONFIRMED deleted.
1097
+ * One edge per rule per distinct set of reasons; never on an unanswered read.
1098
+ */
1099
+ EventCategory["NotificationRuleBroken"] = "notification.rule-broken";
1100
+ /** The clear of {@link NotificationRuleBroken}: the rule loads and names nothing deleted. */
1101
+ EventCategory["NotificationRuleRepaired"] = "notification.rule-repaired";
1085
1102
  EventCategory["DeviceUpdated"] = "device.updated";
1086
1103
  /**
1087
1104
  * Transport-level connectivity. Emitted by the device driver when
@@ -5809,7 +5826,7 @@ var ZodIssueCode = {
5809
5826
  var ZodFirstPartyTypeKind;
5810
5827
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5811
5828
  //#endregion
5812
- //#region ../types/dist/sleep-_sV1BE2f.mjs
5829
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
5813
5830
  /**
5814
5831
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5815
5832
  * window to float samples (D455).
@@ -8271,7 +8288,7 @@ var EntryDescriptorSchema = object({
8271
8288
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
8272
8289
  fields: record(string(), unknown())
8273
8290
  }).strict();
8274
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
8291
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
8275
8292
  var RecordKindDeclarationSchema = object({
8276
8293
  database: _enum(RECORD_DATABASES).default("settings"),
8277
8294
  class: _enum(RECORD_CLASSES),
@@ -8290,14 +8307,6 @@ var RecordKindDeclarationSchema = object({
8290
8307
  secretPaths: array(string().min(1)).default([]),
8291
8308
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8292
8309
  secretArrayKeys: record(string(), string()).default({}),
8293
- /**
8294
- * RETIRED (D900): the legacy table a kind adopted from during the records
8295
- * migration. Nothing declares it any more and nothing reads it; the schema
8296
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8297
- * (an orphaned kind is never redeclared) and an addon built before the
8298
- * removal still sends it. Never set it.
8299
- */
8300
- adoptsFrom: string().min(1).optional(),
8301
8310
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8302
8311
  transactFamily: string().min(1).optional(),
8303
8312
  entry: EntryDescriptorSchema.optional()
@@ -13181,17 +13190,6 @@ object({
13181
13190
  createdAt: number(),
13182
13191
  updatedAt: number()
13183
13192
  });
13184
- object({
13185
- id: string(),
13186
- label: string(),
13187
- isAdmin: boolean().default(false),
13188
- allowedProviders: AllowedProviderSchema,
13189
- allowedDevices: AllowedDevicesSchema,
13190
- tokenHash: string(),
13191
- tokenPrefix: string(),
13192
- createdAt: number(),
13193
- lastUsedAt: number().optional()
13194
- });
13195
13193
  object({
13196
13194
  id: string(),
13197
13195
  userId: string(),
@@ -17112,16 +17110,36 @@ var RecordKindStateSchema = _enum([
17112
17110
  var DeclareKindResultSchema = object({
17113
17111
  kindId: number().int(),
17114
17112
  state: RecordKindStateSchema,
17115
- createdIndexes: array(string()),
17116
- /**
17117
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
17118
- * it stays on the wire, null, because an addon built before the removal reads
17119
- * an ABSENT field as "adoption pending" and refuses to start.
17120
- */
17121
- adoptionPending: _null()
17113
+ createdIndexes: array(string())
17122
17114
  });
17123
17115
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
17124
17116
  var SecretRefsList = array(string());
17117
+ /**
17118
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
17119
+ * All ops of one call share ONE database file and ONE `transactFamily`.
17120
+ */
17121
+ var RecordTransactOpSchema = discriminatedUnion("op", [
17122
+ object({
17123
+ op: literal("put"),
17124
+ kind: RecordKindNameSchema,
17125
+ record: RecordInputSchema,
17126
+ ifRev: number().int().min(0).optional()
17127
+ }),
17128
+ object({
17129
+ op: literal("patch"),
17130
+ kind: RecordKindNameSchema,
17131
+ id: RecordIdSchema,
17132
+ data: RecordBodySchema,
17133
+ at: number().int().nullable().optional(),
17134
+ expiresAt: number().int().nullable().optional(),
17135
+ ifRev: number().int().min(1).optional()
17136
+ }),
17137
+ object({
17138
+ op: literal("delete"),
17139
+ kind: RecordKindNameSchema,
17140
+ id: RecordIdSchema
17141
+ })
17142
+ ]);
17125
17143
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
17126
17144
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
17127
17145
  kind: "mutation",
@@ -17228,6 +17246,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
17228
17246
  }), {
17229
17247
  kind: "mutation",
17230
17248
  auth: "admin"
17249
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
17250
+ results: array(object({
17251
+ rev: number().int().nullable(),
17252
+ deleted: boolean()
17253
+ })),
17254
+ releasedRefs: SecretRefsList,
17255
+ secretRefs: SecretRefsList
17256
+ }), {
17257
+ kind: "mutation",
17258
+ auth: "admin"
17231
17259
  }), method(object({
17232
17260
  deviceId: number().int(),
17233
17261
  kinds: array(RecordKindNameSchema).optional()
@@ -42592,9 +42620,13 @@ var NcSystemEventKindSchema = _enum([
42592
42620
  "node-updating",
42593
42621
  "node-inference-unavailable",
42594
42622
  "detection-blind",
42623
+ "motion-noisy",
42624
+ "motion-calm",
42595
42625
  "recording-stalled",
42596
42626
  "recording-healthy",
42597
42627
  "recording-degraded",
42628
+ "device-attention-required",
42629
+ "device-attention-resolved",
42598
42630
  "storage-location-low",
42599
42631
  "storage-location-critical",
42600
42632
  "storage-location-ok",
@@ -42618,6 +42650,8 @@ var NcSystemEventKindSchema = _enum([
42618
42650
  "alert-critical",
42619
42651
  "alert-error",
42620
42652
  "alert-critical-resolved",
42653
+ "rule-broken",
42654
+ "rule-repaired",
42621
42655
  "camera-online",
42622
42656
  "camera-offline",
42623
42657
  "camera-disabled",
@@ -55049,6 +55083,16 @@ object({
55049
55083
  powerState: string().nullable(),
55050
55084
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
55051
55085
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
55086
+ /**
55087
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
55088
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
55089
+ * when none is reported. A cleared reminder is not an unknown one.
55090
+ */
55091
+ filterCleaningDue: boolean().nullable(),
55092
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
55093
+ machineCareDue: boolean().nullable(),
55094
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
55095
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
55052
55096
  /** Option states: null when the appliance does not expose the option or has not said. */
55053
55097
  halfLoad: boolean().nullable(),
55054
55098
  hygienePlus: boolean().nullable(),
@@ -61666,16 +61710,6 @@ var UpdateUserInputSchema = object({
61666
61710
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
61667
61711
  scopes: array(TokenScopeSchema).optional()
61668
61712
  });
61669
- var ApiKeySummarySchema = object({
61670
- id: string(),
61671
- label: string(),
61672
- isAdmin: boolean().default(false),
61673
- allowedProviders: union([array(string()), literal("*")]).optional(),
61674
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
61675
- tokenPrefix: string(),
61676
- createdAt: number(),
61677
- lastUsedAt: number().optional()
61678
- });
61679
61713
  var OauthSessionSummarySchema = object({
61680
61714
  id: string(),
61681
61715
  userId: string(),
@@ -61697,8 +61731,7 @@ var TotpStatusSchema = object({
61697
61731
  confirmedAt: number().nullable()
61698
61732
  });
61699
61733
  /**
61700
- * user-management — singleton capability for user accounts and the
61701
- * legacy API-key rows.
61734
+ * user-management — singleton capability for user accounts.
61702
61735
  *
61703
61736
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61704
61737
  * — the subset check on `setUserScopes` is moot
@@ -61754,10 +61787,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61754
61787
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
61755
61788
  kind: "mutation",
61756
61789
  access: "view"
61757
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
61758
- kind: "mutation",
61759
- auth: "admin",
61760
- access: "delete"
61761
61790
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
61762
61791
  kind: "mutation",
61763
61792
  auth: "admin",
@@ -69368,6 +69397,12 @@ Object.freeze({
69368
69397
  addonId: null,
69369
69398
  access: "view"
69370
69399
  },
69400
+ "records.transact": {
69401
+ capName: "records",
69402
+ capScope: "system",
69403
+ addonId: null,
69404
+ access: "create"
69405
+ },
69371
69406
  "sceneMonitor.captureReference": {
69372
69407
  capName: "scene-monitor",
69373
69408
  capScope: "device",
@@ -70700,12 +70735,6 @@ Object.freeze({
70700
70735
  addonId: null,
70701
70736
  access: "view"
70702
70737
  },
70703
- "userManagement.listApiKeys": {
70704
- capName: "user-management",
70705
- capScope: "system",
70706
- addonId: null,
70707
- access: "view"
70708
- },
70709
70738
  "userManagement.listExternalIdentities": {
70710
70739
  capName: "user-management",
70711
70740
  capScope: "system",
@@ -70760,12 +70789,6 @@ Object.freeze({
70760
70789
  addonId: null,
70761
70790
  access: "create"
70762
70791
  },
70763
- "userManagement.revokeApiKey": {
70764
- capName: "user-management",
70765
- capScope: "system",
70766
- addonId: null,
70767
- access: "delete"
70768
- },
70769
70792
  "userManagement.revokeOauthSession": {
70770
70793
  capName: "user-management",
70771
70794
  capScope: "system",
@@ -74130,9 +74153,13 @@ new Map(Object.entries({
74130
74153
  "stream-online": "device-events",
74131
74154
  "stream-offline": "device-events",
74132
74155
  "detection-blind": "device-events",
74156
+ "motion-noisy": "device-events",
74157
+ "motion-calm": "device-events",
74133
74158
  "recording-stalled": "device-events",
74134
74159
  "recording-healthy": "device-events",
74135
74160
  "recording-degraded": "device-events",
74161
+ "device-attention-required": "device-events",
74162
+ "device-attention-resolved": "device-events",
74136
74163
  "node-online": "system",
74137
74164
  "node-offline": "system",
74138
74165
  "node-restarting": "system",
@@ -74149,6 +74176,8 @@ new Map(Object.entries({
74149
74176
  "alert-critical": "system",
74150
74177
  "alert-error": "system",
74151
74178
  "alert-critical-resolved": "system",
74179
+ "rule-broken": "system",
74180
+ "rule-repaired": "system",
74152
74181
  "storage-location-low": "system",
74153
74182
  "storage-location-critical": "system",
74154
74183
  "storage-location-ok": "system",
@@ -74213,6 +74242,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
74213
74242
  label: "Detecting nothing",
74214
74243
  kinds: ["detection-blind"]
74215
74244
  },
74245
+ {
74246
+ id: "motion-noise",
74247
+ family: "device-events",
74248
+ label: "Motion without a subject",
74249
+ kinds: ["motion-noisy", "motion-calm"]
74250
+ },
74216
74251
  {
74217
74252
  id: "recording",
74218
74253
  family: "device-events",
@@ -74223,6 +74258,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
74223
74258
  "recording-degraded"
74224
74259
  ]
74225
74260
  },
74261
+ {
74262
+ id: "device-attention",
74263
+ family: "device-events",
74264
+ label: "Needs attention",
74265
+ kinds: ["device-attention-required", "device-attention-resolved"]
74266
+ },
74226
74267
  {
74227
74268
  id: "nodes",
74228
74269
  family: "system",
@@ -74283,6 +74324,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
74283
74324
  "alert-critical-resolved"
74284
74325
  ]
74285
74326
  },
74327
+ {
74328
+ id: "rule-health",
74329
+ family: "system",
74330
+ label: "Notification rules",
74331
+ kinds: ["rule-broken", "rule-repaired"]
74332
+ },
74286
74333
  {
74287
74334
  id: "alarm",
74288
74335
  family: "alarm",
@@ -74356,6 +74403,7 @@ var ALERT_EPISODE = [
74356
74403
  "alert-error",
74357
74404
  "alert-critical-resolved"
74358
74405
  ];
74406
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
74359
74407
  var UPDATES = [
74360
74408
  "addon-update-available",
74361
74409
  "server-update-available",
@@ -74385,9 +74433,12 @@ var DEVICE_EVENTS = [
74385
74433
  "stream-online",
74386
74434
  "stream-offline",
74387
74435
  "detection-blind",
74436
+ "motion-noisy",
74437
+ "motion-calm",
74388
74438
  "recording-stalled",
74389
74439
  "recording-healthy",
74390
74440
  "recording-degraded",
74441
+ ...DEVICE_ATTENTION,
74391
74442
  ...ALARM
74392
74443
  ];
74393
74444
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -74555,7 +74606,13 @@ var STATE_SUMMARY_VARS = [
74555
74606
  [...RULE_TEXT],
74556
74607
  [...RULE_TEXT],
74557
74608
  [...RULE_TEXT],
74558
- ([...RULE_TEXT], [...ALERT_EPISODE]),
74609
+ [...RULE_TEXT],
74610
+ [...RULE_TEXT],
74611
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
74612
+ [...RULE_TEXT],
74613
+ [...RULE_TEXT],
74614
+ [...RULE_TEXT],
74615
+ [...RULE_TEXT],
74559
74616
  [...RULE_TEXT],
74560
74617
  [...RULE_TEXT],
74561
74618
  [...RULE_TEXT],
@@ -74573,11 +74630,11 @@ var STATE_SUMMARY_VARS = [
74573
74630
  [...RULE_TEXT],
74574
74631
  [...RULE_TEXT],
74575
74632
  [...RULE_TEXT],
74633
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
74576
74634
  ([...RULE_TEXT], [...ALERT_EPISODE]),
74635
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
74577
74636
  ([...RULE_TEXT], [...ALERT_EPISODE]),
74578
- ([...RULE_TEXT], [...ALERT_EPISODE]),
74579
- ([...RULE_TEXT], [...ALERT_EPISODE]),
74580
- ([...RULE_TEXT], [...ALERT_EPISODE]),
74637
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
74581
74638
  [...RULE_TEXT],
74582
74639
  [...RULE_TEXT],
74583
74640
  [...RULE_TEXT],
@@ -74598,6 +74655,125 @@ var STATE_SUMMARY_VARS = [
74598
74655
  [...RULE_TEXT],
74599
74656
  ...STATE_SUMMARY_VARS
74600
74657
  ];
74658
+ new Map([
74659
+ {
74660
+ id: "device-connectivity",
74661
+ family: "device-events",
74662
+ label: "Device connectivity (offline / back online)",
74663
+ bad: ["device-offline"],
74664
+ recovery: ["device-online"],
74665
+ snapshotLabel: "Devices offline now",
74666
+ snapshotSection: "device-state"
74667
+ },
74668
+ {
74669
+ id: "device-switch",
74670
+ family: "device-events",
74671
+ label: "Device switched off / back on",
74672
+ bad: ["device-disabled"],
74673
+ recovery: ["device-enabled"],
74674
+ snapshotLabel: "Devices switched off now",
74675
+ snapshotSection: "device-state"
74676
+ },
74677
+ {
74678
+ id: "stream-connectivity",
74679
+ family: "device-events",
74680
+ label: "Stream connectivity (offline / back online)",
74681
+ bad: ["stream-offline"],
74682
+ recovery: ["stream-online"],
74683
+ snapshotLabel: "Streams offline now",
74684
+ snapshotSection: "streams"
74685
+ },
74686
+ {
74687
+ id: "battery",
74688
+ family: "device-events",
74689
+ label: "Battery (low / back to normal)",
74690
+ bad: ["device-battery-low"],
74691
+ recovery: ["device-battery-normal"],
74692
+ snapshotLabel: "Batteries low now",
74693
+ snapshotSection: "battery"
74694
+ },
74695
+ {
74696
+ id: "consumables",
74697
+ family: "device-events",
74698
+ label: "Consumables (low / replaced)",
74699
+ bad: ["device-consumable-low"],
74700
+ recovery: ["device-consumable-normal"],
74701
+ snapshotLabel: "Consumables low now",
74702
+ snapshotSection: "consumables"
74703
+ },
74704
+ {
74705
+ id: "tanks",
74706
+ family: "device-events",
74707
+ label: "Tanks (low or full / back to normal)",
74708
+ bad: ["device-tank-low", "device-tank-full"],
74709
+ recovery: ["device-tank-normal"],
74710
+ snapshotLabel: "Tanks low or full now",
74711
+ snapshotSection: "tanks"
74712
+ },
74713
+ {
74714
+ id: "motion-noise",
74715
+ family: "device-events",
74716
+ label: "Motion without a subject (constant / calm again)",
74717
+ bad: ["motion-noisy"],
74718
+ recovery: ["motion-calm"],
74719
+ snapshotLabel: "Cameras with constant motion now",
74720
+ snapshotSection: null
74721
+ },
74722
+ {
74723
+ id: "recording-health",
74724
+ family: "device-events",
74725
+ label: "Recording health (stalled or degraded / recording again)",
74726
+ bad: ["recording-stalled", "recording-degraded"],
74727
+ recovery: ["recording-healthy"],
74728
+ snapshotLabel: "Recordings stalled now",
74729
+ snapshotSection: null
74730
+ },
74731
+ {
74732
+ id: "device-attention",
74733
+ family: "device-events",
74734
+ label: "Device needs attention (raised / resolved)",
74735
+ bad: ["device-attention-required"],
74736
+ recovery: ["device-attention-resolved"],
74737
+ snapshotLabel: "Devices needing attention now",
74738
+ snapshotSection: null
74739
+ },
74740
+ {
74741
+ id: "node-connectivity",
74742
+ family: "system",
74743
+ label: "Node connectivity (offline / back online)",
74744
+ bad: ["node-offline"],
74745
+ recovery: ["node-online"],
74746
+ snapshotLabel: "Nodes offline now",
74747
+ snapshotSection: "nodes"
74748
+ },
74749
+ {
74750
+ id: "storage-space",
74751
+ family: "system",
74752
+ label: "Storage space (low or critical / ok again)",
74753
+ bad: ["storage-location-low", "storage-location-critical"],
74754
+ recovery: ["storage-location-ok"],
74755
+ snapshotLabel: "Storage locations low now",
74756
+ snapshotSection: null
74757
+ },
74758
+ {
74759
+ id: "critical-alerts",
74760
+ family: "system",
74761
+ label: "Critical alerts (raised / resolved)",
74762
+ bad: ["alert-critical"],
74763
+ recovery: ["alert-critical-resolved"],
74764
+ snapshotLabel: "Critical alerts open now",
74765
+ snapshotSection: null
74766
+ },
74767
+ {
74768
+ id: "rule-health",
74769
+ family: "system",
74770
+ label: "Rule health (broken / repaired)",
74771
+ bad: ["rule-broken"],
74772
+ recovery: ["rule-repaired"],
74773
+ snapshotLabel: "Notification rules broken now",
74774
+ snapshotSection: null
74775
+ }
74776
+ ].flatMap((spec) => [...spec.bad, ...spec.recovery].map((kind) => [kind, spec])));
74601
74777
  new Set([
74602
74778
  "disarmed",
74603
74779
  "armed_home",