@camstack/addon-matter-broker 0.2.14 → 0.2.16

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 (3) hide show
  1. package/dist/addon.js +731 -76
  2. package/dist/addon.mjs +731 -76
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10834,7 +10834,14 @@ var cameraStreamsCapability = {
10834
10834
  low: string$2().optional()
10835
10835
  }),
10836
10836
  lastChangedAt: number()
10837
- })
10837
+ }),
10838
+ /**
10839
+ * Runtime-state durability: **session** — a restored `slotStatuses: streaming` for a camera that has been dark for two hours is a lie the UI renders as truth.
10840
+ *
10841
+ * See `RuntimeStateDurability`. Enforced by
10842
+ * `scripts/check-runtime-state-durability.ts`.
10843
+ */
10844
+ durability: "session"
10838
10845
  };
10839
10846
  /** Where a block runs. The operator chooses — a block driving a device on an
10840
10847
  * agent is the reason placement is not fixed to the hub. */
@@ -11395,6 +11402,13 @@ var deviceDiscoveryCapability = {
11395
11402
  kind: "poll"
11396
11403
  },
11397
11404
  runtimeState: DeviceDiscoveryStatusSchema.extend({ lastFetchedAt: number().int().nonnegative() }),
11405
+ /**
11406
+ * Runtime-state durability: **session** — 5.7 KB of scan output on the largest device, fully re-derivable by re-scanning.
11407
+ *
11408
+ * See `RuntimeStateDurability`. Enforced by
11409
+ * `scripts/check-runtime-state-durability.ts`.
11410
+ */
11411
+ durability: "session",
11398
11412
  methods: {
11399
11413
  /**
11400
11414
  * Snapshot of the current `discovered` list. Returns the
@@ -13281,11 +13295,33 @@ var NotificationFormatSchema = _enum([
13281
13295
  * Named by INTENT, never by glyph. "check" would tie the vocabulary to one
13282
13296
  * renderer's icon set; "acknowledge" survives an adapter that draws it
13283
13297
  * differently.
13298
+ *
13299
+ * ── A TOKEN IS NOT A WIRE VALUE ─────────────────────────────────────
13300
+ *
13301
+ * These names are for US. **No adapter may forward one verbatim.** Each maps
13302
+ * the whole set onto its own renderer's vocabulary through a
13303
+ * `Record<NotificationActionIcon, string>` — a Record, never a lookup with a
13304
+ * fallback, so adding a member here fails every adapter's build until someone
13305
+ * decides its glyph, which is the only place that decision can be made
13306
+ * honestly.
13307
+ *
13308
+ * This paragraph is the bug. Zentik declared `actionIcons: true` and passed
13309
+ * `disarm` straight through; iOS feeds that string to
13310
+ * `UNNotificationActionIcon(systemImageName:)`, `disarm` is not an SF Symbol,
13311
+ * and every snooze and alarm button arrived BLANK. A pass-through is not a
13312
+ * mapping, and "the field is documented" is not "the value renders".
13313
+ *
13314
+ * Adding a member is TRAIN-BOUND. The enum lives in the published
13315
+ * `@camstack/server` closure and the cap seam validates against the HUB's copy,
13316
+ * so an addon that emits a token the running hub does not know does not lose an
13317
+ * icon — its whole `send` fails Zod validation and the notification never
13318
+ * arrives. Never emit a new token from an addon before the train carrying it.
13284
13319
  */
13285
13320
  var NotificationActionIconSchema = _enum([
13286
13321
  "acknowledge",
13287
13322
  "dismiss",
13288
13323
  "silence",
13324
+ "snooze",
13289
13325
  "view",
13290
13326
  "play",
13291
13327
  "open",
@@ -13293,9 +13329,13 @@ var NotificationActionIconSchema = _enum([
13293
13329
  "lock",
13294
13330
  "unlock",
13295
13331
  "arm",
13332
+ "arm-home",
13333
+ "arm-away",
13334
+ "arm-night",
13296
13335
  "disarm",
13297
13336
  "light",
13298
- "alert"
13337
+ "alert",
13338
+ "camera"
13299
13339
  ]);
13300
13340
  /** A single tap-through action button. */
13301
13341
  var NotificationActionSchema = object({
@@ -13311,7 +13351,23 @@ var NotificationActionSchema = object({
13311
13351
  * else — see `notification-center/action-token.ts` for what that does and
13312
13352
  * does not buy.
13313
13353
  */
13314
- destructive: boolean().optional()
13354
+ destructive: boolean().optional(),
13355
+ /**
13356
+ * How the tap should REACH the url.
13357
+ *
13358
+ * `navigate` (absent, and every button authored before this field) opens it:
13359
+ * the phone leaves the notification and shows whatever the callback returns.
13360
+ * That is right for a button whose answer the operator wants to read.
13361
+ *
13362
+ * `background` fires it as a POST and stays put. It exists for the buttons
13363
+ * whose whole point is not to interrupt — "silence this for 30 minutes" is
13364
+ * an answer to the notification, and being thrown into a browser tab to
13365
+ * confirm it costs more attention than the notification did. A backend that
13366
+ * cannot do a background call renders it as an ordinary link (the adapters
13367
+ * fall back rather than dropping the button), so this is a preference, never
13368
+ * a requirement.
13369
+ */
13370
+ mode: _enum(["navigate", "background"]).optional()
13315
13371
  });
13316
13372
  /**
13317
13373
  * The canonical notification. `body` is the only hard field (Apprise model).
@@ -13479,6 +13535,24 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
13479
13535
  targetId: string$2(),
13480
13536
  enabled: boolean()
13481
13537
  }), _void(), { kind: "mutation" });
13538
+ new Set([
13539
+ {
13540
+ id: "person",
13541
+ name: "Person"
13542
+ },
13543
+ {
13544
+ id: "vehicle",
13545
+ name: "Vehicle"
13546
+ },
13547
+ {
13548
+ id: "animal",
13549
+ name: "Animal"
13550
+ },
13551
+ {
13552
+ id: "package",
13553
+ name: "Package"
13554
+ }
13555
+ ].map((l) => l.id));
13482
13556
  var COCO_TO_MACRO = {
13483
13557
  mapping: {
13484
13558
  person: "person",
@@ -14163,7 +14237,17 @@ var alarmPanelCapability = {
14163
14237
  * full slice; renders an arm button per `availableModes` entry and
14164
14238
  * a PIN field iff `requiresCode === true`.
14165
14239
  */
14166
- runtimeState: AlarmPanelStatusSchema
14240
+ runtimeState: AlarmPanelStatusSchema,
14241
+ /**
14242
+ * Runtime-state durability: **restored** — armed state is the one thing a panel must not lose across a restart.
14243
+ *
14244
+ * See `RuntimeStateDurability`. Enforced by
14245
+ * `scripts/check-runtime-state-durability.ts`.
14246
+ */
14247
+ durability: "restored",
14248
+ /** Clock fields: written, but excluded from the compare that decides
14249
+ * whether persisting is worth a SQLite commit. */
14250
+ volatileStateFields: ["lastChangedAt"]
14167
14251
  };
14168
14252
  /**
14169
14253
  * Shared geometry vocabulary for on-frame shape caps — privacy-mask,
@@ -14304,6 +14388,8 @@ var NcSystemEventKindSchema = _enum([
14304
14388
  "alarm-triggered",
14305
14389
  "alarm-armed",
14306
14390
  "alarm-disarmed",
14391
+ "alarm-arming",
14392
+ "alarm-arm-refused",
14307
14393
  "camera-online",
14308
14394
  "camera-offline",
14309
14395
  "camera-disabled",
@@ -14340,6 +14426,9 @@ var NcSystemEventConditionSchema = object({
14340
14426
  nodeIds: array(string$2().min(1)).min(1).optional(),
14341
14427
  packageNames: array(string$2().min(1)).min(1).optional()
14342
14428
  });
14429
+ /** Hard ceiling on a window (24h). A snooze that could not expire would be an
14430
+ * outage the operator asked for once and forgot. */
14431
+ var NC_SNOOZE_MAX_MINUTES = 1440;
14343
14432
  /** Weekly schedule — OR of windows; absence on the rule = always active. */
14344
14433
  var NcScheduleSchema = object({
14345
14434
  windows: array(object({
@@ -14716,15 +14805,15 @@ var NcConditionsSchema = object({
14716
14805
  * (an `immediate` rule naming an `audio-*` class, one notification per
14717
14806
  * classified sample) stays exactly as it was for rules that already use it.
14718
14807
  *
14719
- * NOT in {@link NC_CONDITION_CATALOG} yet, and that is the sequencing rule
14720
- * rather than an oversight: the viewer mirrors the descriptor enums BY HAND
14721
- * (`camstack/src/data/notification-center.ts`, guarded by
14722
- * `scripts/check-viewer-condition-mirror.ts`) and its rule editor STRIPS the
14808
+ * In {@link NC_CONDITION_CATALOG} since P2, and the ORDER it got there is the
14809
+ * rule rather than an accident: the viewer mirrors the descriptor enums BY
14810
+ * HAND (`camstack/src/data/notification-center.ts`, guarded by
14811
+ * `scripts/check-viewer-condition-mirror.ts`) and its rule editor strips the
14723
14812
  * condition fields it does not know when a rule is saved from the phone.
14724
14813
  * Publishing an editor for a condition the app cannot round-trip is how an
14725
- * operator loses a rule's conditions by opening it — so the descriptor, the
14726
- * admin widget and the viewer mirror land together (P2 + P3), and only then
14727
- * does an audio rule become authorable.
14814
+ * operator loses a rule's conditions by opening it — so the viewer mirror
14815
+ * (P3, shipped) went FIRST, and the descriptor an editor renders from
14816
+ * follows here.
14728
14817
  */
14729
14818
  audio: NcAudioConditionSchema.optional()
14730
14819
  });
@@ -14960,6 +15049,30 @@ var NcRuleInputSchema = object({
14960
15049
  */
14961
15050
  snoozeAllowGlobal: boolean().optional(),
14962
15051
  /**
15052
+ * The snooze durations THIS rule's notification offers as buttons, in
15053
+ * minutes.
15054
+ *
15055
+ * Three states, and all three are distinct — which is exactly why this is
15056
+ * `.optional()` and never `.default()`. A Zod default does not run on the
15057
+ * addon cap path (three production failures in one day), so a schema default
15058
+ * would collapse the first two:
15059
+ *
15060
+ * | value | meaning |
15061
+ * | --- | --- |
15062
+ * | absent | the operator never said ⇒ {@link NC_DEFAULT_SNOOZE_MINUTES} |
15063
+ * | `[]` | **no snooze buttons on this rule** — the explicit override |
15064
+ * | a list | these choices, de-duplicated and sorted, at most four |
15065
+ *
15066
+ * `.max(4)` because the notifier's own action budget is small (ntfy allows
15067
+ * three buttons in total) and a rule that spent it all on snooze choices
15068
+ * would push its own tap-through actions off the notification.
15069
+ *
15070
+ * An empty list is NOT an alarm exemption: a rule the alarm is about, or
15071
+ * that arms the panel, is exempt automatically and cannot be silenced by a
15072
+ * window from anywhere (D133).
15073
+ */
15074
+ snoozeOptions: array(number().int().min(1).max(NC_SNOOZE_MAX_MINUTES)).max(4).optional(),
15075
+ /**
14963
15076
  * Devices this rule ACTUATES — arm the alarm, open a gate, turn on a light.
14964
15077
  *
14965
15078
  * This is what makes the rule set the alarm's trigger set without the alarm
@@ -15059,6 +15172,7 @@ var NcConditionDescriptorSchema = object({
15059
15172
  "device",
15060
15173
  "package",
15061
15174
  "occupancy",
15175
+ "audio",
15062
15176
  "system"
15063
15177
  ]),
15064
15178
  label: string$2(),
@@ -15077,6 +15191,7 @@ var NcConditionDescriptorSchema = object({
15077
15191
  "crossingSelect",
15078
15192
  "polygonDraw",
15079
15193
  "occupancy",
15194
+ "audio",
15080
15195
  "deviceState",
15081
15196
  "systemEvent"
15082
15197
  ]),
@@ -15228,7 +15343,20 @@ var NcSnoozeInputSchema = object({
15228
15343
  ruleId: string$2().optional(),
15229
15344
  /** Required when `scope: 'device'`. */
15230
15345
  deviceId: number().int().optional(),
15231
- durationMinutes: number().int().min(1).max(1440),
15346
+ /**
15347
+ * Narrow the window to these subject classes — "the cat, not the person".
15348
+ *
15349
+ * ORTHOGONAL to `scope`, deliberately, and absent means EVERY class: that is
15350
+ * what every window authored before this field meant, so no persisted row
15351
+ * changes meaning and no client has to learn anything to keep working.
15352
+ *
15353
+ * It is what makes the window's real key `(deviceId, classes[])` and lets it
15354
+ * cross rules (D133): the operator points at a camera and a kind of thing,
15355
+ * not at whichever of their four rules happened to produce the notification
15356
+ * they are dismissing.
15357
+ */
15358
+ classes: array(string$2().min(1)).min(1).optional(),
15359
+ durationMinutes: number().int().min(1).max(NC_SNOOZE_MAX_MINUTES),
15232
15360
  /**
15233
15361
  * Silence this for EVERY recipient, not just the caller. Permission is
15234
15362
  * checked server-side (the rule's `snoozeAllowGlobal`, or admin for the
@@ -15253,6 +15381,10 @@ var NcSnoozeSchema = object({
15253
15381
  scope: NcSnoozeScopeSchema,
15254
15382
  ruleId: string$2().optional(),
15255
15383
  deviceId: number().int().optional(),
15384
+ /** Subject classes this window covers. ABSENT = every class — see
15385
+ * {@link NcSnoozeInputSchema.shape.classes}. Lives in the JSON blob and has
15386
+ * no SQLite column: nothing queries a window by class. */
15387
+ classes: array(string$2().min(1)).min(1).optional(),
15256
15388
  startedAt: number(),
15257
15389
  /** Exclusive: at exactly this instant the snooze is over. Expiry is a
15258
15390
  * COMPARISON, not a job — no sweeper can leave the operator silenced. */
@@ -17353,7 +17485,14 @@ var zonesCapability = {
17353
17485
  * handle. Slice shape is `{ zones: Zone[] }` so future extensions
17354
17486
  * (e.g. zone groupings) can sit alongside the polygon list.
17355
17487
  */
17356
- runtimeState: object({ zones: array(ZoneSchema).readonly() })
17488
+ runtimeState: object({ zones: array(ZoneSchema).readonly() }),
17489
+ /**
17490
+ * Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
17491
+ *
17492
+ * See `RuntimeStateDurability`. Enforced by
17493
+ * `scripts/check-runtime-state-durability.ts`.
17494
+ */
17495
+ durability: "restored"
17357
17496
  };
17358
17497
  /**
17359
17498
  * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
@@ -17523,6 +17662,22 @@ var detectionFpsField = {
17523
17662
  default: 10,
17524
17663
  step: 1
17525
17664
  };
17665
+ /**
17666
+ * The occupancy re-check interval. DEFAULT 300 s (2026-08-13 — was 30 s).
17667
+ *
17668
+ * The recheck is now on by default (a parked car is invisible to occupancy
17669
+ * rules until the stationary registry has been rebuilt by motion, which after a
17670
+ * restart may be never on a quiet camera). Each cycle re-subscribes a detection
17671
+ * session — an RTSP re-dial — so the switch is only affordable at a WIDE
17672
+ * interval: 300 s is ~12 re-dials an hour per camera, against 120 at the old
17673
+ * 30 s. A parked car is therefore counted within 5 minutes of a restart.
17674
+ *
17675
+ * Why not wider: `max` is 300 and raising it is TRAIN-BOUND, not addon-bound —
17676
+ * the host validates `attachCamera` against ITS copy of this schema, so a
17677
+ * runner asked for 600 would be rejected by the hub until a `@camstack/server`
17678
+ * carrying the wider bound is installed everywhere. 300 is the widest value
17679
+ * that ships with an addon deploy.
17680
+ */
17526
17681
  var occupancyRecheckSecField = {
17527
17682
  min: 0,
17528
17683
  max: 300,
@@ -17724,15 +17879,21 @@ var RunnerCameraConfigSchema = object({
17724
17879
  */
17725
17880
  onboardMotionDrivesAnalyzer: boolean().default(true),
17726
17881
  /**
17727
- * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
17728
- * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
17729
- * this is off by default because the recheck re-subscribes a detection session
17730
- * every N seconds while `watching`, a major source of pull-decoder re-dial
17731
- * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
17882
+ * Master toggle for the occupancy re-check. When `false` the runner never arms
17883
+ * the periodic recheck timer, regardless of `occupancyRecheckSec`; the
17732
17884
  * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
17733
17885
  * (and only render) when this is enabled.
17886
+ *
17887
+ * DEFAULT `true` since 2026-08-13 (was `false`). It was off because the
17888
+ * recheck re-subscribes a detection session every N seconds while `watching`
17889
+ * — each cycle creates+tears a session ⇒ an RTSP re-dial ⇒ latency, a major
17890
+ * pull-decoder churn source. What that bought was a blind spot: a STATIONARY
17891
+ * object is counted only while the stationary registry holds it, and the
17892
+ * registry rebuilds from motion, so after a restart a parked car was invisible
17893
+ * to every occupancy rule until something moved in front of it. The churn is
17894
+ * now paid on the interval instead — see `occupancyRecheckSecField`.
17734
17895
  */
17735
- occupancyRecheckEnabled: boolean().default(false),
17896
+ occupancyRecheckEnabled: boolean().default(true),
17736
17897
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
17737
17898
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
17738
17899
  /**
@@ -20152,7 +20313,17 @@ var airQualitySensorCapability = {
20152
20313
  schema: AirQualitySensorStatusSchema,
20153
20314
  kind: "push"
20154
20315
  },
20155
- runtimeState: AirQualitySensorStatusSchema
20316
+ runtimeState: AirQualitySensorStatusSchema,
20317
+ /**
20318
+ * Runtime-state durability: **restored** — as `numeric-sensor`.
20319
+ *
20320
+ * See `RuntimeStateDurability`. Enforced by
20321
+ * `scripts/check-runtime-state-durability.ts`.
20322
+ */
20323
+ durability: "restored",
20324
+ /** Clock fields: written, but excluded from the compare that decides
20325
+ * whether persisting is worth a SQLite commit. */
20326
+ volatileStateFields: ["lastFetchedAt"]
20156
20327
  };
20157
20328
  /**
20158
20329
  * Ambient illuminance reading in lux. Drives Home Assistant `sensor`
@@ -20184,7 +20355,17 @@ var ambientLightSensorCapability = {
20184
20355
  schema: AmbientLightSensorStatusSchema,
20185
20356
  kind: "push"
20186
20357
  },
20187
- runtimeState: AmbientLightSensorStatusSchema
20358
+ runtimeState: AmbientLightSensorStatusSchema,
20359
+ /**
20360
+ * Runtime-state durability: **restored** — as `numeric-sensor`.
20361
+ *
20362
+ * See `RuntimeStateDurability`. Enforced by
20363
+ * `scripts/check-runtime-state-durability.ts`.
20364
+ */
20365
+ durability: "restored",
20366
+ /** Clock fields: written, but excluded from the compare that decides
20367
+ * whether persisting is worth a SQLite commit. */
20368
+ volatileStateFields: ["lastFetchedAt"]
20188
20369
  };
20189
20370
  /**
20190
20371
  * Per-class audio metrics aggregated over a sliding window.
@@ -20302,7 +20483,14 @@ var audioMetricsCapability = {
20302
20483
  }), AudioMetricsHistorySchema)
20303
20484
  },
20304
20485
  /** Reactive runtime-state mirror — live `device.state.audioMetrics.value`. */
20305
- runtimeState: AudioMetricsSnapshotSchema
20486
+ runtimeState: AudioMetricsSnapshotSchema,
20487
+ /**
20488
+ * Runtime-state durability: **session** — 1 Hz per camera at the mirror and ~63 % of the fleet's whole runtime-state write rate. `avgDbfs` is a rolling 60 s mean that genuinely moves every second, so no equality fix reclaims it — and a two-hour-old dB reading rendered as current is worse than no reading.
20489
+ *
20490
+ * See `RuntimeStateDurability`. Enforced by
20491
+ * `scripts/check-runtime-state-durability.ts`.
20492
+ */
20493
+ durability: "session"
20306
20494
  };
20307
20495
  /**
20308
20496
  * Automation-control cap. Models HA `automation.*` entities on
@@ -20364,7 +20552,14 @@ var automationControlCapability = {
20364
20552
  * reads `enabled` (toggle) + `isRunning` (spinner) + `lastError`
20365
20553
  * (badge) directly.
20366
20554
  */
20367
- runtimeState: AutomationControlStatusSchema
20555
+ runtimeState: AutomationControlStatusSchema,
20556
+ /**
20557
+ * Runtime-state durability: **session** — the authority for an automation being enabled is the automation store; a restored `isRunning` would be a lie. D62: one authority per switch.
20558
+ *
20559
+ * See `RuntimeStateDurability`. Enforced by
20560
+ * `scripts/check-runtime-state-durability.ts`.
20561
+ */
20562
+ durability: "session"
20368
20563
  };
20369
20564
  /**
20370
20565
  * Battery status snapshot. Emitted by providers whose device is
@@ -20470,7 +20665,17 @@ onStatusChanged: { data: object({
20470
20665
  * via `device.runtimeState.getCapState('battery')` regardless of
20471
20666
  * the underlying driver.
20472
20667
  */
20473
- runtimeState: BatteryStatusSchema
20668
+ runtimeState: BatteryStatusSchema,
20669
+ /**
20670
+ * Runtime-state durability: **restored** — a sleeping battery camera may not report for hours; the restored percentage is the only thing the UI and the sleep gate have. Zero churn once `lastUpdated` is excluded — 526 writes, 0 value changes, in 25 minutes.
20671
+ *
20672
+ * See `RuntimeStateDurability`. Enforced by
20673
+ * `scripts/check-runtime-state-durability.ts`.
20674
+ */
20675
+ durability: "restored",
20676
+ /** Clock fields: written, but excluded from the compare that decides
20677
+ * whether persisting is worth a SQLite commit. */
20678
+ volatileStateFields: ["lastUpdated"]
20474
20679
  };
20475
20680
  /**
20476
20681
  * Generic boolean sensor — last-resort fallback when no domain-
@@ -20499,7 +20704,17 @@ var binaryCapability = {
20499
20704
  schema: BinaryStatusSchema,
20500
20705
  kind: "push"
20501
20706
  },
20502
- runtimeState: BinaryStatusSchema
20707
+ runtimeState: BinaryStatusSchema,
20708
+ /**
20709
+ * Runtime-state durability: **restored** — transition-driven sensor state; the restored value gives the boot comparison.
20710
+ *
20711
+ * See `RuntimeStateDurability`. Enforced by
20712
+ * `scripts/check-runtime-state-durability.ts`.
20713
+ */
20714
+ durability: "restored",
20715
+ /** Clock fields: written, but excluded from the compare that decides
20716
+ * whether persisting is worth a SQLite commit. */
20717
+ volatileStateFields: ["lastChangedAt"]
20503
20718
  };
20504
20719
  /**
20505
20720
  * Dimmable-light brightness control. Co-exists with `switch` on the
@@ -20552,7 +20767,14 @@ onBrightnessChanged: { data: object({
20552
20767
  * by the kernel. Read via `device.state.brightness.value` so UI
20553
20768
  * sliders surface the current level without polling the provider.
20554
20769
  */
20555
- runtimeState: BrightnessStatusSchema
20770
+ runtimeState: BrightnessStatusSchema,
20771
+ /**
20772
+ * Runtime-state durability: **session** — live lamp state, re-published by the provider on connect.
20773
+ *
20774
+ * See `RuntimeStateDurability`. Enforced by
20775
+ * `scripts/check-runtime-state-durability.ts`.
20776
+ */
20777
+ durability: "session"
20556
20778
  };
20557
20779
  /**
20558
20780
  * button — device-scoped capability for HA `button.*` / `input_button.*`
@@ -20657,7 +20879,17 @@ var carbonMonoxideCapability = {
20657
20879
  schema: CarbonMonoxideStatusSchema,
20658
20880
  kind: "push"
20659
20881
  },
20660
- runtimeState: CarbonMonoxideStatusSchema
20882
+ runtimeState: CarbonMonoxideStatusSchema,
20883
+ /**
20884
+ * Runtime-state durability: **restored** — as `smoke`.
20885
+ *
20886
+ * See `RuntimeStateDurability`. Enforced by
20887
+ * `scripts/check-runtime-state-durability.ts`.
20888
+ */
20889
+ durability: "restored",
20890
+ /** Clock fields: written, but excluded from the compare that decides
20891
+ * whether persisting is worth a SQLite commit. */
20892
+ volatileStateFields: ["lastChangedAt"]
20661
20893
  };
20662
20894
  /**
20663
20895
  * HVAC / climate control cap. Models the full surface of a HA
@@ -20817,7 +21049,14 @@ var climateControlCapability = {
20817
21049
  * the full slice via `device.state.climate-control.value` and refresh
20818
21050
  * on every push without re-querying the provider.
20819
21051
  */
20820
- runtimeState: ClimateControlStatusSchema
21052
+ runtimeState: ClimateControlStatusSchema,
21053
+ /**
21054
+ * Runtime-state durability: **session** — as `brightness`; `currentTemp` moves continuously and is re-published on connect.
21055
+ *
21056
+ * See `RuntimeStateDurability`. Enforced by
21057
+ * `scripts/check-runtime-state-durability.ts`.
21058
+ */
21059
+ durability: "session"
20821
21060
  };
20822
21061
  /**
20823
21062
  * Color-light cap. Coexists with `switch` (on/off) and `brightness`
@@ -20927,7 +21166,14 @@ onColorChanged: { data: object({
20927
21166
  * kernel. Read via `device.state.color.value` so UI pickers surface
20928
21167
  * the current chromaticity without polling the provider.
20929
21168
  */
20930
- runtimeState: ColorStatusSchema
21169
+ runtimeState: ColorStatusSchema,
21170
+ /**
21171
+ * Runtime-state durability: **session** — as `brightness`.
21172
+ *
21173
+ * See `RuntimeStateDurability`. Enforced by
21174
+ * `scripts/check-runtime-state-durability.ts`.
21175
+ */
21176
+ durability: "session"
20931
21177
  };
20932
21178
  var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
20933
21179
  object({
@@ -20985,7 +21231,17 @@ var connectivityCapability = {
20985
21231
  schema: ConnectivityStatusSchema,
20986
21232
  kind: "push"
20987
21233
  },
20988
- runtimeState: ConnectivityStatusSchema
21234
+ runtimeState: ConnectivityStatusSchema,
21235
+ /**
21236
+ * Runtime-state durability: **restored** — same shape and same argument as `device-status`, for links rather than devices.
21237
+ *
21238
+ * See `RuntimeStateDurability`. Enforced by
21239
+ * `scripts/check-runtime-state-durability.ts`.
21240
+ */
21241
+ durability: "restored",
21242
+ /** Clock fields: written, but excluded from the compare that decides
21243
+ * whether persisting is worth a SQLite commit. */
21244
+ volatileStateFields: ["lastChangedAt"]
20989
21245
  };
20990
21246
  /**
20991
21247
  * Generic device-consumables capability — surfaces a device's
@@ -21067,7 +21323,14 @@ reset: method(object({
21067
21323
  }
21068
21324
  }
21069
21325
  },
21070
- runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: number() })
21326
+ runtimeState: ConsumablesStatusSchema.extend({ lastFetchedAt: number() }),
21327
+ /**
21328
+ * Runtime-state durability: **session** — the authority is the appliance; the provider re-reads the whole item array on connect.
21329
+ *
21330
+ * See `RuntimeStateDurability`. Enforced by
21331
+ * `scripts/check-runtime-state-durability.ts`.
21332
+ */
21333
+ durability: "session"
21071
21334
  };
21072
21335
  /**
21073
21336
  * Door / window / opening / garage / valve contact sensor. Boolean
@@ -21098,7 +21361,17 @@ var contactCapability = {
21098
21361
  schema: ContactStatusSchema,
21099
21362
  kind: "push"
21100
21363
  },
21101
- runtimeState: ContactStatusSchema
21364
+ runtimeState: ContactStatusSchema,
21365
+ /**
21366
+ * Runtime-state durability: **restored** — a door left open across a restart must still read open.
21367
+ *
21368
+ * See `RuntimeStateDurability`. Enforced by
21369
+ * `scripts/check-runtime-state-durability.ts`.
21370
+ */
21371
+ durability: "restored",
21372
+ /** Clock fields: written, but excluded from the compare that decides
21373
+ * whether persisting is worth a SQLite commit. */
21374
+ volatileStateFields: ["lastChangedAt"]
21102
21375
  };
21103
21376
  /**
21104
21377
  * Status slice — flat object (the framework's `runtimeState` contract
@@ -21204,7 +21477,14 @@ var controlCapability = {
21204
21477
  * dropdown / text field / date picker) read the slice's discriminant
21205
21478
  * and value directly without polling the provider.
21206
21479
  */
21207
- runtimeState: ControlStatusSchema
21480
+ runtimeState: ControlStatusSchema,
21481
+ /**
21482
+ * Runtime-state durability: **session** — a generic control mirrors an external entity that re-publishes on connect; the options array is re-derived with it.
21483
+ *
21484
+ * See `RuntimeStateDurability`. Enforced by
21485
+ * `scripts/check-runtime-state-durability.ts`.
21486
+ */
21487
+ durability: "session"
21208
21488
  };
21209
21489
  var CoverStatusSchema = object({
21210
21490
  /** Lifecycle state of the cover. */
@@ -21265,7 +21545,17 @@ var coverCapability = {
21265
21545
  * Runtime-state slice — mirrored by the kernel. UI controls watch
21266
21546
  * the slice for live position changes during a move.
21267
21547
  */
21268
- runtimeState: CoverStatusSchema
21548
+ runtimeState: CoverStatusSchema,
21549
+ /**
21550
+ * Runtime-state durability: **restored** — position survives a restart on the device; the mirror should agree at boot rather than read blank.
21551
+ *
21552
+ * See `RuntimeStateDurability`. Enforced by
21553
+ * `scripts/check-runtime-state-durability.ts`.
21554
+ */
21555
+ durability: "restored",
21556
+ /** Clock fields: written, but excluded from the compare that decides
21557
+ * whether persisting is worth a SQLite commit. */
21558
+ volatileStateFields: ["lastChangedAt"]
21269
21559
  };
21270
21560
  /**
21271
21561
  * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
@@ -21359,7 +21649,17 @@ var dayNightCapability = {
21359
21649
  schema: DayNightStatusSchema,
21360
21650
  kind: "poll"
21361
21651
  },
21362
- runtimeState: DayNightStatusSchema
21652
+ runtimeState: DayNightStatusSchema,
21653
+ /**
21654
+ * Runtime-state durability: **restored** — operator-set IR-cut behaviour; mutation-driven.
21655
+ *
21656
+ * See `RuntimeStateDurability`. Enforced by
21657
+ * `scripts/check-runtime-state-durability.ts`.
21658
+ */
21659
+ durability: "restored",
21660
+ /** Clock fields: written, but excluded from the compare that decides
21661
+ * whether persisting is worth a SQLite commit. */
21662
+ volatileStateFields: ["lastFetchedAt"]
21363
21663
  };
21364
21664
  /**
21365
21665
  * Generic device-level status snapshot. Auto-registered by `BaseDevice`
@@ -21406,7 +21706,17 @@ onStatusChanged: { data: object({
21406
21706
  schema: DeviceStatusSchema,
21407
21707
  kind: "push"
21408
21708
  },
21409
- runtimeState: DeviceStatusSchema
21709
+ runtimeState: DeviceStatusSchema,
21710
+ /**
21711
+ * Runtime-state durability: **restored** — the previous observation is what makes the first reading after a restart a COMPARISON instead of a phantom transition (D130). 32 real flips across 16 devices in 25 min — the busiest slice in the cold half.
21712
+ *
21713
+ * See `RuntimeStateDurability`. Enforced by
21714
+ * `scripts/check-runtime-state-durability.ts`.
21715
+ */
21716
+ durability: "restored",
21717
+ /** Clock fields: written, but excluded from the compare that decides
21718
+ * whether persisting is worth a SQLite commit. */
21719
+ volatileStateFields: ["lastChangedAt"]
21410
21720
  };
21411
21721
  /**
21412
21722
  * Doorbell button cap. Two kinds of providers coexist behind this cap
@@ -21468,7 +21778,14 @@ onPressed: { data: DoorbellPressEventSchema } },
21468
21778
  * `device.state.doorbell.value`. UIs can show "last ring 5m ago"
21469
21779
  * without subscribing.
21470
21780
  */
21471
- runtimeState: DoorbellStatusSchema
21781
+ runtimeState: DoorbellStatusSchema,
21782
+ /**
21783
+ * Runtime-state durability: **restored** — a monotonic accumulator: the slice IS the record. `lastPressedAt` is content here, not a clock, so it is deliberately NOT volatile.
21784
+ *
21785
+ * See `RuntimeStateDurability`. Enforced by
21786
+ * `scripts/check-runtime-state-durability.ts`.
21787
+ */
21788
+ durability: "restored"
21472
21789
  };
21473
21790
  /**
21474
21791
  * Enum-state sensor — a string value picked from a finite option set.
@@ -21508,7 +21825,17 @@ var enumSensorCapability = {
21508
21825
  schema: EnumSensorStatusSchema,
21509
21826
  kind: "push"
21510
21827
  },
21511
- runtimeState: EnumSensorStatusSchema
21828
+ runtimeState: EnumSensorStatusSchema,
21829
+ /**
21830
+ * Runtime-state durability: **restored** — as `numeric-sensor`; 80 devices.
21831
+ *
21832
+ * See `RuntimeStateDurability`. Enforced by
21833
+ * `scripts/check-runtime-state-durability.ts`.
21834
+ */
21835
+ durability: "restored",
21836
+ /** Clock fields: written, but excluded from the compare that decides
21837
+ * whether persisting is worth a SQLite commit. */
21838
+ volatileStateFields: ["lastFetchedAt"]
21512
21839
  };
21513
21840
  /**
21514
21841
  * Generic stateless event emitter. Installed on a `DeviceType.EventEmitter`
@@ -21544,7 +21871,14 @@ var eventEmitterCapability = {
21544
21871
  schema: EventEmitterStatusSchema,
21545
21872
  kind: "push"
21546
21873
  },
21547
- runtimeState: EventEmitterStatusSchema
21874
+ runtimeState: EventEmitterStatusSchema,
21875
+ /**
21876
+ * Runtime-state durability: **session** — `eventCountSinceStart` names its own scope.
21877
+ *
21878
+ * See `RuntimeStateDurability`. Enforced by
21879
+ * `scripts/check-runtime-state-durability.ts`.
21880
+ */
21881
+ durability: "session"
21548
21882
  };
21549
21883
  var EventItemSchema = object({
21550
21884
  id: string$2(),
@@ -21825,7 +22159,14 @@ var fanControlCapability = {
21825
22159
  * Runtime-state slice — mirrored by the kernel. UI fan speed
21826
22160
  * sliders read `percentage` for live updates.
21827
22161
  */
21828
- runtimeState: FanControlStatusSchema
22162
+ runtimeState: FanControlStatusSchema,
22163
+ /**
22164
+ * Runtime-state durability: **session** — as `brightness`.
22165
+ *
22166
+ * See `RuntimeStateDurability`. Enforced by
22167
+ * `scripts/check-runtime-state-durability.ts`.
22168
+ */
22169
+ durability: "session"
21829
22170
  };
21830
22171
  /**
21831
22172
  * Per-device feature/identity probe slice. Holds the runtime-resolved
@@ -21901,7 +22242,14 @@ onProbeChanged: { data: object({
21901
22242
  schema: FeatureProbeStatusSchema,
21902
22243
  kind: "push"
21903
22244
  },
21904
- runtimeState: FeatureProbeStatusSchema
22245
+ runtimeState: FeatureProbeStatusSchema,
22246
+ /**
22247
+ * Runtime-state durability: **session** — per-session by definition — `lastProbedAt` means "this worker completed a probe THIS session", which is why the mirror seed already blanks it. Persisting it only creates something to blank.
22248
+ *
22249
+ * See `RuntimeStateDurability`. Enforced by
22250
+ * `scripts/check-runtime-state-durability.ts`.
22251
+ */
22252
+ durability: "session"
21905
22253
  };
21906
22254
  /**
21907
22255
  * Water leak / moisture sensor. Boolean "is liquid currently
@@ -21928,7 +22276,17 @@ var floodCapability = {
21928
22276
  schema: FloodStatusSchema,
21929
22277
  kind: "push"
21930
22278
  },
21931
- runtimeState: FloodStatusSchema
22279
+ runtimeState: FloodStatusSchema,
22280
+ /**
22281
+ * Runtime-state durability: **restored** — as `smoke`.
22282
+ *
22283
+ * See `RuntimeStateDurability`. Enforced by
22284
+ * `scripts/check-runtime-state-durability.ts`.
22285
+ */
22286
+ durability: "restored",
22287
+ /** Clock fields: written, but excluded from the compare that decides
22288
+ * whether persisting is worth a SQLite commit. */
22289
+ volatileStateFields: ["lastChangedAt"]
21932
22290
  };
21933
22291
  /**
21934
22292
  * Combustible-gas (LPG / methane / hydrogen) alarm sensor. Drives
@@ -21951,7 +22309,17 @@ var gasCapability = {
21951
22309
  schema: GasStatusSchema,
21952
22310
  kind: "push"
21953
22311
  },
21954
- runtimeState: GasStatusSchema
22312
+ runtimeState: GasStatusSchema,
22313
+ /**
22314
+ * Runtime-state durability: **restored** — as `smoke`.
22315
+ *
22316
+ * See `RuntimeStateDurability`. Enforced by
22317
+ * `scripts/check-runtime-state-durability.ts`.
22318
+ */
22319
+ durability: "restored",
22320
+ /** Clock fields: written, but excluded from the compare that decides
22321
+ * whether persisting is worth a SQLite commit. */
22322
+ volatileStateFields: ["lastChangedAt"]
21955
22323
  };
21956
22324
  /**
21957
22325
  * Humidifier / dehumidifier cap. Models HA `humidifier.*` entities —
@@ -22027,7 +22395,14 @@ var humidifierCapability = {
22027
22395
  * Runtime-state slice — mirrored by the kernel. UI controls watch the
22028
22396
  * slice for live humidity / mode changes.
22029
22397
  */
22030
- runtimeState: HumidifierStatusSchema
22398
+ runtimeState: HumidifierStatusSchema,
22399
+ /**
22400
+ * Runtime-state durability: **session** — as `climate-control`.
22401
+ *
22402
+ * See `RuntimeStateDurability`. Enforced by
22403
+ * `scripts/check-runtime-state-durability.ts`.
22404
+ */
22405
+ durability: "session"
22031
22406
  };
22032
22407
  /**
22033
22408
  * Single-metric humidity reading. Drives Home Assistant `sensor`
@@ -22063,7 +22438,17 @@ var humiditySensorCapability = {
22063
22438
  schema: HumiditySensorStatusSchema,
22064
22439
  kind: "push"
22065
22440
  },
22066
- runtimeState: HumiditySensorStatusSchema
22441
+ runtimeState: HumiditySensorStatusSchema,
22442
+ /**
22443
+ * Runtime-state durability: **restored** — as `numeric-sensor` (67 of 75 writes were the clock alone).
22444
+ *
22445
+ * See `RuntimeStateDurability`. Enforced by
22446
+ * `scripts/check-runtime-state-durability.ts`.
22447
+ */
22448
+ durability: "restored",
22449
+ /** Clock fields: written, but excluded from the compare that decides
22450
+ * whether persisting is worth a SQLite commit. */
22451
+ volatileStateFields: ["lastFetchedAt"]
22067
22452
  };
22068
22453
  /**
22069
22454
  * Image display cap. Models a single still image exposed by an integration —
@@ -22101,7 +22486,14 @@ var imageCapability = {
22101
22486
  * Runtime-state slice — mirrored by the kernel. The UI reads `url`
22102
22487
  * directly and renders the still image.
22103
22488
  */
22104
- runtimeState: ImageStatusSchema
22489
+ runtimeState: ImageStatusSchema,
22490
+ /**
22491
+ * Runtime-state durability: **session** — a snapshot URL is a session-scoped handle; a restored one points at nothing.
22492
+ *
22493
+ * See `RuntimeStateDurability`. Enforced by
22494
+ * `scripts/check-runtime-state-durability.ts`.
22495
+ */
22496
+ durability: "session"
22105
22497
  };
22106
22498
  /**
22107
22499
  * Vendor-neutral image / picture-adjustment cap — the per-camera config
@@ -22250,7 +22642,17 @@ var imageSettingsCapability = {
22250
22642
  schema: ImageSettingsStatusSchema,
22251
22643
  kind: "poll"
22252
22644
  },
22253
- runtimeState: ImageSettingsStatusSchema
22645
+ runtimeState: ImageSettingsStatusSchema,
22646
+ /**
22647
+ * Runtime-state durability: **restored** — operator-set camera imaging; mutation-driven.
22648
+ *
22649
+ * See `RuntimeStateDurability`. Enforced by
22650
+ * `scripts/check-runtime-state-durability.ts`.
22651
+ */
22652
+ durability: "restored",
22653
+ /** Clock fields: written, but excluded from the compare that decides
22654
+ * whether persisting is worth a SQLite commit. */
22655
+ volatileStateFields: ["lastFetchedAt"]
22254
22656
  };
22255
22657
  /**
22256
22658
  * integrations — system-scoped singleton capability for integration
@@ -22590,7 +22992,14 @@ var lawnMowerControlCapability = {
22590
22992
  * Runtime-state slice — mirrored by the kernel. UI controls watch the
22591
22993
  * slice for live activity + battery changes.
22592
22994
  */
22593
- runtimeState: LawnMowerControlStatusSchema
22995
+ runtimeState: LawnMowerControlStatusSchema,
22996
+ /**
22997
+ * Runtime-state durability: **session** — as `vacuum-control`.
22998
+ *
22999
+ * See `RuntimeStateDurability`. Enforced by
23000
+ * `scripts/check-runtime-state-durability.ts`.
23001
+ */
23002
+ durability: "session"
22594
23003
  };
22595
23004
  /**
22596
23005
  * local-network — hub-only singleton.
@@ -22796,7 +23205,17 @@ var lockControlCapability = {
22796
23205
  * read `state` and disable themselves during `locking`/`unlocking`
22797
23206
  * transitions.
22798
23207
  */
22799
- runtimeState: LockControlStatusSchema
23208
+ runtimeState: LockControlStatusSchema,
23209
+ /**
23210
+ * Runtime-state durability: **restored** — a lock left locked must still read locked.
23211
+ *
23212
+ * See `RuntimeStateDurability`. Enforced by
23213
+ * `scripts/check-runtime-state-durability.ts`.
23214
+ */
23215
+ durability: "restored",
23216
+ /** Clock fields: written, but excluded from the compare that decides
23217
+ * whether persisting is worth a SQLite commit. */
23218
+ volatileStateFields: ["lastChangedAt"]
22800
23219
  };
22801
23220
  /**
22802
23221
  * Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
@@ -22958,7 +23377,14 @@ var mediaPlayerCapability = {
22958
23377
  * full slice for live now-playing, volume, and progress updates
22959
23378
  * without polling.
22960
23379
  */
22961
- runtimeState: MediaPlayerStatusSchema
23380
+ runtimeState: MediaPlayerStatusSchema,
23381
+ /**
23382
+ * Runtime-state durability: **session** — a restored transport position describes a playback that stopped when the hub did.
23383
+ *
23384
+ * See `RuntimeStateDurability`. Enforced by
23385
+ * `scripts/check-runtime-state-durability.ts`.
23386
+ */
23387
+ durability: "session"
22962
23388
  };
22963
23389
  /**
22964
23390
  * mesh-network — collection cap for mesh-VPN providers.
@@ -23222,7 +23648,14 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
23222
23648
  * `device.state.motion.value`. Reads never invoke the provider, so
23223
23649
  * UIs and other addons can poll the cached state safely.
23224
23650
  */
23225
- runtimeState: MotionStatusSchema
23651
+ runtimeState: MotionStatusSchema,
23652
+ /**
23653
+ * Runtime-state durability: **session** — self-clearing by construction (`autoClearAfterMs`); a restored `detected: true` is a frozen event, and the next frame re-publishes the real one.
23654
+ *
23655
+ * See `RuntimeStateDurability`. Enforced by
23656
+ * `scripts/check-runtime-state-durability.ts`.
23657
+ */
23658
+ durability: "session"
23226
23659
  };
23227
23660
  /**
23228
23661
  * Motion-trigger toggle for accessory devices.
@@ -23287,7 +23720,14 @@ var motionTriggerCapability = {
23287
23720
  schema: MotionTriggerStatusSchema,
23288
23721
  kind: "command-driven"
23289
23722
  },
23290
- runtimeState: MotionTriggerRuntimeStateSchema
23723
+ runtimeState: MotionTriggerRuntimeStateSchema,
23724
+ /**
23725
+ * Runtime-state durability: **session** — the authority for motion-trigger enablement is the provider's own config; the slice is a mirror of it, re-published on connect.
23726
+ *
23727
+ * See `RuntimeStateDurability`. Enforced by
23728
+ * `scripts/check-runtime-state-durability.ts`.
23729
+ */
23730
+ durability: "session"
23291
23731
  };
23292
23732
  /**
23293
23733
  * Motion-zones share the same MaskShape vocabulary as privacy-mask — the
@@ -23354,7 +23794,17 @@ var motionZonesCapability = {
23354
23794
  schema: MotionZoneStatusSchema,
23355
23795
  kind: "poll"
23356
23796
  },
23357
- runtimeState: MotionZoneStatusSchema
23797
+ runtimeState: MotionZoneStatusSchema,
23798
+ /**
23799
+ * Runtime-state durability: **restored** — the 14 KB polygon list is the single largest slice on the fleet and has not changed since the operator drew it. Highest value per byte in the table.
23800
+ *
23801
+ * See `RuntimeStateDurability`. Enforced by
23802
+ * `scripts/check-runtime-state-durability.ts`.
23803
+ */
23804
+ durability: "restored",
23805
+ /** Clock fields: written, but excluded from the compare that decides
23806
+ * whether persisting is worth a SQLite commit. */
23807
+ volatileStateFields: ["lastFetchedAt"]
23358
23808
  };
23359
23809
  /**
23360
23810
  * On-camera AI object detection cap. Surfaces per-device the classes
@@ -23428,7 +23878,17 @@ var nativeObjectDetectionCapability = {
23428
23878
  schema: NativeObjectDetectionStatusSchema,
23429
23879
  kind: "push"
23430
23880
  },
23431
- runtimeState: NativeObjectDetectionRuntimeStateSchema
23881
+ runtimeState: NativeObjectDetectionRuntimeStateSchema,
23882
+ /**
23883
+ * Runtime-state durability: **restored** — `enabled` is an operator toggle on a camera whose refresh is a no-op and whose staleMs is Infinity. There is no hardware value to re-read — losing it loses the setting.
23884
+ *
23885
+ * See `RuntimeStateDurability`. Enforced by
23886
+ * `scripts/check-runtime-state-durability.ts`.
23887
+ */
23888
+ durability: "restored",
23889
+ /** Clock fields: written, but excluded from the compare that decides
23890
+ * whether persisting is worth a SQLite commit. */
23891
+ volatileStateFields: ["lastFetchedAt"]
23432
23892
  };
23433
23893
  /**
23434
23894
  * network-quality — system-scoped singleton capability tracking RTT,
@@ -23762,7 +24222,14 @@ onSent: { data: object({
23762
24222
  * form reads `supports` to gate optional fields; history pane reads
23763
24223
  * `lastSentAt` / `lastError` / `queueDepth`.
23764
24224
  */
23765
- runtimeState: NotifierStatusSchema
24225
+ runtimeState: NotifierStatusSchema,
24226
+ /**
24227
+ * Runtime-state durability: **session** — live queue depth and last-send state; a restored queue depth describes a queue that no longer exists.
24228
+ *
24229
+ * See `RuntimeStateDurability`. Enforced by
24230
+ * `scripts/check-runtime-state-durability.ts`.
24231
+ */
24232
+ durability: "session"
23766
24233
  };
23767
24234
  /**
23768
24235
  * Generic numeric sensor — last-resort fallback when no typed numeric
@@ -23805,7 +24272,17 @@ var numericSensorCapability = {
23805
24272
  schema: NumericSensorStatusSchema,
23806
24273
  kind: "push"
23807
24274
  },
23808
- runtimeState: NumericSensorStatusSchema
24275
+ runtimeState: NumericSensorStatusSchema,
24276
+ /**
24277
+ * Runtime-state durability: **restored** — polled value, low churn once the clock is excluded (251 of 669 writes were the clock alone); restoring it removes the cold window before the first poll.
24278
+ *
24279
+ * See `RuntimeStateDurability`. Enforced by
24280
+ * `scripts/check-runtime-state-durability.ts`.
24281
+ */
24282
+ durability: "restored",
24283
+ /** Clock fields: written, but excluded from the compare that decides
24284
+ * whether persisting is worth a SQLite commit. */
24285
+ volatileStateFields: ["lastFetchedAt"]
23809
24286
  };
23810
24287
  /**
23811
24288
  * Generic on-screen-display (video overlay) cap. Each camera exposes
@@ -24190,7 +24667,14 @@ var petFeederCapability = {
24190
24667
  * the full slice via `device.state.petFeeder.value` and refresh on
24191
24668
  * every poll without re-querying the provider.
24192
24669
  */
24193
- runtimeState: PetFeederStatusSchema
24670
+ runtimeState: PetFeederStatusSchema,
24671
+ /**
24672
+ * Runtime-state durability: **session** — live appliance state re-published on connect.
24673
+ *
24674
+ * See `RuntimeStateDurability`. Enforced by
24675
+ * `scripts/check-runtime-state-durability.ts`.
24676
+ */
24677
+ durability: "session"
24194
24678
  };
24195
24679
  var VehicleSchema = object({
24196
24680
  id: string$2(),
@@ -24502,7 +24986,17 @@ var powerMeterCapability = {
24502
24986
  schema: PowerMeterStatusSchema,
24503
24987
  kind: "push"
24504
24988
  },
24505
- runtimeState: PowerMeterStatusSchema
24989
+ runtimeState: PowerMeterStatusSchema,
24990
+ /**
24991
+ * Runtime-state durability: **restored** — as `numeric-sensor`; `kwhTotal` is an accumulator whose restored value is the baseline.
24992
+ *
24993
+ * See `RuntimeStateDurability`. Enforced by
24994
+ * `scripts/check-runtime-state-durability.ts`.
24995
+ */
24996
+ durability: "restored",
24997
+ /** Clock fields: written, but excluded from the compare that decides
24998
+ * whether persisting is worth a SQLite commit. */
24999
+ volatileStateFields: ["lastFetchedAt"]
24506
25000
  };
24507
25001
  /**
24508
25002
  * Presence cap. Models HA `person.*` and `device_tracker.*` entities
@@ -24559,7 +25053,17 @@ var presenceCapability = {
24559
25053
  * the map pin is rendered (use `DeviceFeature.PresenceGps` for the
24560
25054
  * pre-fetch fast-path check).
24561
25055
  */
24562
- runtimeState: PresenceStatusSchema
25056
+ runtimeState: PresenceStatusSchema,
25057
+ /**
25058
+ * Runtime-state durability: **restored** — occupancy-relevant: the restored state is what an occupancy rule compares the first post-restart observation against.
25059
+ *
25060
+ * See `RuntimeStateDurability`. Enforced by
25061
+ * `scripts/check-runtime-state-durability.ts`.
25062
+ */
25063
+ durability: "restored",
25064
+ /** Clock fields: written, but excluded from the compare that decides
25065
+ * whether persisting is worth a SQLite commit. */
25066
+ volatileStateFields: ["lastChangedAt"]
24563
25067
  };
24564
25068
  /**
24565
25069
  * Atmospheric pressure reading in hectopascals. Drives Home Assistant
@@ -24595,7 +25099,17 @@ var pressureSensorCapability = {
24595
25099
  schema: PressureSensorStatusSchema,
24596
25100
  kind: "push"
24597
25101
  },
24598
- runtimeState: PressureSensorStatusSchema
25102
+ runtimeState: PressureSensorStatusSchema,
25103
+ /**
25104
+ * Runtime-state durability: **restored** — as `numeric-sensor`.
25105
+ *
25106
+ * See `RuntimeStateDurability`. Enforced by
25107
+ * `scripts/check-runtime-state-durability.ts`.
25108
+ */
25109
+ durability: "restored",
25110
+ /** Clock fields: written, but excluded from the compare that decides
25111
+ * whether persisting is worth a SQLite commit. */
25112
+ volatileStateFields: ["lastFetchedAt"]
24599
25113
  };
24600
25114
  /**
24601
25115
  * PRIVACY — what the camera deliberately does not capture. Two planes:
@@ -24725,7 +25239,17 @@ var privacyMaskCapability = {
24725
25239
  schema: PrivacyMaskStatusSchema,
24726
25240
  kind: "poll"
24727
25241
  },
24728
- runtimeState: PrivacyMaskStatusSchema
25242
+ runtimeState: PrivacyMaskStatusSchema,
25243
+ /**
25244
+ * Runtime-state durability: **restored** — operator-drawn regions, zero real churn — 22 writes in 25 minutes, every one of them the clock.
25245
+ *
25246
+ * See `RuntimeStateDurability`. Enforced by
25247
+ * `scripts/check-runtime-state-durability.ts`.
25248
+ */
25249
+ durability: "restored",
25250
+ /** Clock fields: written, but excluded from the compare that decides
25251
+ * whether persisting is worth a SQLite commit. */
25252
+ volatileStateFields: ["lastFetchedAt"]
24729
25253
  };
24730
25254
  var PtzPresetSchema = object({
24731
25255
  id: string$2(),
@@ -24891,7 +25415,14 @@ var ptzAutotrackCapability = {
24891
25415
  * fetch / cache / fallback logic out of the four cap methods —
24892
25416
  * they become trampolines over `runtimeState`.
24893
25417
  */
24894
- runtimeState: PtzAutotrackRuntimeStateSchema
25418
+ runtimeState: PtzAutotrackRuntimeStateSchema,
25419
+ /**
25420
+ * Runtime-state durability: **session** — mirrors the camera's own autotrack config, re-read on connect.
25421
+ *
25422
+ * See `RuntimeStateDurability`. Enforced by
25423
+ * `scripts/check-runtime-state-durability.ts`.
25424
+ */
25425
+ durability: "session"
24895
25426
  };
24896
25427
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
24897
25428
  kind: "mutation",
@@ -25541,7 +26072,14 @@ var sceneMonitorCapability = {
25541
26072
  schema: SceneMonitorStatusSchema,
25542
26073
  kind: "push"
25543
26074
  },
25544
- runtimeState: SceneMonitorStatusSchema
26075
+ runtimeState: SceneMonitorStatusSchema,
26076
+ /**
26077
+ * Runtime-state durability: **session** — re-derived from the current scene on the next evaluation.
26078
+ *
26079
+ * See `RuntimeStateDurability`. Enforced by
26080
+ * `scripts/check-runtime-state-durability.ts`.
26081
+ */
26082
+ durability: "session"
25545
26083
  };
25546
26084
  /**
25547
26085
  * Per-stage gating mode applied to the zones a rule references.
@@ -25685,7 +26223,14 @@ var scriptRunnerCapability = {
25685
26223
  * `isRunning` to render a spinner during execution and surfaces
25686
26224
  * `lastError` / `lastRunSuccess` in the recent-runs panel.
25687
26225
  */
25688
- runtimeState: ScriptRunnerStatusSchema
26226
+ runtimeState: ScriptRunnerStatusSchema,
26227
+ /**
26228
+ * Runtime-state durability: **session** — a restored `isRunning: true` describes a process that died with the previous hub.
26229
+ *
26230
+ * See `RuntimeStateDurability`. Enforced by
26231
+ * `scripts/check-runtime-state-durability.ts`.
26232
+ */
26233
+ durability: "session"
25689
26234
  };
25690
26235
  /**
25691
26236
  * Smoke alarm sensor — boolean "is smoke currently detected" with
@@ -25712,7 +26257,17 @@ var smokeCapability = {
25712
26257
  schema: SmokeStatusSchema,
25713
26258
  kind: "push"
25714
26259
  },
25715
- runtimeState: SmokeStatusSchema
26260
+ runtimeState: SmokeStatusSchema,
26261
+ /**
26262
+ * Runtime-state durability: **restored** — a safety sensor must not read "clear" merely because the hub restarted.
26263
+ *
26264
+ * See `RuntimeStateDurability`. Enforced by
26265
+ * `scripts/check-runtime-state-durability.ts`.
26266
+ */
26267
+ durability: "restored",
26268
+ /** Clock fields: written, but excluded from the compare that decides
26269
+ * whether persisting is worth a SQLite commit. */
26270
+ volatileStateFields: ["lastChangedAt"]
25716
26271
  };
25717
26272
  /**
25718
26273
  * One publishable camera stream as its OWNING PROVIDER describes it — the same
@@ -25885,7 +26440,17 @@ var streamParamsCapability = {
25885
26440
  schema: StreamParamsStatusSchema,
25886
26441
  kind: "poll"
25887
26442
  },
25888
- runtimeState: StreamParamsStatusSchema
26443
+ runtimeState: StreamParamsStatusSchema,
26444
+ /**
26445
+ * Runtime-state durability: **restored** — operator-set encoder profile; mutation-driven.
26446
+ *
26447
+ * See `RuntimeStateDurability`. Enforced by
26448
+ * `scripts/check-runtime-state-durability.ts`.
26449
+ */
26450
+ durability: "restored",
26451
+ /** Clock fields: written, but excluded from the compare that decides
26452
+ * whether persisting is worth a SQLite commit. */
26453
+ volatileStateFields: ["lastFetchedAt"]
25889
26454
  };
25890
26455
  /**
25891
26456
  * Generic on/off switch cap for accessory children (siren, floodlight,
@@ -25931,6 +26496,16 @@ var switchCapability = {
25931
26496
  * not need to re-query the provider after a setState mutation.
25932
26497
  */
25933
26498
  runtimeState: SwitchStatusSchema,
26499
+ /**
26500
+ * Runtime-state durability: **restored** — device state an operator reads as authoritative; 55 devices, transition-driven.
26501
+ *
26502
+ * See `RuntimeStateDurability`. Enforced by
26503
+ * `scripts/check-runtime-state-durability.ts`.
26504
+ */
26505
+ durability: "restored",
26506
+ /** Clock fields: written, but excluded from the compare that decides
26507
+ * whether persisting is worth a SQLite commit. */
26508
+ volatileStateFields: ["lastChangedAt"],
25934
26509
  settings: { bindings: [{
25935
26510
  kind: "scalar",
25936
26511
  statusPath: "on",
@@ -26010,7 +26585,17 @@ var tamperCapability = {
26010
26585
  schema: TamperStatusSchema,
26011
26586
  kind: "push"
26012
26587
  },
26013
- runtimeState: TamperStatusSchema
26588
+ runtimeState: TamperStatusSchema,
26589
+ /**
26590
+ * Runtime-state durability: **restored** — as `smoke`.
26591
+ *
26592
+ * See `RuntimeStateDurability`. Enforced by
26593
+ * `scripts/check-runtime-state-durability.ts`.
26594
+ */
26595
+ durability: "restored",
26596
+ /** Clock fields: written, but excluded from the compare that decides
26597
+ * whether persisting is worth a SQLite commit. */
26598
+ volatileStateFields: ["lastChangedAt"]
26014
26599
  };
26015
26600
  /**
26016
26601
  * Single-metric temperature reading. Drives Home Assistant `sensor`
@@ -26055,7 +26640,17 @@ var temperatureSensorCapability = {
26055
26640
  schema: TemperatureSensorStatusSchema,
26056
26641
  kind: "push"
26057
26642
  },
26058
- runtimeState: TemperatureSensorStatusSchema
26643
+ runtimeState: TemperatureSensorStatusSchema,
26644
+ /**
26645
+ * Runtime-state durability: **restored** — as `numeric-sensor` (69 of 125 writes were the clock alone).
26646
+ *
26647
+ * See `RuntimeStateDurability`. Enforced by
26648
+ * `scripts/check-runtime-state-durability.ts`.
26649
+ */
26650
+ durability: "restored",
26651
+ /** Clock fields: written, but excluded from the compare that decides
26652
+ * whether persisting is worth a SQLite commit. */
26653
+ volatileStateFields: ["lastFetchedAt"]
26059
26654
  };
26060
26655
  /**
26061
26656
  * toast — system-scoped singleton capability that streams toast
@@ -26124,7 +26719,14 @@ var updateCapability = {
26124
26719
  schema: UpdateStatusSchema,
26125
26720
  kind: "poll"
26126
26721
  },
26127
- runtimeState: UpdateStatusSchema
26722
+ runtimeState: UpdateStatusSchema,
26723
+ /**
26724
+ * Runtime-state durability: **session** — a restored `inProgress: true` describes an update that is no longer running; versions are re-probed at boot.
26725
+ *
26726
+ * See `RuntimeStateDurability`. Enforced by
26727
+ * `scripts/check-runtime-state-durability.ts`.
26728
+ */
26729
+ durability: "session"
26128
26730
  };
26129
26731
  var UserSummarySchema = object({
26130
26732
  id: string$2(),
@@ -26458,7 +27060,14 @@ var vacuumControlCapability = {
26458
27060
  * Runtime-state slice — mirrored by the kernel. UI controls watch the
26459
27061
  * slice for live state + battery + fan-speed changes.
26460
27062
  */
26461
- runtimeState: VacuumControlStatusSchema
27063
+ runtimeState: VacuumControlStatusSchema,
27064
+ /**
27065
+ * Runtime-state durability: **session** — as `media-player` — a restored `state: cleaning` is a robot that is not cleaning.
27066
+ *
27067
+ * See `RuntimeStateDurability`. Enforced by
27068
+ * `scripts/check-runtime-state-durability.ts`.
27069
+ */
27070
+ durability: "session"
26462
27071
  };
26463
27072
  var ValveStatusSchema = object({
26464
27073
  /** Lifecycle state of the valve. */
@@ -26510,7 +27119,14 @@ var valveCapability = {
26510
27119
  * Runtime-state slice — mirrored by the kernel. UI controls watch the
26511
27120
  * slice for live position changes during a move.
26512
27121
  */
26513
- runtimeState: ValveStatusSchema
27122
+ runtimeState: ValveStatusSchema,
27123
+ /**
27124
+ * Runtime-state durability: **session** — as `brightness`.
27125
+ *
27126
+ * See `RuntimeStateDurability`. Enforced by
27127
+ * `scripts/check-runtime-state-durability.ts`.
27128
+ */
27129
+ durability: "session"
26514
27130
  };
26515
27131
  /**
26516
27132
  * Vibration / shake / impact sensor. Drives Home Assistant
@@ -26532,7 +27148,17 @@ var vibrationCapability = {
26532
27148
  schema: VibrationStatusSchema,
26533
27149
  kind: "push"
26534
27150
  },
26535
- runtimeState: VibrationStatusSchema
27151
+ runtimeState: VibrationStatusSchema,
27152
+ /**
27153
+ * Runtime-state durability: **restored** — as `smoke`.
27154
+ *
27155
+ * See `RuntimeStateDurability`. Enforced by
27156
+ * `scripts/check-runtime-state-durability.ts`.
27157
+ */
27158
+ durability: "restored",
27159
+ /** Clock fields: written, but excluded from the compare that decides
27160
+ * whether persisting is worth a SQLite commit. */
27161
+ volatileStateFields: ["lastChangedAt"]
26536
27162
  };
26537
27163
  /**
26538
27164
  * Water heater / boiler cap. Models HA `water_heater.*` entities — a
@@ -26606,7 +27232,14 @@ var waterHeaterCapability = {
26606
27232
  * Runtime-state slice — mirrored by the kernel. UI controls watch the
26607
27233
  * slice for live temperature / mode / away changes.
26608
27234
  */
26609
- runtimeState: WaterHeaterStatusSchema
27235
+ runtimeState: WaterHeaterStatusSchema,
27236
+ /**
27237
+ * Runtime-state durability: **session** — as `climate-control`.
27238
+ *
27239
+ * See `RuntimeStateDurability`. Enforced by
27240
+ * `scripts/check-runtime-state-durability.ts`.
27241
+ */
27242
+ durability: "session"
26610
27243
  };
26611
27244
  /**
26612
27245
  * Weather provider cap. Models HA `weather.*` entities — a read-only
@@ -26665,7 +27298,14 @@ var weatherCapability = {
26665
27298
  * Runtime-state slice — mirrored by the kernel. The UI reads the
26666
27299
  * current conditions directly from the slice on each weather push.
26667
27300
  */
26668
- runtimeState: WeatherStatusSchema
27301
+ runtimeState: WeatherStatusSchema,
27302
+ /**
27303
+ * Runtime-state durability: **session** — a forecast is stale the moment the hub is down; the provider re-fetches on connect.
27304
+ *
27305
+ * See `RuntimeStateDurability`. Enforced by
27306
+ * `scripts/check-runtime-state-durability.ts`.
27307
+ */
27308
+ durability: "session"
26669
27309
  };
26670
27310
  /**
26671
27311
  * Per-zone occupancy aggregation produced by the analytics frame
@@ -26827,7 +27467,14 @@ var zoneAnalyticsCapability = {
26827
27467
  * automatically; the explicit `getCurrentSnapshot` cap method is
26828
27468
  * still useful for one-off polls without a subscription.
26829
27469
  */
26830
- runtimeState: CameraOccupancySnapshotSchema
27470
+ runtimeState: CameraOccupancySnapshotSchema,
27471
+ /**
27472
+ * Runtime-state durability: **session** — per-frame analytics; with `audio-metrics` it is ~90 % of the offered write rate. Re-derived on the next frame.
27473
+ *
27474
+ * See `RuntimeStateDurability`. Enforced by
27475
+ * `scripts/check-runtime-state-durability.ts`.
27476
+ */
27477
+ durability: "session"
26831
27478
  };
26832
27479
  /**
26833
27480
  * Stages a {@link ZoneRule} can apply to. Discriminator on the rules
@@ -26905,7 +27552,14 @@ var zoneRulesCapability = {
26905
27552
  motion: array(ZoneRuleSchema).readonly(),
26906
27553
  detection: array(ZoneRuleSchema).readonly(),
26907
27554
  package: array(ZoneRuleSchema).readonly()
26908
- })
27555
+ }),
27556
+ /**
27557
+ * Runtime-state durability: **restored** — operator intent, mutation-only, same argument as `zones`.
27558
+ *
27559
+ * See `RuntimeStateDurability`. Enforced by
27560
+ * `scripts/check-runtime-state-durability.ts`.
27561
+ */
27562
+ durability: "restored"
26909
27563
  };
26910
27564
  /**
26911
27565
  * Accessory device helpers — shared across drivers.
@@ -33592,6 +34246,7 @@ Object.freeze({
33592
34246
  "network-access": "ingress",
33593
34247
  "smtp-provider": "email"
33594
34248
  });
34249
+ new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
33595
34250
  new Set(["devices", "classes"]);
33596
34251
  /**
33597
34252
  * TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.