@camstack/types 1.2.414 → 1.2.416

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 (68) hide show
  1. package/dist/addon.js +4 -1798
  2. package/dist/addon.mjs +2 -1796
  3. package/dist/capabilities/camera-grid-layout.cap.d.ts +1 -1
  4. package/dist/capabilities/customize-catalog.d.ts +26 -0
  5. package/dist/capabilities/customize-spec.d.ts +6 -1
  6. package/dist/capabilities/device-history.cap.d.ts +1 -1
  7. package/dist/capabilities/device-manager.cap.d.ts +2 -2
  8. package/dist/capabilities/doorbell.cap.d.ts +1 -0
  9. package/dist/capabilities/notification-rules.cap.d.ts +2 -2
  10. package/dist/capabilities/osd-manager.cap.d.ts +1 -1
  11. package/dist/capabilities/pipeline-analytics.cap.d.ts +1 -1
  12. package/dist/capabilities/pipeline-runner.cap.d.ts +1 -1
  13. package/dist/capabilities/ptz.cap.d.ts +3 -3
  14. package/dist/capabilities/recording-export.cap.d.ts +1 -1
  15. package/dist/capabilities/running-state.cap.d.ts +1 -0
  16. package/dist/capabilities/scene-monitor.cap.d.ts +1 -1
  17. package/dist/capabilities/stream-signals.cap.d.ts +1 -1
  18. package/dist/capabilities/videoclips.cap.d.ts +2 -2
  19. package/dist/capabilities/viewer-ui.cap.d.ts +1 -1
  20. package/dist/catalogs/index.d.ts +1 -1
  21. package/dist/catalogs/{frigate-plus-classmap.d.ts → plus-catalog-classmap.d.ts} +25 -25
  22. package/dist/catalogs/root-model-supply.d.ts +3 -3
  23. package/dist/client.js +22 -22
  24. package/dist/client.mjs +22 -22
  25. package/dist/composition/cards/__fixtures__/stored-compositions.d.ts +2 -2
  26. package/dist/composition/customize/__fixtures__/refs.d.ts +1 -1
  27. package/dist/composition/customize/override-draft.d.ts +10 -0
  28. package/dist/{composition-CSLSFGTO.js → composition-DsmkwP9-.js} +1 -1
  29. package/dist/{composition-BJ8iAZb3.mjs → composition-kEl9mevu.mjs} +1 -1
  30. package/dist/device/base-device-provider.d.ts +1 -1
  31. package/dist/device/device-state-handle.d.ts +1 -1
  32. package/dist/device/location-icon.d.ts +1 -1
  33. package/dist/device/site-zone.d.ts +2 -2
  34. package/dist/enums/event-category.d.ts +1 -1
  35. package/dist/enums.js +1 -1
  36. package/dist/enums.mjs +1 -1
  37. package/dist/{event-category-Ceif8n-v.mjs → event-category-DHXxB8t9.mjs} +1 -1
  38. package/dist/{event-category-DG6Vir8Z.js → event-category-DXZ3f9Q5.js} +1 -1
  39. package/dist/ffmpeg/fmp4-fragment-plane.d.ts +1 -1
  40. package/dist/ffmpeg/gif-derive.d.ts +1 -1
  41. package/dist/ffmpeg/process.d.ts +1 -1
  42. package/dist/generated/addon-cap-facts.d.ts +2 -0
  43. package/dist/generated/customize-catalog.d.ts +48 -0
  44. package/dist/geometry/subject-path.d.ts +1 -1
  45. package/dist/index.d.ts +3 -3
  46. package/dist/index.js +1603 -1533
  47. package/dist/index.mjs +1597 -1527
  48. package/dist/interfaces/addon-peer-bytes.d.ts +1 -1
  49. package/dist/interfaces/agent.d.ts +1 -1
  50. package/dist/interfaces/birth-decision-ledger.d.ts +1 -1
  51. package/dist/interfaces/debug-note-archive.d.ts +1 -1
  52. package/dist/interfaces/inference-engine.d.ts +1 -1
  53. package/dist/interfaces/logging.d.ts +1 -1
  54. package/dist/metrics/failure-counters.d.ts +2 -2
  55. package/dist/node.js +2 -2
  56. package/dist/node.mjs +2 -2
  57. package/dist/notification/timelapse-rule.d.ts +1 -1
  58. package/dist/pipeline/root-face-crop.d.ts +1 -1
  59. package/dist/pipeline/second-pass/motion-crop-plan.d.ts +1 -1
  60. package/dist/pipeline/second-pass/small-subject-recovery.d.ts +4 -4
  61. package/dist/process/child-cost-registry.d.ts +1 -1
  62. package/dist/{sleep-CYfIZzGv.mjs → sleep-BErAxhul.mjs} +1982 -4
  63. package/dist/{sleep-UP964hNP.js → sleep-BPQ2ZyaI.js} +1999 -3
  64. package/dist/types/detection.d.ts +2 -2
  65. package/dist/types/models.d.ts +3 -3
  66. package/dist/types/overlay-layer.d.ts +1 -1
  67. package/dist/utils/addon-id.d.ts +1 -1
  68. package/package.json +7 -2
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-UP964hNP.js");
3
- const require_event_category = require("./event-category-DG6Vir8Z.js");
4
- const require_composition = require("./composition-CSLSFGTO.js");
2
+ const require_sleep = require("./sleep-BPQ2ZyaI.js");
3
+ const require_event_category = require("./event-category-DXZ3f9Q5.js");
4
+ const require_composition = require("./composition-DsmkwP9-.js");
5
5
  const require_node_color = require("./node-color.js");
6
6
  const require_err_msg = require("./err-msg-BhVbr0NX.js");
7
7
  const require_enums = require("./enums.js");
@@ -718,7 +718,7 @@ function gifDeriveSpeed(gifSpeed, videoSpeed) {
718
718
  * runs at `fps / speed` in SOURCE time and `setpts` multiplies what survived.
719
719
  * The trailing `fps` re-declares the rate, which is NOT redundant: `setpts`
720
720
  * leaves the filter link advertising the sampled rate and the gif muxer
721
- * believes the link — measured on 615 as a 3.01 s gif of ten frames.
721
+ * believes the link — measured on 101 as a 3.01 s gif of ten frames.
722
722
  */
723
723
  function gifFilterComplex(input) {
724
724
  const speed = input.speed > 0 ? input.speed : 1;
@@ -2161,7 +2161,7 @@ function parseRetrainRevisionConflict(message) {
2161
2161
  * ── Why a TABLE and not a log line ─────────────────────────────────────────
2162
2162
  * `logs.query` is an in-memory ring. Measured on the live hub on 2026-09-08 it
2163
2163
  * held 40 000 entries covering 38 minutes — the whole ring is under an hour of
2164
- * fleet traffic. Every question this data is for ("how often, on camera 617,
2164
+ * fleet traffic. Every question this data is for ("how often, on camera 102,
2165
2165
  * over the week the operator complained about") outlives that ring by two
2166
2166
  * orders of magnitude, and a previous investigation in this repo was blocked
2167
2167
  * for precisely this reason. The gate ALREADY writes a log line per decision
@@ -2422,7 +2422,7 @@ var BirthDecisionQueryInputSchema = zod.z.object({
2422
2422
  * - A per-device bound multiplies by the fleet — 30 cameras at 500 each is
2423
2423
  * 15 000 rows to protect a corpus that only ever gets read fleet-wide (the
2424
2424
  * thing being mined is "what keeps going wrong", not "what goes wrong on
2425
- * 617"). One global ceiling is one number to reason about.
2425
+ * 102"). One global ceiling is one number to reason about.
2426
2426
  * - An AGE bound would delete the corpus for being old, which is the failure
2427
2427
  * being fixed: a note from six months ago is the most valuable row in the
2428
2428
  * table precisely because the pattern it describes has had time to repeat.
@@ -4722,7 +4722,7 @@ var LogChannelDescriptorSchema = zod.z.object({
4722
4722
  * `true` is a PROMISE with two halves, and both must hold: the gate is
4723
4723
  * consulted with the numeric device id, AND every line the channel admits
4724
4724
  * carries `tags: { deviceId }` with that same numeric id. The second half is
4725
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
4725
+ * what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
4726
4726
  * keeps `deviceId` out of the stream labels for cardinality, so the tag in
4727
4727
  * the body is the only way to filter.
4728
4728
  *
@@ -5037,8 +5037,8 @@ function createLogChannelsProvider(logger, options = {}) {
5037
5037
  *
5038
5038
  * The key is the numeric `deviceId` — the same value every log line in this
5039
5039
  * repo carries as `tags.deviceId`. There is no fleet-total mode and no
5040
- * device-less bucket, because the question is always "why is 617 worse than
5041
- * 615?" and a fleet total cannot answer it. A caller that cannot name the
5040
+ * device-less bucket, because the question is always "why is 102 worse than
5041
+ * 101?" and a fleet total cannot answer it. A caller that cannot name the
5042
5042
  * camera must not note anything: an unnamed per-camera count is
5043
5043
  * indistinguishable from a shared one, which is how one camera's failures
5044
5044
  * quietly become everybody's.
@@ -5967,7 +5967,7 @@ function effectFor(stepId, label) {
5967
5967
  * - label kind: a label counts for a step only when the classMap sends it to
5968
5968
  * that step's macro AND it names a vocabulary entry. Every root is judged
5969
5969
  * the same way — a COCO model supplies the animal classifier with the six
5970
- * species COCO names, exactly as a Frigate+ model supplies seven.
5970
+ * species COCO names, exactly as a plus catalog model supplies seven.
5971
5971
  * - crop kind: the labelmap carries one of the step's root labels. Those
5972
5972
  * labels are deliberately left out of the classMap, so they never make a
5973
5973
  * track of their own.
@@ -6252,7 +6252,7 @@ var ModelVariantGroupSchema = zod.z.object({
6252
6252
  precision: zod.z.enum(["fp32", "int8"]).optional(),
6253
6253
  /**
6254
6254
  * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
6255
- * an alternate training of the same family (Scrypted `relu_test`); chip
6255
+ * an alternate training of the same family (plugin catalog `relu_test`); chip
6256
6256
  * label is "Test".
6257
6257
  */
6258
6258
  optimization: zod.z.enum(["standard", "test"]).optional(),
@@ -6267,7 +6267,7 @@ var ModelVariantGroupSchema = zod.z.object({
6267
6267
  });
6268
6268
  /**
6269
6269
  * Where a catalog entry came from. The pipeline stepper partitions the picker
6270
- * by this id (CamStack / Frigate / Scrypted / Custom). Absent on older durable
6270
+ * by this id (CamStack / plus catalog / plugin catalog / Custom). Absent on older durable
6271
6271
  * registry rows — {@link inferModelProvider} fills it at read time. Built-in
6272
6272
  * catalog entries omit it and `getSchema` treats them as `camstack`.
6273
6273
  */
@@ -6280,9 +6280,9 @@ var MODEL_PROVIDER_IDS = [
6280
6280
  var ModelProviderIdSchema = zod.z.enum(MODEL_PROVIDER_IDS);
6281
6281
  /**
6282
6282
  * Resolve a catalog entry's picker provider. An explicit stamp always wins;
6283
- * otherwise Frigate/Scrypted are recognised from id prefix or description.
6283
+ * otherwise plus catalog/plugin catalog are recognised from id prefix or description.
6284
6284
  * Unstamped BYO registry rows fall through to `custom`. Family `yolov9` is
6285
- * NOT a Scrypted signal — CamStack ships that family too.
6285
+ * NOT a plugin catalog signal — CamStack ships that family too.
6286
6286
  */
6287
6287
  function inferModelProvider(entry) {
6288
6288
  if (entry.provider !== void 0) return entry.provider;
@@ -6526,8 +6526,8 @@ var ModelCatalogEntrySchema = zod.z.object({
6526
6526
  provider: ModelProviderIdSchema.optional(),
6527
6527
  /**
6528
6528
  * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
6529
- * applies (Frigate / COCO public catalog). Set on a custom model whose raw
6530
- * labels already ARE the CamStack macros (Scrypted identity map).
6529
+ * applies (plus catalog / COCO public catalog). Set on a custom model whose raw
6530
+ * labels already ARE the CamStack macros (plugin catalog identity map).
6531
6531
  */
6532
6532
  classMap: DetectionCatalogClassMapSchema.optional(),
6533
6533
  /**
@@ -11624,7 +11624,7 @@ var streamBrokerCapability = {
11624
11624
  * `1` is real time and is the ONLY value that allows the copy branch —
11625
11625
  * anything else forces `libx264` over the window. That was priced
11626
11626
  * before it was chosen: a per-event burst measured at 0.23 s and 254 KB
11627
- * on a real 615 720p cut, against 922 KB for the copy it replaces. A
11627
+ * on a real 101 720p cut, against 922 KB for the copy it replaces. A
11628
11628
  * re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
11629
11629
  * once the decode is forced the width stops being free.
11630
11630
  */
@@ -15453,7 +15453,7 @@ var deviceHistoryCapability = {
15453
15453
  listSeries: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int() }), zod.z.array(SeriesInfoSchema).readonly()),
15454
15454
  /**
15455
15455
  * A NODE's series. The subject is `forNodeId`, never `nodeId`: a top-level
15456
- * `nodeId` is the cap ROUTING key, and `nodeId: 'little-unraid'` sent the
15456
+ * `nodeId` is the cap ROUTING key, and `nodeId: 'agent-a'` sent the
15457
15457
  * read to that agent, which hosts no device-history.
15458
15458
  */
15459
15459
  listNodeSeries: require_sleep.method(zod.z.object({ forNodeId: zod.z.string().min(1) }), zod.z.array(SeriesInfoSchema).readonly(), { auth: "admin" }),
@@ -37075,7 +37075,7 @@ var LOCATION_ICON_FALLBACK = "map-pin";
37075
37075
  * `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
37076
37076
  * operator's casing. The registry matches labels trimmed + case-insensitively
37077
37077
  * everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
37078
- * case-only rename (`cucina` → `Cucina`) is a real edit this repo supports; a
37078
+ * case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
37079
37079
  * map keyed on the displayed casing would orphan its entry on exactly that
37080
37080
  * edit. Consumers join by keying their own label through `locationIconKey`.
37081
37081
  */
@@ -37120,7 +37120,7 @@ var LocationDescriptionAssignmentSchema = zod.z.object({
37120
37120
  /**
37121
37121
  * A SITE ZONE — a named part of the property that several locations belong to.
37122
37122
  *
37123
- * "Zona notte" holds every bedroom; "Zona giorno" the living room and the
37123
+ * "Night zone" holds every bedroom; "Zona giorno" the living room and the
37124
37124
  * kitchen. A camera belongs to exactly one location, and a location to at most
37125
37125
  * one zone, so a camera's zone is derived and never stored on the device: the
37126
37126
  * whole point of this entity is that grouping rooms touches no device row.
@@ -37149,7 +37149,7 @@ var LocationDescriptionAssignmentSchema = zod.z.object({
37149
37149
  * the locations inside it.
37150
37150
  *
37151
37151
  * The LABEL is carried alongside the key because the key is lossy on purpose —
37152
- * a surface must show "Zona notte", not "zona notte". Locations are carried
37152
+ * a surface must show "Night zone", not "night zone". Locations are carried
37153
37153
  * here, rather than left to a second call, because every consumer wants both
37154
37154
  * at once and a viewer that asked twice could render a zone whose membership
37155
37155
  * it has not fetched yet.
@@ -38069,7 +38069,7 @@ var deviceManagerCapability = {
38069
38069
  * The room's ICON travels with the rename, including when `from` was
38070
38070
  * never registered — otherwise it orphans on a key no location carries
38071
38071
  * any more. A merge keeps the TARGET's icon when it has one: renaming
38072
- * "Sala" into "Salone" moves devices into Salone, it does not restyle
38072
+ * "Sala" into "Hall" moves devices into Hall, it does not restyle
38073
38073
  * it. */
38074
38074
  renameLocation: require_sleep.method(zod.z.object({
38075
38075
  from: zod.z.string(),
@@ -38141,7 +38141,7 @@ var deviceManagerCapability = {
38141
38141
  auth: "admin"
38142
38142
  }),
38143
38143
  /** Every SITE ZONE — a named part of the property that groups locations
38144
- * ("Zona notte" holds the bedrooms). One call answers the whole picture:
38144
+ * ("Night zone" holds the bedrooms). One call answers the whole picture:
38145
38145
  * key, the label as typed, the icon, and the locations inside.
38146
38146
  *
38147
38147
  * Together, because a surface that asked for membership separately could
@@ -39845,7 +39845,7 @@ function validateCustomAddress(raw) {
39845
39845
  const trimmed = raw.trim();
39846
39846
  if (trimmed === "") return {
39847
39847
  ok: false,
39848
- reason: "Enter an address, e.g. https://192.168.1.50:4443."
39848
+ reason: "Enter an address, e.g. https://192.0.2.20:4443."
39849
39849
  };
39850
39850
  let parsed;
39851
39851
  try {
@@ -41016,8 +41016,8 @@ var LoadContributionSchema = zod.z.object({
41016
41016
  deviceId: zod.z.number().int().positive().nullable(),
41017
41017
  attribution: zod.z.enum(LOAD_CONTRIBUTION_ATTRIBUTIONS),
41018
41018
  /**
41019
- * What ONE entry is, in the contributor's own words — `615/high`,
41020
- * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
41019
+ * What ONE entry is, in the contributor's own words — `101/high`,
41020
+ * `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
41021
41021
  * family and inventing a common one would lose the only information that
41022
41022
  * makes two entries for the same camera distinguishable.
41023
41023
  */
@@ -45079,7 +45079,7 @@ var NcConditionsSchema = zod.z.object({
45079
45079
  * with the list under it is worse than no switch (D62).
45080
45080
  *
45081
45081
  * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
45082
- * renameable, and a rule authored on "Gianluca" went silently dark the moment
45082
+ * renameable, and a rule authored on "Alice" went silently dark the moment
45083
45083
  * the operator fixed the spelling. The id reaches the record on
45084
45084
  * `LabelAttribution.identityId`; the name is what the editor shows and what
45085
45085
  * `{{label}}` renders.
@@ -45662,7 +45662,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
45662
45662
  * A rule scoped to one camera and one zone silently became a rule that
45663
45663
  * matches EVERY event on EVERY camera, and lost its `media` policy
45664
45664
  * (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
45665
- * live on 2026-08-12: a rule scoped to device 617 fired on 590 and 615
45665
+ * live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
45666
45666
  * within a minute of a two-field patch.
45667
45667
  *
45668
45668
  * So every defaulted field is re-declared here WITHOUT its default. The
@@ -47229,8 +47229,8 @@ var NcAlarmSensorsSchema = zod.z.object({
47229
47229
  * own `sustainSeconds` (29 s on this hub), so its clip is anchored well in the
47230
47230
  * past — and the other source, the recordings, cannot cover a recent moment:
47231
47231
  * measured against `recording.getAvailability` for a 10 s window at several
47232
- * anchors, full coverage arrived at −18 s on device 590 and −26 s on 615 and
47233
- * 617. That edge is a PHASE of the 10-second segment cycle, not a number. The
47232
+ * anchors, full coverage arrived at −18 s on device 104 and −26 s on 101 and
47233
+ * 102. That edge is a PHASE of the 10-second segment cycle, not a number. The
47234
47234
  * ring therefore has to hold the moment until the recordings can take it over:
47235
47235
  * the worst measured phase (26 s) plus the confirmation lag (29 s) is 55 s, and
47236
47236
  * 60 is the round number above it.
@@ -48583,7 +48583,7 @@ var LabelAttributionSchema = zod.z.object({
48583
48583
  * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
48584
48584
  *
48585
48585
  * The text alone is a DISPLAY NAME, and a display name is renameable: a
48586
- * notification rule authored on "Gianluca" stopped matching the moment the
48586
+ * notification rule authored on "Alice" stopped matching the moment the
48587
48587
  * operator fixed the spelling in the gallery, and nothing said so. The id is
48588
48588
  * the thing that does not move, so it is what a rule matches on
48589
48589
  * (`NcConditions.identities`) and the text is what a human is shown.
@@ -51418,7 +51418,7 @@ var pipelineAnalyticsCapability = {
51418
51418
  * audio, stopping at the first hit — so on the live hub, where object
51419
51419
  * events own no media of their own and 299 883 of 300 559 media rows are
51420
51420
  * motion-owned, EVERY object event resolved to its motion namesake. A
51421
- * track from 17:34 on camera 615 was served a snapshot from 22:35 eleven
51421
+ * track from 17:34 on camera 101 was served a snapshot from 22:35 eleven
51422
51422
  * days earlier, silently.
51423
51423
  *
51424
51424
  * D476 had already disambiguated the KEY (`motion:` vs `object:`); this is
@@ -52084,7 +52084,7 @@ var pipelineExecutorCapability = {
52084
52084
  /**
52085
52085
  * Root-supplied detections for the tree's ROOT step (D730). Set by
52086
52086
  * `runDetailSubtree` when the camera's root model supplies a crop-kind
52087
- * step (a Frigate+ `license_plate` for `plate-detection`): the step is
52087
+ * step (a plus catalog `license_plate` for `plate-detection`): the step is
52088
52088
  * NOT inferred, these boxes are its output, and its children (the plate
52089
52089
  * reader) run on them through their own crop policy. Boxes are in the
52090
52090
  * PIXELS of the image this call carries. Absent ⇒ the root step runs.
@@ -53879,7 +53879,7 @@ var RunnerCameraConfigSchema = zod.z.object({
53879
53879
  * detection session that asks for history. What shipped was a last-moment
53880
53880
  * discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
53881
53881
  * arriving inside a few hundred ms of wall clock looks to it like one frame's
53882
- * worth. Device 617, 2026-09-08: a re-run of the SAME model over the stored
53882
+ * worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
53883
53883
  * recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
53884
53884
  * 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
53885
53885
  * was decoded, and was freed.
@@ -54260,7 +54260,7 @@ var pipelineRunnerCapability = {
54260
54260
  *
54261
54261
  * The periodic recheck (`occupancyRecheckSec`, 300 s) exists to watch a
54262
54262
  * still scene. It is the wrong instrument for a QUESTION that has just been
54263
- * asked: on device 617 a parked car's departure was observed, a departure
54263
+ * asked: on device 102 a parked car's departure was observed, a departure
54264
54264
  * strike was armed — and then the motion session ended, the strike decayed
54265
54265
  * after its 30 s TTL, and the next periodic look arrived up to five minutes
54266
54266
  * later with nothing left to confirm. Every one of those departures was
@@ -57293,7 +57293,7 @@ var storageProviderCapability = {
57293
57293
  * The signals a device can emit to WAKE its own stream.
57294
57294
  *
57295
57295
  * A camera whose stream is built on demand sleeps until something asks for it,
57296
- * and "something" cannot be a consumer that is merely attached — a Frigate-style
57296
+ * and "something" cannot be a consumer that is merely attached — a external-catalog
57297
57297
  * puller holds a session open for ever, and treating that as demand would keep
57298
57298
  * a battery camera awake for ever, which is the whole thing the battery is for
57299
57299
  * (D173). So the wake has to come from the CAMERA: an event it noticed by
@@ -58116,7 +58116,7 @@ var vectorStoreCapability = {
58116
58116
  * device's SOURCES are its BINDINGS: `deviceManager.getBindings(deviceId)` is
58117
58117
  * what says a provider serves this camera, never the set of addons that
58118
58118
  * happen to have registered the capability somewhere in the cluster. That is
58119
- * what stopped one addon appearing three times on 592 — as the device's
58119
+ * what stopped one addon appearing three times on 107 — as the device's
58120
58120
  * native provider, as the hub-local registration and as an
58121
58121
  * `<addonId>@<nodeId>` one (D554 amended 2026-09-20).
58122
58122
  *
@@ -58292,7 +58292,7 @@ var ClipSchema = zod.z.object({
58292
58292
  * {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
58293
58293
  *
58294
58294
  * Bounded because it is not a payload the surface pages through: one visit on
58295
- * device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
58295
+ * device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
58296
58296
  * camera-day. Read {@link eventCount} for the true total.
58297
58297
  */
58298
58298
  eventIds: zod.z.array(zod.z.string()).optional(),
@@ -58437,7 +58437,7 @@ var ClipPlaybackSchema = zod.z.object({
58437
58437
  * camera has no recordings", which is the defect this whole line of work is
58438
58438
  * about: a battery camera nobody woke (`sleeping`), a camera that could not be
58439
58439
  * reached at all (`unreachable`, also what a provider that THREW reports), a
58440
- * camera whose SD card is not mounted (`no-storage`, measured on 640 —
58440
+ * camera whose SD card is not mounted (`no-storage`, measured on 106 —
58441
58441
  * `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
58442
58442
  * camera whose OWN index disagrees with its OWN calendar (`index-empty`,
58443
58443
  * measured on 618: the calendar marks 3–20 September, days 6–20 list zero
@@ -58898,7 +58898,7 @@ var videoclipsCapability = {
58898
58898
  *
58899
58899
  * It was optional, documented as "absent means the device's BOUND
58900
58900
  * provider, which is CamStack on every camera". No code implemented
58901
- * that. Measured on the live hub 2026-09-20 — device 592, bound to
58901
+ * that. Measured on the live hub 2026-09-20 — device 107, bound to
58902
58902
  * `recorder` AND `provider-reolink` — a bare call with `limit: 3`
58903
58903
  * answered SIX rows, three from each source, merged newest-first:
58904
58904
  * `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
@@ -61616,7 +61616,7 @@ var GridLayoutCellSchema = zod.z.object({
61616
61616
  *
61617
61617
  * A grid's `high` composes its sources' `high` and its `low` their `low`, so a
61618
61618
  * profile is on offer only when EVERY source can serve it. The refusal NAMES
61619
- * the sources, because "this grid has no low" is not a finding — "615 has no
61619
+ * the sources, because "this grid has no low" is not a finding — "101 has no
61620
61620
  * low" is, and it is the one an operator can act on.
61621
61621
  */
61622
61622
  var GridProfileOfferSchema = zod.z.object({
@@ -63383,6 +63383,7 @@ var doorbellCustomize = {
63383
63383
  applyAuthority: { kind: "composition-claim" },
63384
63384
  eventName: "onPressed",
63385
63385
  edges: ["rising"],
63386
+ defaultEdge: "rising",
63386
63387
  timestampPath: "lastPressedAt",
63387
63388
  counterPath: "pressCountSinceStart",
63388
63389
  highWater: "composer-advance",
@@ -67940,7 +67941,7 @@ setOverlay: require_sleep.method(zod.z.object({
67940
67941
  * This cap owns the other half: a per-(camera, slot) BINDING that says
67941
67942
  * which value feeds the slot, how it is formatted, and under which
67942
67943
  * conditions it is shown at all. Named TEMPLATES combine many device
67943
- * fields into one overlay string (Scrypted OSD Manager parity).
67944
+ * fields into one overlay string (plugin catalog OSD Manager parity).
67944
67945
  */
67945
67946
  /**
67946
67947
  * How a parser token expands one binding. Not stored on the binding —
@@ -70181,9 +70182,9 @@ var PtzOptionsSchema = zod.z.object({
70181
70182
  * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
70182
70183
  * not one of the three cameras honours its own:
70183
70184
  *
70184
- * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
70185
- * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
70186
- * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
70185
+ * 107 Camera camera Carol (reolink) preset 0 holds "stanza"
70186
+ * 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
70187
+ * 3836 Camera studio (amcrest) preset 1 holds "Preset1"
70187
70188
  *
70188
70189
  * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
70189
70190
  * and two of the three swallowed the failure in a bare `catch`. For autotrack
@@ -70616,6 +70617,7 @@ var runningCustomize = {
70616
70617
  requiredUnit: "W",
70617
70618
  transforms: [{
70618
70619
  kind: "threshold",
70620
+ comparisons: ["gte", "lte"],
70619
70621
  comparison: "gte",
70620
70622
  defaultThreshold: 5,
70621
70623
  defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
@@ -70807,7 +70809,7 @@ var RecordingAvailabilitySchema = zod.z.object({
70807
70809
  * would look identical. But the answer used to say nothing about that, so a
70808
70810
  * caller asking "what can I export?" read the single preferred profile as
70809
70811
  * the only one that exists — on this deployment every camera records `high`
70810
- * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
70812
+ * AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
70811
70813
  * UI could not see it.
70812
70814
  *
70813
70815
  * Cheap: it is the same shallow directory read the profile CHOICE already
@@ -70906,7 +70908,7 @@ var RecordingSourceOptionsSchema = zod.z.object({
70906
70908
  * `sparse` = gaps are the absence of one, and must be drawn as such.
70907
70909
  *
70908
70910
  * Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
70909
- * of 592's day and 1.2 % of 1436's. It is a fact about a (source, camera)
70911
+ * of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
70910
70912
  * pair, and ours answers it per camera from `deriveRecordingMode`. */
70911
70913
  coverage: zod.z.enum(["continuous", "sparse"]),
70912
70914
  /** Where the playhead may be put.
@@ -71017,7 +71019,7 @@ var recordingCapability = {
71017
71019
  * merely discouraged (D554 amended).
71018
71020
  *
71019
71021
  * It was learned the expensive way on `videoclips.listClips`: measured
71020
- * on the live hub 2026-09-20, device 592 bound to `recorder` AND
71022
+ * on the live hub 2026-09-20, device 107 bound to `recorder` AND
71021
71023
  * `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
71022
71024
  * three from each source, merged — `device-collection-dispatch.ts`
71023
71025
  * leaves an unpinned fan-out un-narrowed, so absence buys the union the
@@ -71860,7 +71862,7 @@ var ExportSpeedSchema = zod.z.number().min(.25).max(32);
71860
71862
  * on a 10 h window holding 29,393 s of footage every range landed late by the
71861
71863
  * gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
71862
71864
  * the video was a uniform timelapse, and the log line reported the five ranges
71863
- * that had been ASKED for (2026-08-13, export `57d14363`, camera 615).
71865
+ * that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
71864
71866
  *
71865
71867
  * Relative and not absolute epoch, because an absolute epoch would make every
71866
71868
  * call site responsible for the same subtraction.
@@ -73101,7 +73103,7 @@ function reservedSourceOwner(capName, sourceId) {
73101
73103
  * which put a "Scenes" tab on one camera's detail page. That is the wrong shape
73102
73104
  * for the thing: a scene is a standing question about the property ("is the bin
73103
73105
  * still out"), and the operator's question is "which of my scenes have tripped",
73104
- * across every camera at once — not "what does camera 617 think". Buried one
73106
+ * across every camera at once — not "what does camera 102 think". Buried one
73105
73107
  * camera deep it also could not be found. The surface is now a top-level admin
73106
73108
  * page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
73107
73109
  * picks the camera inside the create flow, the same shape Events and Faces have.
@@ -78116,7 +78118,14 @@ var CAP_CUSTOMIZE_CATALOG = {
78116
78118
  sources: [{
78117
78119
  kind: "field",
78118
78120
  valueKinds: ["number", "string"],
78119
- transformKinds: ["identity", "linear"]
78121
+ transformKinds: ["identity", "linear"],
78122
+ transforms: [{ kind: "identity" }, {
78123
+ kind: "linear",
78124
+ defaultScale: 1,
78125
+ defaultOffset: 0,
78126
+ clampMin: 0,
78127
+ clampMax: 100
78128
+ }]
78120
78129
  }],
78121
78130
  sourceReport: { status: "assignment-status" },
78122
78131
  advancedExpression: true,
@@ -78231,7 +78240,14 @@ var CAP_CUSTOMIZE_CATALOG = {
78231
78240
  nullable: true,
78232
78241
  sources: [{
78233
78242
  kind: "numeric",
78234
- transformKinds: ["identity", "linear"]
78243
+ transformKinds: ["identity", "linear"],
78244
+ transforms: [{ kind: "identity" }, {
78245
+ kind: "linear",
78246
+ defaultScale: 1,
78247
+ defaultOffset: 0,
78248
+ clampMin: 0,
78249
+ clampMax: 100
78250
+ }]
78235
78251
  }]
78236
78252
  },
78237
78253
  {
@@ -78240,7 +78256,8 @@ var CAP_CUSTOMIZE_CATALOG = {
78240
78256
  nullable: true,
78241
78257
  sources: [{
78242
78258
  kind: "numeric",
78243
- transformKinds: ["identity"]
78259
+ transformKinds: ["identity"],
78260
+ transforms: [{ kind: "identity" }]
78244
78261
  }],
78245
78262
  literals: [{
78246
78263
  path: "remaining.unit",
@@ -78264,7 +78281,18 @@ var CAP_CUSTOMIZE_CATALOG = {
78264
78281
  ],
78265
78282
  sources: [{
78266
78283
  kind: "enum",
78267
- transformKinds: ["enum-map"]
78284
+ transformKinds: ["enum-map"],
78285
+ transforms: [{
78286
+ kind: "enum-map",
78287
+ outputValues: [
78288
+ "ok",
78289
+ "low",
78290
+ "empty",
78291
+ "full",
78292
+ "replace"
78293
+ ],
78294
+ unmapped: null
78295
+ }]
78268
78296
  }]
78269
78297
  }
78270
78298
  ],
@@ -78309,10 +78337,12 @@ var CAP_CUSTOMIZE_CATALOG = {
78309
78337
  vocabularyEvent: "onPressed",
78310
78338
  sources: [{
78311
78339
  kind: "binary",
78312
- transformKinds: []
78340
+ transformKinds: [],
78341
+ transforms: []
78313
78342
  }, {
78314
78343
  kind: "switch",
78315
- transformKinds: []
78344
+ transformKinds: [],
78345
+ transforms: []
78316
78346
  }],
78317
78347
  sourceReport: { status: "assignment-status" },
78318
78348
  advancedExpression: true,
@@ -78321,6 +78351,7 @@ var CAP_CUSTOMIZE_CATALOG = {
78321
78351
  eventName: "onPressed",
78322
78352
  combine: "any",
78323
78353
  edges: ["rising"],
78354
+ defaultEdge: "rising",
78324
78355
  timestampPath: "lastPressedAt",
78325
78356
  counterPath: "pressCountSinceStart",
78326
78357
  highWater: "composer-advance",
@@ -78349,10 +78380,12 @@ var CAP_CUSTOMIZE_CATALOG = {
78349
78380
  vocabularyEvent: "onMotionChanged",
78350
78381
  sources: [{
78351
78382
  kind: "binary",
78352
- transformKinds: []
78383
+ transformKinds: [],
78384
+ transforms: []
78353
78385
  }, {
78354
78386
  kind: "switch",
78355
- transformKinds: []
78387
+ transformKinds: [],
78388
+ transforms: []
78356
78389
  }],
78357
78390
  sourceReport: { status: "assignment-status" },
78358
78391
  advancedExpression: false,
@@ -78412,16 +78445,27 @@ var CAP_CUSTOMIZE_CATALOG = {
78412
78445
  sources: [
78413
78446
  {
78414
78447
  kind: "switch",
78415
- transformKinds: ["identity"]
78448
+ transformKinds: ["identity"],
78449
+ transforms: [{ kind: "identity" }]
78416
78450
  },
78417
78451
  {
78418
78452
  kind: "binary",
78419
- transformKinds: ["identity", "invert"]
78453
+ transformKinds: ["identity", "invert"],
78454
+ transforms: [{ kind: "identity" }, { kind: "invert" }]
78420
78455
  },
78421
78456
  {
78422
78457
  kind: "numeric",
78423
78458
  requiredUnit: "W",
78424
- transformKinds: ["threshold"]
78459
+ transformKinds: ["threshold"],
78460
+ transforms: [{
78461
+ kind: "threshold",
78462
+ comparisons: ["gte", "lte"],
78463
+ comparison: "gte",
78464
+ defaultThreshold: 5,
78465
+ defaultStartDwellMs: 3e4,
78466
+ defaultStopDwellMs: 18e4,
78467
+ thresholdUnit: "W"
78468
+ }]
78425
78469
  }
78426
78470
  ],
78427
78471
  sourceReport: {
@@ -78609,13 +78653,16 @@ function compilePulseOverride(input) {
78609
78653
  const timestampPath = target.timestampPath;
78610
78654
  const counterPath = target.counterPath;
78611
78655
  if (timestampPath === void 0 || counterPath === void 0 || !isIdentifier(timestampPath) || !isIdentifier(counterPath)) return fail$2("path");
78612
- if (!(target.edges ?? []).includes("rising")) return fail$2("edge");
78656
+ const edges = chosenEdges(input.draft.edges, target);
78657
+ if (edges === null) return fail$2("edge");
78613
78658
  const pairs = pairSources(input);
78614
78659
  if (!pairs.ok) return pairs;
78615
78660
  if (pairs.value.length === 0) return fail$2("sources");
78616
78661
  const debounce = unsignedToken(input.draft.debounceMs);
78617
78662
  if (debounce === null) return fail$2("debounce");
78618
78663
  const ordered = pairs.value.toSorted((a, b) => pairKey(a).localeCompare(pairKey(b)));
78664
+ const calls = edgeCalls(edges, ordered.length, debounce);
78665
+ if (calls === null) return fail$2("edge");
78619
78666
  return {
78620
78667
  ok: true,
78621
78668
  value: {
@@ -78623,7 +78670,7 @@ function compilePulseOverride(input) {
78623
78670
  cap: input.draft.cap,
78624
78671
  enabled: input.draft.enabled,
78625
78672
  fields: {
78626
- [timestampPath]: expression(pulseExpr(ordered.length, debounce), pulseBindings(ordered)),
78673
+ [timestampPath]: expression(pulseExpr(calls), pulseBindings(ordered)),
78627
78674
  [counterPath]: expression(`count(${timestampPath})`, { [timestampPath]: fromRead(input.device, input.draft.cap, timestampPath) })
78628
78675
  }
78629
78676
  }
@@ -78677,10 +78724,28 @@ function pairSources(input) {
78677
78724
  function pairKey(pair) {
78678
78725
  return `${pair.source.addonId}/${pair.source.stableId}#${pair.source.cap}#${pair.source.fieldPath}`;
78679
78726
  }
78680
- function pulseExpr(count, debounce) {
78681
- const roses = [];
78682
- for (let index = 0; index < count; index += 1) roses.push(`rose(active${index}, changed${index}, ${debounce})`);
78683
- return `latest(${roses.join(", ")})`;
78727
+ function chosenEdges(draftEdges, target) {
78728
+ const allowed = target.edges ?? [];
78729
+ const chosen = draftEdges ?? (target.defaultEdge !== void 0 ? [target.defaultEdge] : []);
78730
+ if (chosen.length === 0) return null;
78731
+ if (chosen.some((edge) => !allowed.includes(edge))) return null;
78732
+ return chosen;
78733
+ }
78734
+ function edgeCalls(edges, count, debounce) {
78735
+ const calls = [];
78736
+ for (let index = 0; index < count; index += 1) for (const edge of edges) {
78737
+ const call = edgeCall(edge, index, debounce);
78738
+ if (call === null) return null;
78739
+ calls.push(call);
78740
+ }
78741
+ return calls;
78742
+ }
78743
+ function edgeCall(edge, index, debounce) {
78744
+ if (edge === "rising") return `rose(active${index}, changed${index}, ${debounce})`;
78745
+ return null;
78746
+ }
78747
+ function pulseExpr(calls) {
78748
+ return `latest(${calls.join(", ")})`;
78684
78749
  }
78685
78750
  function pulseBindings(pairs) {
78686
78751
  const bindings = {};
@@ -79861,1313 +79926,209 @@ function formulaProblem(expr, bindings) {
79861
79926
  });
79862
79927
  }
79863
79928
  //#endregion
79864
- //#region src/generated/capability-router-map.ts
79865
- var CAPABILITY_NAMES = {
79866
- accessories: "accessories",
79867
- addonPages: "addon-pages",
79868
- addonPagesSource: "addon-pages-source",
79869
- addonRoutes: "addon-routes",
79870
- addonSettings: "addon-settings",
79871
- addonWidgets: "addon-widgets",
79872
- addonWidgetsSource: "addon-widgets-source",
79873
- addons: "addons",
79874
- adminUi: "admin-ui",
79875
- airQualitySensor: "air-quality-sensor",
79876
- alarmPanel: "alarm-panel",
79877
- alerts: "alerts",
79878
- ambientLightSensor: "ambient-light-sensor",
79879
- audioAnalysis: "audio-analysis",
79880
- audioAnalyzer: "audio-analyzer",
79881
- audioCodec: "audio-codec",
79882
- audioMetrics: "audio-metrics",
79883
- authProvider: "auth-provider",
79884
- automationControl: "automation-control",
79885
- backup: "backup",
79886
- battery: "battery",
79887
- binary: "binary",
79888
- brightness: "brightness",
79889
- broker: "broker",
79890
- button: "button",
79891
- calendarSource: "calendar-source",
79892
- calendars: "calendars",
79893
- cameraCredentials: "camera-credentials",
79894
- cameraGridLayout: "camera-grid-layout",
79895
- cameraPipelineConfig: "camera-pipeline-config",
79896
- cameraStreams: "camera-streams",
79897
- carbonMonoxide: "carbon-monoxide",
79898
- climateControl: "climate-control",
79899
- color: "color",
79900
- composer: "composer",
79901
- connectionTest: "connection-test",
79902
- connectivity: "connectivity",
79903
- consumables: "consumables",
79904
- contact: "contact",
79905
- control: "control",
79906
- coreBlocks: "core-blocks",
79907
- cover: "cover",
79908
- customModelRegistry: "custom-model-registry",
79909
- dataStoreProvider: "data-store-provider",
79910
- databaseSnapshot: "database-snapshot",
79911
- dayNight: "day-night",
79912
- decoder: "decoder",
79913
- detectionPipeline: "detection-pipeline",
79914
- deviceAdminLink: "device-admin-link",
79915
- deviceAdoption: "device-adoption",
79916
- deviceCredentials: "device-credentials",
79917
- deviceDiscovery: "device-discovery",
79918
- deviceExport: "device-export",
79919
- deviceExtension: "device-extension",
79920
- deviceHistory: "device-history",
79921
- deviceManager: "device-manager",
79922
- deviceOps: "device-ops",
79923
- deviceProvider: "device-provider",
79924
- deviceRemovalHook: "device-removal-hook",
79925
- deviceState: "device-state",
79926
- deviceStatus: "device-status",
79927
- dishwasher: "dishwasher",
79928
- displayPalette: "display-palette",
79929
- doorbell: "doorbell",
79930
- embeddingEncoder: "embedding-encoder",
79931
- enumSensor: "enum-sensor",
79932
- eventEmitter: "event-emitter",
79933
- faceGallery: "face-gallery",
79934
- failureContribution: "failure-contribution",
79935
- fanControl: "fan-control",
79936
- featureProbe: "feature-probe",
79937
- filesystemBrowse: "filesystem-browse",
79938
- flood: "flood",
79939
- gas: "gas",
79940
- heatingValve: "heating-valve",
79941
- humidifier: "humidifier",
79942
- humiditySensor: "humidity-sensor",
79943
- image: "image",
79944
- imageSettings: "image-settings",
79945
- integrations: "integrations",
79946
- intercom: "intercom",
79947
- keychain: "keychain",
79948
- keychainAdmin: "keychain-admin",
79949
- lawnMowerControl: "lawn-mower-control",
79950
- llm: "llm",
79951
- llmRuntime: "llm-runtime",
79952
- loadContribution: "load-contribution",
79953
- localNetwork: "local-network",
79954
- lockControl: "lock-control",
79955
- logChannels: "log-channels",
79956
- logDestination: "log-destination",
79957
- loginMethod: "login-method",
79958
- mediaPlayer: "media-player",
79959
- meshNetwork: "mesh-network",
79960
- metricsProvider: "metrics-provider",
79961
- modelConvert: "model-convert",
79962
- modelDistributor: "model-distributor",
79963
- motion: "motion",
79964
- motionDetection: "motion-detection",
79965
- motionTrigger: "motion-trigger",
79966
- motionZones: "motion-zones",
79967
- mqttBroker: "mqtt-broker",
79968
- nativeObjectDetection: "native-object-detection",
79969
- navigation: "navigation",
79970
- networkAccess: "network-access",
79971
- networkLink: "network-link",
79972
- networkQuality: "network-quality",
79973
- nodeCertificates: "node-certificates",
79974
- nodes: "nodes",
79975
- notificationOutput: "notification-output",
79976
- notificationRules: "notification-rules",
79977
- notifier: "notifier",
79978
- numericSensor: "numeric-sensor",
79979
- oauthIntegration: "oauth-integration",
79980
- oidcConnections: "oidc-connections",
79981
- osd: "osd",
79982
- osdManager: "osd-manager",
79983
- petFeeder: "pet-feeder",
79984
- pipelineAnalytics: "pipeline-analytics",
79985
- pipelineExecutor: "pipeline-executor",
79986
- pipelineOrchestrator: "pipeline-orchestrator",
79987
- pipelineRunner: "pipeline-runner",
79988
- plateGallery: "plate-gallery",
79989
- platformProbe: "platform-probe",
79990
- powerMeter: "power-meter",
79991
- presence: "presence",
79992
- pressureSensor: "pressure-sensor",
79993
- privacyMask: "privacy-mask",
79994
- ptz: "ptz",
79995
- ptzAutotrack: "ptz-autotrack",
79996
- reboot: "reboot",
79997
- recordEntries: "record-entries",
79998
- recording: "recording",
79999
- recordingArchive: "recording-archive",
80000
- recordingExport: "recording-export",
80001
- recordingOnboard: "recording-onboard",
80002
- recordingSignal: "recording-signal",
80003
- records: "records",
80004
- runningState: "running-state",
80005
- sceneMonitor: "scene-monitor",
80006
- scriptRunner: "script-runner",
80007
- serverManagement: "server-management",
80008
- settingsStore: "settings-store",
80009
- smoke: "smoke",
80010
- smtpProvider: "smtp-provider",
80011
- snapshot: "snapshot",
80012
- ssoBridge: "sso-bridge",
80013
- storage: "storage",
80014
- storageAdmin: "storage-admin",
80015
- storageEvictable: "storage-evictable",
80016
- storageMigration: "storage-migration",
80017
- storageOccupancy: "storage-occupancy",
80018
- storageProvider: "storage-provider",
80019
- streamBroker: "stream-broker",
80020
- streamCatalog: "stream-catalog",
80021
- streamParams: "stream-params",
80022
- streamSignals: "stream-signals",
80023
- switch: "switch",
80024
- system: "system",
80025
- tamper: "tamper",
80026
- temperatureSensor: "temperature-sensor",
80027
- terminalSession: "terminal-session",
80028
- toast: "toast",
80029
- training: "training",
80030
- trainingProvider: "training-provider",
80031
- turnProvider: "turn-provider",
80032
- update: "update",
80033
- userManagement: "user-management",
80034
- userPasskeys: "user-passkeys",
80035
- vacuumControl: "vacuum-control",
80036
- valve: "valve",
80037
- vectorStore: "vector-store",
80038
- vibration: "vibration",
80039
- videoclips: "videoclips",
80040
- viewerUi: "viewer-ui",
80041
- waterHeater: "water-heater",
80042
- weather: "weather",
80043
- webrtcSession: "webrtc-session",
80044
- zoneAnalytics: "zone-analytics",
80045
- zoneRules: "zone-rules",
80046
- zones: "zones"
79929
+ //#region src/composition/cards/role-cap.ts
79930
+ /**
79931
+ * Map a device role to the primary composition cap (D939).
79932
+ */
79933
+ var ROLE_CAP_ALIASES = {
79934
+ [require_err_msg.DeviceRole.BinarySensor]: "binary",
79935
+ [require_err_msg.DeviceRole.MotionSensor]: "motion"
80047
79936
  };
80048
- /** Router key → capability name mapping for auto-mount. */
80049
- var CAPABILITY_ROUTER_KEYS = [
80050
- {
80051
- key: "accessories",
80052
- name: "accessories"
80053
- },
80054
- {
80055
- key: "addonPages",
80056
- name: "addon-pages"
80057
- },
80058
- {
80059
- key: "addonPagesSource",
80060
- name: "addon-pages-source"
80061
- },
80062
- {
80063
- key: "addonRoutes",
80064
- name: "addon-routes"
80065
- },
80066
- {
80067
- key: "addonSettings",
80068
- name: "addon-settings"
80069
- },
80070
- {
80071
- key: "addonWidgets",
80072
- name: "addon-widgets"
80073
- },
80074
- {
80075
- key: "addonWidgetsSource",
80076
- name: "addon-widgets-source"
80077
- },
80078
- {
80079
- key: "addons",
80080
- name: "addons"
80081
- },
80082
- {
80083
- key: "adminUi",
80084
- name: "admin-ui"
80085
- },
80086
- {
80087
- key: "airQualitySensor",
80088
- name: "air-quality-sensor"
80089
- },
80090
- {
80091
- key: "alarmPanel",
80092
- name: "alarm-panel"
80093
- },
80094
- {
80095
- key: "alerts",
80096
- name: "alerts"
80097
- },
80098
- {
80099
- key: "ambientLightSensor",
80100
- name: "ambient-light-sensor"
80101
- },
80102
- {
80103
- key: "audioAnalysis",
80104
- name: "audio-analysis"
80105
- },
80106
- {
80107
- key: "audioAnalyzer",
80108
- name: "audio-analyzer"
80109
- },
80110
- {
80111
- key: "audioCodec",
80112
- name: "audio-codec"
80113
- },
80114
- {
80115
- key: "audioMetrics",
80116
- name: "audio-metrics"
80117
- },
80118
- {
80119
- key: "authProvider",
80120
- name: "auth-provider"
80121
- },
80122
- {
80123
- key: "automationControl",
80124
- name: "automation-control"
80125
- },
80126
- {
80127
- key: "backup",
80128
- name: "backup"
80129
- },
80130
- {
80131
- key: "battery",
80132
- name: "battery"
80133
- },
80134
- {
80135
- key: "binary",
80136
- name: "binary"
80137
- },
80138
- {
80139
- key: "brightness",
80140
- name: "brightness"
80141
- },
80142
- {
80143
- key: "broker",
80144
- name: "broker"
80145
- },
80146
- {
80147
- key: "button",
80148
- name: "button"
80149
- },
80150
- {
80151
- key: "calendarSource",
80152
- name: "calendar-source"
80153
- },
80154
- {
80155
- key: "calendars",
80156
- name: "calendars"
80157
- },
80158
- {
80159
- key: "cameraCredentials",
80160
- name: "camera-credentials"
80161
- },
80162
- {
80163
- key: "cameraGridLayout",
80164
- name: "camera-grid-layout"
80165
- },
80166
- {
80167
- key: "cameraPipelineConfig",
80168
- name: "camera-pipeline-config"
80169
- },
80170
- {
80171
- key: "cameraStreams",
80172
- name: "camera-streams"
80173
- },
80174
- {
80175
- key: "carbonMonoxide",
80176
- name: "carbon-monoxide"
80177
- },
80178
- {
80179
- key: "climateControl",
80180
- name: "climate-control"
80181
- },
80182
- {
80183
- key: "color",
80184
- name: "color"
80185
- },
80186
- {
80187
- key: "composer",
80188
- name: "composer"
80189
- },
79937
+ var KNOWN_CAPS = new Set(require_sleep.CAP_NAMES);
79938
+ function primaryCapForRole(role) {
79939
+ if (role === null || role === "") return null;
79940
+ const aliased = ROLE_CAP_ALIASES[role];
79941
+ if (aliased !== void 0) return KNOWN_CAPS.has(aliased) ? aliased : null;
79942
+ return KNOWN_CAPS.has(role) ? role : null;
79943
+ }
79944
+ //#endregion
79945
+ //#region src/composition/cards/fill-status.ts
79946
+ function isUnfilledRequiredProblem(problem) {
79947
+ return problem.code === "missing-field";
79948
+ }
79949
+ function compositionFillStatus(problems) {
79950
+ return problems.some(isUnfilledRequiredProblem) ? "incomplete" : "complete";
79951
+ }
79952
+ /** True when the only problems are unfilled required fields — save may proceed. */
79953
+ function problemsBlockSave(problems) {
79954
+ return problems.some((p) => !isUnfilledRequiredProblem(p));
79955
+ }
79956
+ //#endregion
79957
+ //#region src/catalogs/plus-catalog-classmap.ts
79958
+ function isClassMapMacroTarget(value) {
79959
+ return CLASS_MAP_MACRO_TARGETS.some((target) => target === value);
79960
+ }
79961
+ /**
79962
+ * Raw plus catalog label → detection macro. Every label of the documented
79963
+ * plus catalog base set (docs.frigate.video/plus, verified 2026-08-21) is either
79964
+ * here or in {@link PLUS_CATALOG_UNMAPPED_LABELS}, with the reason it is not.
79965
+ *
79966
+ * Why this exists: a plus catalog import used to carry NO classMap, so it inherited
79967
+ * the step's `COCO_TO_MACRO` (`preserveOriginal: false`) and the executor
79968
+ * dropped every label COCO does not name — deer, raccoon, fox, squirrel, goat,
79969
+ * rabbit, skunk, kangaroo, possum, rodent, school_bus, garbage_truck and even
79970
+ * `package` vanished as `class-filter` discards. The executor keeps the raw
79971
+ * label as `originalClass` whenever the map resolves it, so the fine identity
79972
+ * survives under the macro.
79973
+ */
79974
+ var PLUS_CATALOG_TO_MACRO = {
79975
+ person: "person",
79976
+ baby: "person",
79977
+ car: "vehicle",
79978
+ motorcycle: "vehicle",
79979
+ bicycle: "vehicle",
79980
+ boat: "vehicle",
79981
+ school_bus: "vehicle",
79982
+ garbage_truck: "vehicle",
79983
+ dog: "animal",
79984
+ cat: "animal",
79985
+ deer: "animal",
79986
+ horse: "animal",
79987
+ bird: "animal",
79988
+ raccoon: "animal",
79989
+ fox: "animal",
79990
+ bear: "animal",
79991
+ cow: "animal",
79992
+ squirrel: "animal",
79993
+ goat: "animal",
79994
+ rabbit: "animal",
79995
+ skunk: "animal",
79996
+ kangaroo: "animal",
79997
+ possum: "animal",
79998
+ rodent: "animal",
79999
+ package: "package"
80000
+ };
80001
+ /**
80002
+ * plus catalog labels deliberately left OUT of {@link PLUS_CATALOG_TO_MACRO}.
80003
+ *
80004
+ * - `attribute`: plus catalog emits these INSIDE a parent box (a face inside a
80005
+ * person, a plate or a carrier logo on a vehicle). Mapping one to its
80006
+ * parent's macro would spawn a second, overlapping track for the same
80007
+ * subject. `face` and `license_plate` are instead declared as CROP supplies
80008
+ * (D730): the box becomes a detail child of the person / vehicle containing
80009
+ * it, when the face / plate step uses the root model.
80010
+ * - `no-macro`: an object with no detection macro to live under.
80011
+ */
80012
+ var PLUS_CATALOG_UNMAPPED_LABELS = {
80013
+ face: "attribute",
80014
+ license_plate: "attribute",
80015
+ amazon: "attribute",
80016
+ usps: "attribute",
80017
+ ups: "attribute",
80018
+ fedex: "attribute",
80019
+ dhl: "attribute",
80020
+ an_post: "attribute",
80021
+ purolator: "attribute",
80022
+ postnl: "attribute",
80023
+ nzpost: "attribute",
80024
+ postnord: "attribute",
80025
+ gls: "attribute",
80026
+ dpd: "attribute",
80027
+ canada_post: "attribute",
80028
+ royal_mail: "attribute",
80029
+ waste_bin: "no-macro",
80030
+ bbq_grill: "no-macro",
80031
+ robot_lawnmower: "no-macro",
80032
+ umbrella: "no-macro",
80033
+ baby_stroller: "no-macro"
80034
+ };
80035
+ /**
80036
+ * The per-model classMap for a plus catalog / plus catalog detector, derived from ITS
80037
+ * labelmap: each label resolves through {@link PLUS_CATALOG_TO_MACRO} first,
80038
+ * then `COCO_TO_MACRO` (plus catalog's default model ships the COCO-91 labelmap, so
80039
+ * a preset import may carry either vocabulary). A label neither knows is left
80040
+ * out, and `preserveOriginal: false` drops it in the executor — the same
80041
+ * contract as the COCO map, now with the plus catalog vocabulary in it.
80042
+ */
80043
+ function buildPlusCatalogClassMap(labels) {
80044
+ const mapping = {};
80045
+ for (const label of labels) {
80046
+ const target = PLUS_CATALOG_TO_MACRO[label] ?? COCO_TO_MACRO.mapping[label];
80047
+ if (target !== void 0 && isClassMapMacroTarget(target)) mapping[label] = target;
80048
+ }
80049
+ return {
80050
+ mapping,
80051
+ preserveOriginal: false
80052
+ };
80053
+ }
80054
+ /**
80055
+ * Everything a plus catalog / plus catalog entry derives from ITS OWN labelmap: the
80056
+ * classMap and the steps it can supply (D730) — label and crop kinds alike.
80057
+ * Every plus catalog builder spreads this at import, so the two cannot be derived
80058
+ * from different label lists, and no family is assumed to carry a label it
80059
+ * does not list.
80060
+ */
80061
+ function plusCatalogLabelFields(labels) {
80062
+ const classMap = buildPlusCatalogClassMap(labels);
80063
+ const supplies = deriveRootSupplies(labels, classMap);
80064
+ return supplies.length > 0 ? {
80065
+ classMap,
80066
+ suppliesSteps: supplies
80067
+ } : { classMap };
80068
+ }
80069
+ /**
80070
+ * Per-class confidence-floor defaults of an imported stock plus catalog detector
80071
+ * (D738): its per-detection `min_score` default, 0.5, for every class. Its
80072
+ * track-level `threshold` (the median of a track's recent scores) has no
80073
+ * counterpart in CamStack's per-detection floors and is not carried.
80074
+ */
80075
+ var PLUS_CATALOG_STOCK_CLASS_FLOORS = Object.freeze({
80076
+ person: .5,
80077
+ vehicle: .5,
80078
+ animal: .5
80079
+ });
80080
+ /**
80081
+ * Per-class floor defaults of an imported plus catalog detector (D738): the
80082
+ * documented starting `min_score` values for plus catalog models, which score
80083
+ * higher than the stock ones (person 0.65, car 0.65, cat 0.65, dog 0.70). The
80084
+ * macro `animal` takes the lower of its classes, so no class is cut above its
80085
+ * documented value.
80086
+ */
80087
+ var PLUS_CATALOG_CLASS_FLOORS = Object.freeze({
80088
+ person: .65,
80089
+ vehicle: .65,
80090
+ animal: .65
80091
+ });
80092
+ /**
80093
+ * The `defaultClassFloors` an imported plus catalog entry carries: the import's
80094
+ * own, when it states them, else the defaults of its kind. A fresh object.
80095
+ */
80096
+ function plusCatalogDefaultClassFloors(kind, carried) {
80097
+ if (carried !== void 0) return { ...carried };
80098
+ return { ...kind === "plus" ? PLUS_CATALOG_CLASS_FLOORS : PLUS_CATALOG_STOCK_CLASS_FLOORS };
80099
+ }
80100
+ //#endregion
80101
+ //#region src/catalogs/device-state-vocabulary.ts
80102
+ /**
80103
+ * Most specific first. Extending this list is how a new device kind becomes
80104
+ * gateable; nothing else needs to change.
80105
+ */
80106
+ var DEVICE_STATE_READERS = [
80190
80107
  {
80191
- key: "connectionTest",
80192
- name: "connection-test"
80108
+ cap: "alarm-panel",
80109
+ field: "state"
80193
80110
  },
80194
80111
  {
80195
- key: "connectivity",
80196
- name: "connectivity"
80112
+ cap: "cover",
80113
+ field: "state"
80197
80114
  },
80198
80115
  {
80199
- key: "consumables",
80200
- name: "consumables"
80116
+ cap: "presence",
80117
+ field: "state"
80201
80118
  },
80202
80119
  {
80203
- key: "contact",
80204
- name: "contact"
80120
+ cap: "lock-control",
80121
+ field: "state"
80205
80122
  },
80206
80123
  {
80207
- key: "control",
80208
- name: "control"
80124
+ cap: "contact",
80125
+ field: "entryOpen",
80126
+ booleanWords: ["open", "closed"]
80209
80127
  },
80210
80128
  {
80211
- key: "coreBlocks",
80212
- name: "core-blocks"
80213
- },
80214
- {
80215
- key: "cover",
80216
- name: "cover"
80217
- },
80218
- {
80219
- key: "customModelRegistry",
80220
- name: "custom-model-registry"
80221
- },
80222
- {
80223
- key: "dataStoreProvider",
80224
- name: "data-store-provider"
80225
- },
80226
- {
80227
- key: "databaseSnapshot",
80228
- name: "database-snapshot"
80229
- },
80230
- {
80231
- key: "dayNight",
80232
- name: "day-night"
80233
- },
80234
- {
80235
- key: "decoder",
80236
- name: "decoder"
80237
- },
80238
- {
80239
- key: "detectionPipeline",
80240
- name: "detection-pipeline"
80241
- },
80242
- {
80243
- key: "deviceAdminLink",
80244
- name: "device-admin-link"
80245
- },
80246
- {
80247
- key: "deviceAdoption",
80248
- name: "device-adoption"
80249
- },
80250
- {
80251
- key: "deviceCredentials",
80252
- name: "device-credentials"
80253
- },
80254
- {
80255
- key: "deviceDiscovery",
80256
- name: "device-discovery"
80257
- },
80258
- {
80259
- key: "deviceExport",
80260
- name: "device-export"
80261
- },
80262
- {
80263
- key: "deviceExtension",
80264
- name: "device-extension"
80265
- },
80266
- {
80267
- key: "deviceHistory",
80268
- name: "device-history"
80269
- },
80270
- {
80271
- key: "deviceManager",
80272
- name: "device-manager"
80273
- },
80274
- {
80275
- key: "deviceOps",
80276
- name: "device-ops"
80277
- },
80278
- {
80279
- key: "deviceProvider",
80280
- name: "device-provider"
80281
- },
80282
- {
80283
- key: "deviceRemovalHook",
80284
- name: "device-removal-hook"
80285
- },
80286
- {
80287
- key: "deviceState",
80288
- name: "device-state"
80289
- },
80290
- {
80291
- key: "deviceStatus",
80292
- name: "device-status"
80293
- },
80294
- {
80295
- key: "dishwasher",
80296
- name: "dishwasher"
80297
- },
80298
- {
80299
- key: "displayPalette",
80300
- name: "display-palette"
80301
- },
80302
- {
80303
- key: "doorbell",
80304
- name: "doorbell"
80305
- },
80306
- {
80307
- key: "embeddingEncoder",
80308
- name: "embedding-encoder"
80309
- },
80310
- {
80311
- key: "enumSensor",
80312
- name: "enum-sensor"
80313
- },
80314
- {
80315
- key: "eventEmitter",
80316
- name: "event-emitter"
80317
- },
80318
- {
80319
- key: "faceGallery",
80320
- name: "face-gallery"
80321
- },
80322
- {
80323
- key: "failureContribution",
80324
- name: "failure-contribution"
80325
- },
80326
- {
80327
- key: "fanControl",
80328
- name: "fan-control"
80329
- },
80330
- {
80331
- key: "featureProbe",
80332
- name: "feature-probe"
80333
- },
80334
- {
80335
- key: "filesystemBrowse",
80336
- name: "filesystem-browse"
80337
- },
80338
- {
80339
- key: "flood",
80340
- name: "flood"
80341
- },
80342
- {
80343
- key: "gas",
80344
- name: "gas"
80345
- },
80346
- {
80347
- key: "heatingValve",
80348
- name: "heating-valve"
80349
- },
80350
- {
80351
- key: "humidifier",
80352
- name: "humidifier"
80353
- },
80354
- {
80355
- key: "humiditySensor",
80356
- name: "humidity-sensor"
80357
- },
80358
- {
80359
- key: "image",
80360
- name: "image"
80361
- },
80362
- {
80363
- key: "imageSettings",
80364
- name: "image-settings"
80365
- },
80366
- {
80367
- key: "integrations",
80368
- name: "integrations"
80369
- },
80370
- {
80371
- key: "intercom",
80372
- name: "intercom"
80373
- },
80374
- {
80375
- key: "keychain",
80376
- name: "keychain"
80377
- },
80378
- {
80379
- key: "keychainAdmin",
80380
- name: "keychain-admin"
80381
- },
80382
- {
80383
- key: "lawnMowerControl",
80384
- name: "lawn-mower-control"
80385
- },
80386
- {
80387
- key: "llm",
80388
- name: "llm"
80389
- },
80390
- {
80391
- key: "llmRuntime",
80392
- name: "llm-runtime"
80393
- },
80394
- {
80395
- key: "loadContribution",
80396
- name: "load-contribution"
80397
- },
80398
- {
80399
- key: "localNetwork",
80400
- name: "local-network"
80401
- },
80402
- {
80403
- key: "lockControl",
80404
- name: "lock-control"
80405
- },
80406
- {
80407
- key: "logChannels",
80408
- name: "log-channels"
80409
- },
80410
- {
80411
- key: "logDestination",
80412
- name: "log-destination"
80413
- },
80414
- {
80415
- key: "loginMethod",
80416
- name: "login-method"
80417
- },
80418
- {
80419
- key: "mediaPlayer",
80420
- name: "media-player"
80421
- },
80422
- {
80423
- key: "meshNetwork",
80424
- name: "mesh-network"
80425
- },
80426
- {
80427
- key: "metricsProvider",
80428
- name: "metrics-provider"
80429
- },
80430
- {
80431
- key: "modelConvert",
80432
- name: "model-convert"
80433
- },
80434
- {
80435
- key: "modelDistributor",
80436
- name: "model-distributor"
80437
- },
80438
- {
80439
- key: "motion",
80440
- name: "motion"
80441
- },
80442
- {
80443
- key: "motionDetection",
80444
- name: "motion-detection"
80445
- },
80446
- {
80447
- key: "motionTrigger",
80448
- name: "motion-trigger"
80449
- },
80450
- {
80451
- key: "motionZones",
80452
- name: "motion-zones"
80453
- },
80454
- {
80455
- key: "mqttBroker",
80456
- name: "mqtt-broker"
80457
- },
80458
- {
80459
- key: "nativeObjectDetection",
80460
- name: "native-object-detection"
80461
- },
80462
- {
80463
- key: "navigation",
80464
- name: "navigation"
80465
- },
80466
- {
80467
- key: "networkAccess",
80468
- name: "network-access"
80469
- },
80470
- {
80471
- key: "networkLink",
80472
- name: "network-link"
80473
- },
80474
- {
80475
- key: "networkQuality",
80476
- name: "network-quality"
80477
- },
80478
- {
80479
- key: "nodeCertificates",
80480
- name: "node-certificates"
80481
- },
80482
- {
80483
- key: "nodes",
80484
- name: "nodes"
80485
- },
80486
- {
80487
- key: "notificationOutput",
80488
- name: "notification-output"
80489
- },
80490
- {
80491
- key: "notificationRules",
80492
- name: "notification-rules"
80493
- },
80494
- {
80495
- key: "notifier",
80496
- name: "notifier"
80497
- },
80498
- {
80499
- key: "numericSensor",
80500
- name: "numeric-sensor"
80501
- },
80502
- {
80503
- key: "oauthIntegration",
80504
- name: "oauth-integration"
80505
- },
80506
- {
80507
- key: "oidcConnections",
80508
- name: "oidc-connections"
80509
- },
80510
- {
80511
- key: "osd",
80512
- name: "osd"
80513
- },
80514
- {
80515
- key: "osdManager",
80516
- name: "osd-manager"
80517
- },
80518
- {
80519
- key: "petFeeder",
80520
- name: "pet-feeder"
80521
- },
80522
- {
80523
- key: "pipelineAnalytics",
80524
- name: "pipeline-analytics"
80525
- },
80526
- {
80527
- key: "pipelineExecutor",
80528
- name: "pipeline-executor"
80529
- },
80530
- {
80531
- key: "pipelineOrchestrator",
80532
- name: "pipeline-orchestrator"
80533
- },
80534
- {
80535
- key: "pipelineRunner",
80536
- name: "pipeline-runner"
80537
- },
80538
- {
80539
- key: "plateGallery",
80540
- name: "plate-gallery"
80541
- },
80542
- {
80543
- key: "platformProbe",
80544
- name: "platform-probe"
80545
- },
80546
- {
80547
- key: "powerMeter",
80548
- name: "power-meter"
80549
- },
80550
- {
80551
- key: "presence",
80552
- name: "presence"
80553
- },
80554
- {
80555
- key: "pressureSensor",
80556
- name: "pressure-sensor"
80557
- },
80558
- {
80559
- key: "privacyMask",
80560
- name: "privacy-mask"
80561
- },
80562
- {
80563
- key: "ptz",
80564
- name: "ptz"
80565
- },
80566
- {
80567
- key: "ptzAutotrack",
80568
- name: "ptz-autotrack"
80569
- },
80570
- {
80571
- key: "reboot",
80572
- name: "reboot"
80573
- },
80574
- {
80575
- key: "recordEntries",
80576
- name: "record-entries"
80577
- },
80578
- {
80579
- key: "recording",
80580
- name: "recording"
80581
- },
80582
- {
80583
- key: "recordingArchive",
80584
- name: "recording-archive"
80585
- },
80586
- {
80587
- key: "recordingExport",
80588
- name: "recording-export"
80589
- },
80590
- {
80591
- key: "recordingOnboard",
80592
- name: "recording-onboard"
80593
- },
80594
- {
80595
- key: "recordingSignal",
80596
- name: "recording-signal"
80597
- },
80598
- {
80599
- key: "records",
80600
- name: "records"
80601
- },
80602
- {
80603
- key: "runningState",
80604
- name: "running-state"
80605
- },
80606
- {
80607
- key: "sceneMonitor",
80608
- name: "scene-monitor"
80609
- },
80610
- {
80611
- key: "scriptRunner",
80612
- name: "script-runner"
80613
- },
80614
- {
80615
- key: "serverManagement",
80616
- name: "server-management"
80617
- },
80618
- {
80619
- key: "settingsStore",
80620
- name: "settings-store"
80621
- },
80622
- {
80623
- key: "smoke",
80624
- name: "smoke"
80625
- },
80626
- {
80627
- key: "smtpProvider",
80628
- name: "smtp-provider"
80629
- },
80630
- {
80631
- key: "snapshot",
80632
- name: "snapshot"
80633
- },
80634
- {
80635
- key: "ssoBridge",
80636
- name: "sso-bridge"
80637
- },
80638
- {
80639
- key: "storage",
80640
- name: "storage"
80641
- },
80642
- {
80643
- key: "storageAdmin",
80644
- name: "storage-admin"
80645
- },
80646
- {
80647
- key: "storageEvictable",
80648
- name: "storage-evictable"
80649
- },
80650
- {
80651
- key: "storageMigration",
80652
- name: "storage-migration"
80653
- },
80654
- {
80655
- key: "storageOccupancy",
80656
- name: "storage-occupancy"
80657
- },
80658
- {
80659
- key: "storageProvider",
80660
- name: "storage-provider"
80661
- },
80662
- {
80663
- key: "streamBroker",
80664
- name: "stream-broker"
80665
- },
80666
- {
80667
- key: "streamCatalog",
80668
- name: "stream-catalog"
80669
- },
80670
- {
80671
- key: "streamParams",
80672
- name: "stream-params"
80673
- },
80674
- {
80675
- key: "streamSignals",
80676
- name: "stream-signals"
80677
- },
80678
- {
80679
- key: "switch",
80680
- name: "switch"
80681
- },
80682
- {
80683
- key: "system",
80684
- name: "system"
80685
- },
80686
- {
80687
- key: "tamper",
80688
- name: "tamper"
80689
- },
80690
- {
80691
- key: "temperatureSensor",
80692
- name: "temperature-sensor"
80693
- },
80694
- {
80695
- key: "terminalSession",
80696
- name: "terminal-session"
80697
- },
80698
- {
80699
- key: "toast",
80700
- name: "toast"
80701
- },
80702
- {
80703
- key: "training",
80704
- name: "training"
80705
- },
80706
- {
80707
- key: "trainingProvider",
80708
- name: "training-provider"
80709
- },
80710
- {
80711
- key: "turnProvider",
80712
- name: "turn-provider"
80713
- },
80714
- {
80715
- key: "update",
80716
- name: "update"
80717
- },
80718
- {
80719
- key: "userManagement",
80720
- name: "user-management"
80721
- },
80722
- {
80723
- key: "userPasskeys",
80724
- name: "user-passkeys"
80725
- },
80726
- {
80727
- key: "vacuumControl",
80728
- name: "vacuum-control"
80729
- },
80730
- {
80731
- key: "valve",
80732
- name: "valve"
80733
- },
80734
- {
80735
- key: "vectorStore",
80736
- name: "vector-store"
80737
- },
80738
- {
80739
- key: "vibration",
80740
- name: "vibration"
80741
- },
80742
- {
80743
- key: "videoclips",
80744
- name: "videoclips"
80745
- },
80746
- {
80747
- key: "viewerUi",
80748
- name: "viewer-ui"
80749
- },
80750
- {
80751
- key: "waterHeater",
80752
- name: "water-heater"
80753
- },
80754
- {
80755
- key: "weather",
80756
- name: "weather"
80757
- },
80758
- {
80759
- key: "webrtcSession",
80760
- name: "webrtc-session"
80761
- },
80762
- {
80763
- key: "zoneAnalytics",
80764
- name: "zone-analytics"
80765
- },
80766
- {
80767
- key: "zoneRules",
80768
- name: "zone-rules"
80769
- },
80770
- {
80771
- key: "zones",
80772
- name: "zones"
80773
- }
80774
- ];
80775
- /**
80776
- * Every CapabilityDefinition shipped by `@camstack/types`. The hub
80777
- * iterates this array at boot to declare each cap on the registry
80778
- * before addons (in-process or via the Moleculer bridge) attempt
80779
- * `registerProvider`. Adding a new cap means dropping a `*.cap.ts`
80780
- * file in `packages/types/src/capabilities/` and re-running
80781
- * `npx tsx scripts/generate-capability-router-types.ts` — no manual
80782
- * edit to `main.ts` required.
80783
- */
80784
- var ALL_CAPABILITY_DEFINITIONS = [
80785
- accessoriesCapability,
80786
- addonPagesCapability,
80787
- addonPagesSourceCapability,
80788
- addonRoutesCapability,
80789
- addonSettingsCapability,
80790
- addonWidgetsCapability,
80791
- addonWidgetsSourceCapability,
80792
- addonsCapability,
80793
- require_sleep.adminUiCapability,
80794
- airQualitySensorCapability,
80795
- alarmPanelCapability,
80796
- alertsCapability,
80797
- ambientLightSensorCapability,
80798
- audioAnalysisCapability,
80799
- audioAnalyzerCapability,
80800
- audioCodecCapability,
80801
- audioMetricsCapability,
80802
- authProviderCapability,
80803
- automationControlCapability,
80804
- backupCapability,
80805
- batteryCapability,
80806
- binaryCapability,
80807
- brightnessCapability,
80808
- brokerCapability,
80809
- buttonCapability,
80810
- calendarSourceCapability,
80811
- calendarsCapability,
80812
- cameraCredentialsCapability,
80813
- cameraGridLayoutCapability,
80814
- cameraPipelineConfigCapability,
80815
- cameraStreamsCapability,
80816
- carbonMonoxideCapability,
80817
- climateControlCapability,
80818
- colorCapability,
80819
- composerCapability,
80820
- connectionTestCapability,
80821
- connectivityCapability,
80822
- consumablesCapability,
80823
- contactCapability,
80824
- controlCapability,
80825
- coreBlocksCapability,
80826
- coverCapability,
80827
- customModelRegistryCapability,
80828
- dataStoreProviderCapability,
80829
- databaseSnapshotCapability,
80830
- dayNightCapability,
80831
- decoderCapability,
80832
- detectionPipelineCapability,
80833
- deviceAdminLinkCapability,
80834
- deviceAdoptionCapability,
80835
- deviceCredentialsCapability,
80836
- deviceDiscoveryCapability,
80837
- deviceExportCapability,
80838
- deviceExtensionCapability,
80839
- deviceHistoryCapability,
80840
- deviceManagerCapability,
80841
- require_sleep.deviceOpsCapability,
80842
- deviceProviderCapability,
80843
- deviceRemovalHookCapability,
80844
- deviceStateCapability,
80845
- deviceStatusCapability,
80846
- dishwasherCapability,
80847
- displayPaletteCapability,
80848
- doorbellCapability,
80849
- embeddingEncoderCapability,
80850
- enumSensorCapability,
80851
- eventEmitterCapability,
80852
- faceGalleryCapability,
80853
- failureContributionCapability,
80854
- fanControlCapability,
80855
- featureProbeCapability,
80856
- filesystemBrowseCapability,
80857
- floodCapability,
80858
- gasCapability,
80859
- heatingValveCapability,
80860
- humidifierCapability,
80861
- humiditySensorCapability,
80862
- imageCapability,
80863
- imageSettingsCapability,
80864
- integrationsCapability,
80865
- intercomCapability,
80866
- keychainCapability,
80867
- keychainAdminCapability,
80868
- lawnMowerControlCapability,
80869
- llmCapability,
80870
- llmRuntimeCapability,
80871
- loadContributionCapability,
80872
- localNetworkCapability,
80873
- lockControlCapability,
80874
- logChannelsCapability,
80875
- logDestinationCapability,
80876
- loginMethodCapability,
80877
- mediaPlayerCapability,
80878
- meshNetworkCapability,
80879
- metricsProviderCapability,
80880
- modelConvertCapability,
80881
- modelDistributorCapability,
80882
- motionCapability,
80883
- motionDetectionCapability,
80884
- motionTriggerCapability,
80885
- motionZonesCapability,
80886
- mqttBrokerCapability,
80887
- nativeObjectDetectionCapability,
80888
- navigationCapability,
80889
- networkAccessCapability,
80890
- networkLinkCapability,
80891
- networkQualityCapability,
80892
- nodeCertificatesCapability,
80893
- nodesCapability,
80894
- notificationOutputCapability,
80895
- notificationRulesCapability,
80896
- notifierCapability,
80897
- numericSensorCapability,
80898
- oauthIntegrationCapability,
80899
- oidcConnectionsCapability,
80900
- osdCapability,
80901
- osdManagerCapability,
80902
- petFeederCapability,
80903
- pipelineAnalyticsCapability,
80904
- pipelineExecutorCapability,
80905
- pipelineOrchestratorCapability,
80906
- pipelineRunnerCapability,
80907
- plateGalleryCapability,
80908
- platformProbeCapability,
80909
- powerMeterCapability,
80910
- presenceCapability,
80911
- pressureSensorCapability,
80912
- privacyMaskCapability,
80913
- ptzCapability,
80914
- ptzAutotrackCapability,
80915
- rebootCapability,
80916
- recordEntriesCapability,
80917
- recordingCapability,
80918
- recordingArchiveCapability,
80919
- recordingExportCapability,
80920
- recordingOnboardCapability,
80921
- recordingSignalCapability,
80922
- recordsCapability,
80923
- runningStateCapability,
80924
- sceneMonitorCapability,
80925
- scriptRunnerCapability,
80926
- serverManagementCapability,
80927
- settingsStoreCapability,
80928
- smokeCapability,
80929
- smtpProviderCapability,
80930
- snapshotCapability,
80931
- ssoBridgeCapability,
80932
- storageCapability,
80933
- storageAdminCapability,
80934
- storageEvictableCapability,
80935
- storageMigrationCapability,
80936
- storageOccupancyCapability,
80937
- storageProviderCapability,
80938
- streamBrokerCapability,
80939
- streamCatalogCapability,
80940
- streamParamsCapability,
80941
- streamSignalsCapability,
80942
- switchCapability,
80943
- systemCapability,
80944
- tamperCapability,
80945
- temperatureSensorCapability,
80946
- terminalSessionCapability,
80947
- toastCapability,
80948
- trainingCapability,
80949
- trainingProviderCapability,
80950
- turnProviderCapability,
80951
- updateCapability,
80952
- userManagementCapability,
80953
- userPasskeysCapability,
80954
- vacuumControlCapability,
80955
- valveCapability,
80956
- vectorStoreCapability,
80957
- vibrationCapability,
80958
- videoclipsCapability,
80959
- require_sleep.viewerUiCapability,
80960
- waterHeaterCapability,
80961
- weatherCapability,
80962
- webrtcSessionCapability,
80963
- zoneAnalyticsCapability,
80964
- zoneRulesCapability,
80965
- zonesCapability
80966
- ];
80967
- //#endregion
80968
- //#region src/composition/cards/role-cap.ts
80969
- /**
80970
- * Map a device role to the primary composition cap (D939).
80971
- */
80972
- var ROLE_CAP_ALIASES = {
80973
- [require_err_msg.DeviceRole.BinarySensor]: "binary",
80974
- [require_err_msg.DeviceRole.MotionSensor]: "motion"
80975
- };
80976
- var KNOWN_CAPS = new Set(ALL_CAPABILITY_DEFINITIONS.map((def) => def.name));
80977
- function primaryCapForRole(role) {
80978
- if (role === null || role === "") return null;
80979
- const aliased = ROLE_CAP_ALIASES[role];
80980
- if (aliased !== void 0) return KNOWN_CAPS.has(aliased) ? aliased : null;
80981
- return KNOWN_CAPS.has(role) ? role : null;
80982
- }
80983
- //#endregion
80984
- //#region src/composition/cards/fill-status.ts
80985
- function isUnfilledRequiredProblem(problem) {
80986
- return problem.code === "missing-field";
80987
- }
80988
- function compositionFillStatus(problems) {
80989
- return problems.some(isUnfilledRequiredProblem) ? "incomplete" : "complete";
80990
- }
80991
- /** True when the only problems are unfilled required fields — save may proceed. */
80992
- function problemsBlockSave(problems) {
80993
- return problems.some((p) => !isUnfilledRequiredProblem(p));
80994
- }
80995
- //#endregion
80996
- //#region src/catalogs/frigate-plus-classmap.ts
80997
- function isClassMapMacroTarget(value) {
80998
- return CLASS_MAP_MACRO_TARGETS.some((target) => target === value);
80999
- }
81000
- /**
81001
- * Raw Frigate+ label → detection macro. Every label of the documented
81002
- * Frigate+ base set (docs.frigate.video/plus, verified 2026-08-21) is either
81003
- * here or in {@link FRIGATE_PLUS_UNMAPPED_LABELS}, with the reason it is not.
81004
- *
81005
- * Why this exists: a Frigate+ import used to carry NO classMap, so it inherited
81006
- * the step's `COCO_TO_MACRO` (`preserveOriginal: false`) and the executor
81007
- * dropped every label COCO does not name — deer, raccoon, fox, squirrel, goat,
81008
- * rabbit, skunk, kangaroo, possum, rodent, school_bus, garbage_truck and even
81009
- * `package` vanished as `class-filter` discards. The executor keeps the raw
81010
- * label as `originalClass` whenever the map resolves it, so the fine identity
81011
- * survives under the macro.
81012
- */
81013
- var FRIGATE_PLUS_TO_MACRO = {
81014
- person: "person",
81015
- baby: "person",
81016
- car: "vehicle",
81017
- motorcycle: "vehicle",
81018
- bicycle: "vehicle",
81019
- boat: "vehicle",
81020
- school_bus: "vehicle",
81021
- garbage_truck: "vehicle",
81022
- dog: "animal",
81023
- cat: "animal",
81024
- deer: "animal",
81025
- horse: "animal",
81026
- bird: "animal",
81027
- raccoon: "animal",
81028
- fox: "animal",
81029
- bear: "animal",
81030
- cow: "animal",
81031
- squirrel: "animal",
81032
- goat: "animal",
81033
- rabbit: "animal",
81034
- skunk: "animal",
81035
- kangaroo: "animal",
81036
- possum: "animal",
81037
- rodent: "animal",
81038
- package: "package"
81039
- };
81040
- /**
81041
- * Frigate+ labels deliberately left OUT of {@link FRIGATE_PLUS_TO_MACRO}.
81042
- *
81043
- * - `attribute`: Frigate+ emits these INSIDE a parent box (a face inside a
81044
- * person, a plate or a carrier logo on a vehicle). Mapping one to its
81045
- * parent's macro would spawn a second, overlapping track for the same
81046
- * subject. `face` and `license_plate` are instead declared as CROP supplies
81047
- * (D730): the box becomes a detail child of the person / vehicle containing
81048
- * it, when the face / plate step uses the root model.
81049
- * - `no-macro`: an object with no detection macro to live under.
81050
- */
81051
- var FRIGATE_PLUS_UNMAPPED_LABELS = {
81052
- face: "attribute",
81053
- license_plate: "attribute",
81054
- amazon: "attribute",
81055
- usps: "attribute",
81056
- ups: "attribute",
81057
- fedex: "attribute",
81058
- dhl: "attribute",
81059
- an_post: "attribute",
81060
- purolator: "attribute",
81061
- postnl: "attribute",
81062
- nzpost: "attribute",
81063
- postnord: "attribute",
81064
- gls: "attribute",
81065
- dpd: "attribute",
81066
- canada_post: "attribute",
81067
- royal_mail: "attribute",
81068
- waste_bin: "no-macro",
81069
- bbq_grill: "no-macro",
81070
- robot_lawnmower: "no-macro",
81071
- umbrella: "no-macro",
81072
- baby_stroller: "no-macro"
81073
- };
81074
- /**
81075
- * The per-model classMap for a Frigate / Frigate+ detector, derived from ITS
81076
- * labelmap: each label resolves through {@link FRIGATE_PLUS_TO_MACRO} first,
81077
- * then `COCO_TO_MACRO` (Frigate's default model ships the COCO-91 labelmap, so
81078
- * a preset import may carry either vocabulary). A label neither knows is left
81079
- * out, and `preserveOriginal: false` drops it in the executor — the same
81080
- * contract as the COCO map, now with the Frigate+ vocabulary in it.
81081
- */
81082
- function buildFrigateClassMap(labels) {
81083
- const mapping = {};
81084
- for (const label of labels) {
81085
- const target = FRIGATE_PLUS_TO_MACRO[label] ?? COCO_TO_MACRO.mapping[label];
81086
- if (target !== void 0 && isClassMapMacroTarget(target)) mapping[label] = target;
81087
- }
81088
- return {
81089
- mapping,
81090
- preserveOriginal: false
81091
- };
81092
- }
81093
- /**
81094
- * Everything a Frigate / Frigate+ entry derives from ITS OWN labelmap: the
81095
- * classMap and the steps it can supply (D730) — label and crop kinds alike.
81096
- * Every Frigate builder spreads this at import, so the two cannot be derived
81097
- * from different label lists, and no family is assumed to carry a label it
81098
- * does not list.
81099
- */
81100
- function frigateLabelFields(labels) {
81101
- const classMap = buildFrigateClassMap(labels);
81102
- const supplies = deriveRootSupplies(labels, classMap);
81103
- return supplies.length > 0 ? {
81104
- classMap,
81105
- suppliesSteps: supplies
81106
- } : { classMap };
81107
- }
81108
- /**
81109
- * Per-class confidence-floor defaults of an imported stock Frigate detector
81110
- * (D738): its per-detection `min_score` default, 0.5, for every class. Its
81111
- * track-level `threshold` (the median of a track's recent scores) has no
81112
- * counterpart in CamStack's per-detection floors and is not carried.
81113
- */
81114
- var FRIGATE_STOCK_CLASS_FLOORS = Object.freeze({
81115
- person: .5,
81116
- vehicle: .5,
81117
- animal: .5
81118
- });
81119
- /**
81120
- * Per-class floor defaults of an imported Frigate+ detector (D738): the
81121
- * documented starting `min_score` values for Frigate+ models, which score
81122
- * higher than the stock ones (person 0.65, car 0.65, cat 0.65, dog 0.70). The
81123
- * macro `animal` takes the lower of its classes, so no class is cut above its
81124
- * documented value.
81125
- */
81126
- var FRIGATE_PLUS_CLASS_FLOORS = Object.freeze({
81127
- person: .65,
81128
- vehicle: .65,
81129
- animal: .65
81130
- });
81131
- /**
81132
- * The `defaultClassFloors` an imported Frigate entry carries: the import's
81133
- * own, when it states them, else the defaults of its kind. A fresh object.
81134
- */
81135
- function frigateDefaultClassFloors(kind, carried) {
81136
- if (carried !== void 0) return { ...carried };
81137
- return { ...kind === "plus" ? FRIGATE_PLUS_CLASS_FLOORS : FRIGATE_STOCK_CLASS_FLOORS };
81138
- }
81139
- //#endregion
81140
- //#region src/catalogs/device-state-vocabulary.ts
81141
- /**
81142
- * Most specific first. Extending this list is how a new device kind becomes
81143
- * gateable; nothing else needs to change.
81144
- */
81145
- var DEVICE_STATE_READERS = [
81146
- {
81147
- cap: "alarm-panel",
81148
- field: "state"
81149
- },
81150
- {
81151
- cap: "cover",
81152
- field: "state"
81153
- },
81154
- {
81155
- cap: "presence",
81156
- field: "state"
81157
- },
81158
- {
81159
- cap: "lock-control",
81160
- field: "state"
81161
- },
81162
- {
81163
- cap: "contact",
81164
- field: "entryOpen",
81165
- booleanWords: ["open", "closed"]
81166
- },
81167
- {
81168
- cap: "switch",
81169
- field: "on",
81170
- booleanWords: ["on", "off"]
80129
+ cap: "switch",
80130
+ field: "on",
80131
+ booleanWords: ["on", "off"]
81171
80132
  },
81172
80133
  {
81173
80134
  cap: "binary",
@@ -82556,7 +81517,7 @@ var BaseDeviceProvider = class extends require_sleep.BaseAddon {
82556
81517
  * A top-level persisted row with NO configuration is a leftover, not a
82557
81518
  * device — quarantine it instead of dialling it.
82558
81519
  *
82559
- * Device 614 was deleted, resurrected as a config-less shell by a write
81520
+ * Device 105 was deleted, resurrected as a config-less shell by a write
82560
81521
  * already in flight (D376), and then dialled at every single boot: eight
82561
81522
  * `Failed to restore device — bounded retry scheduled` lines in one day,
82562
81523
  * each one the same Zod refusal on `host` and `password`. The bound was
@@ -83083,13 +82044,13 @@ function rank(type) {
83083
82044
  *
83084
82045
  * An exact case-insensitive match was not enough, and the failure was total
83085
82046
  * rather than marginal. An ESPHome shutter arrives as a container named
83086
- * `Tapparella-Cucina` whose children include the COVER, named `Tapparella
83087
- * cucina`, and a device-presence entity carrying the slug verbatim,
83088
- * `tapparella-cucina`. The slug matched the container exactly and the cover
82047
+ * `Tapparella-Kitchen` whose children include the COVER, named `Tapparella
82048
+ * kitchen`, and a device-presence entity carrying the slug verbatim,
82049
+ * `tapparella-kitchen`. The slug matched the container exactly and the cover
83089
82050
  * did not, so the namesake tie-break handed the container to a connectivity
83090
82051
  * indicator — and the viewer's accessory panel, which correctly shows only
83091
82052
  * children with an actuating control, then rendered NOTHING. The operator saw
83092
- * no shutters at all on cucina, studio and both veranda cameras (2026-09-22).
82053
+ * no shutters at all on kitchen, studio and both porch cameras (2026-09-22).
83093
82054
  *
83094
82055
  * `Markise` was the control case that proved the mechanism: there the cover
83095
82056
  * really is called exactly like its container, so it won and appeared.
@@ -99191,148 +98152,1252 @@ function zodToConfigField(key, schema, description) {
99191
98152
  ...holdsSecret ? { secret: true } : {}
99192
98153
  };
99193
98154
  }
99194
- return {
99195
- ...base,
99196
- type: "text"
99197
- };
99198
- }
99199
- function buildStringField(key, base) {
99200
- const lowerKey = key.toLowerCase();
99201
- if (lowerKey.includes("password") || lowerKey.includes("secret") || lowerKey.includes("token") || lowerKey.includes("apikey") || lowerKey.includes("api_key")) return {
99202
- ...base,
99203
- type: "password",
99204
- showToggle: true
99205
- };
99206
- return {
99207
- ...base,
99208
- type: "text"
99209
- };
99210
- }
99211
- function buildNumberField(inner, base) {
99212
- const anyInner = zodInternals(inner);
99213
- const rawMin = anyInner.minValue;
99214
- const rawMax = anyInner.maxValue;
99215
- const min = rawMin != null && isFinite(rawMin) ? rawMin : void 0;
99216
- const max = rawMax != null && isFinite(rawMax) ? rawMax : void 0;
99217
- const step = getMultipleOfStep(inner);
99218
- return {
99219
- ...base,
99220
- type: "number",
99221
- ...min !== void 0 ? { min } : {},
99222
- ...max !== void 0 ? { max } : {},
99223
- ...step !== void 0 ? { step } : {}
99224
- };
99225
- }
99226
- function getMultipleOfStep(inner) {
99227
- const checks = zodDef(inner).checks ?? [];
99228
- for (const check of checks) if (check._zod?.def?.check === "multiple_of" && check._zod.def.value !== void 0) return check._zod.def.value;
99229
- }
99230
- function buildEnumField(inner, base) {
99231
- const values = inner.options.map((v) => String(v));
99232
- return {
99233
- ...base,
99234
- type: "select",
99235
- options: values.map((v) => ({
99236
- label: humanizeKey(v),
99237
- value: v
99238
- }))
99239
- };
99240
- }
99241
- function unwrapZod(schema) {
99242
- if (schema instanceof zod.z.ZodDefault) return unwrapZod(zodDef(schema).innerType);
99243
- if (schema instanceof zod.z.ZodOptional) return unwrapZod(zodDef(schema).innerType);
99244
- if (schema instanceof zod.z.ZodNullable) return unwrapZod(zodDef(schema).innerType);
99245
- return schema;
99246
- }
99247
- function getZodDefault(schema) {
99248
- if (schema instanceof zod.z.ZodDefault) return zodDef(schema).defaultValue;
99249
- }
99250
- function humanizeKey(key) {
99251
- return key.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/^\w/, (c) => c.toUpperCase()).trim();
99252
- }
99253
- //#endregion
99254
- //#region src/generated/cap-status-types.ts
98155
+ return {
98156
+ ...base,
98157
+ type: "text"
98158
+ };
98159
+ }
98160
+ function buildStringField(key, base) {
98161
+ const lowerKey = key.toLowerCase();
98162
+ if (lowerKey.includes("password") || lowerKey.includes("secret") || lowerKey.includes("token") || lowerKey.includes("apikey") || lowerKey.includes("api_key")) return {
98163
+ ...base,
98164
+ type: "password",
98165
+ showToggle: true
98166
+ };
98167
+ return {
98168
+ ...base,
98169
+ type: "text"
98170
+ };
98171
+ }
98172
+ function buildNumberField(inner, base) {
98173
+ const anyInner = zodInternals(inner);
98174
+ const rawMin = anyInner.minValue;
98175
+ const rawMax = anyInner.maxValue;
98176
+ const min = rawMin != null && isFinite(rawMin) ? rawMin : void 0;
98177
+ const max = rawMax != null && isFinite(rawMax) ? rawMax : void 0;
98178
+ const step = getMultipleOfStep(inner);
98179
+ return {
98180
+ ...base,
98181
+ type: "number",
98182
+ ...min !== void 0 ? { min } : {},
98183
+ ...max !== void 0 ? { max } : {},
98184
+ ...step !== void 0 ? { step } : {}
98185
+ };
98186
+ }
98187
+ function getMultipleOfStep(inner) {
98188
+ const checks = zodDef(inner).checks ?? [];
98189
+ for (const check of checks) if (check._zod?.def?.check === "multiple_of" && check._zod.def.value !== void 0) return check._zod.def.value;
98190
+ }
98191
+ function buildEnumField(inner, base) {
98192
+ const values = inner.options.map((v) => String(v));
98193
+ return {
98194
+ ...base,
98195
+ type: "select",
98196
+ options: values.map((v) => ({
98197
+ label: humanizeKey(v),
98198
+ value: v
98199
+ }))
98200
+ };
98201
+ }
98202
+ function unwrapZod(schema) {
98203
+ if (schema instanceof zod.z.ZodDefault) return unwrapZod(zodDef(schema).innerType);
98204
+ if (schema instanceof zod.z.ZodOptional) return unwrapZod(zodDef(schema).innerType);
98205
+ if (schema instanceof zod.z.ZodNullable) return unwrapZod(zodDef(schema).innerType);
98206
+ return schema;
98207
+ }
98208
+ function getZodDefault(schema) {
98209
+ if (schema instanceof zod.z.ZodDefault) return zodDef(schema).defaultValue;
98210
+ }
98211
+ function humanizeKey(key) {
98212
+ return key.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/^\w/, (c) => c.toUpperCase()).trim();
98213
+ }
98214
+ //#endregion
98215
+ //#region src/generated/cap-status-types.ts
98216
+ /**
98217
+ * Runtime list of cap names with status. Used by the settings
98218
+ * aggregator to enumerate caps whose `status` should be polled +
98219
+ * streamed via `subscribeDeviceStatusAggregate`.
98220
+ */
98221
+ var CAP_NAMES_WITH_STATUS = [
98222
+ "accessories",
98223
+ "air-quality-sensor",
98224
+ "alarm-panel",
98225
+ "ambient-light-sensor",
98226
+ "automation-control",
98227
+ "battery",
98228
+ "binary",
98229
+ "brightness",
98230
+ "broker",
98231
+ "camera-credentials",
98232
+ "carbon-monoxide",
98233
+ "climate-control",
98234
+ "color",
98235
+ "connectivity",
98236
+ "consumables",
98237
+ "contact",
98238
+ "control",
98239
+ "cover",
98240
+ "day-night",
98241
+ "device-adoption",
98242
+ "device-discovery",
98243
+ "device-export",
98244
+ "device-status",
98245
+ "dishwasher",
98246
+ "doorbell",
98247
+ "enum-sensor",
98248
+ "event-emitter",
98249
+ "fan-control",
98250
+ "feature-probe",
98251
+ "flood",
98252
+ "gas",
98253
+ "heating-valve",
98254
+ "humidifier",
98255
+ "humidity-sensor",
98256
+ "image",
98257
+ "image-settings",
98258
+ "intercom",
98259
+ "lawn-mower-control",
98260
+ "lock-control",
98261
+ "media-player",
98262
+ "motion",
98263
+ "motion-trigger",
98264
+ "motion-zones",
98265
+ "mqtt-broker",
98266
+ "native-object-detection",
98267
+ "navigation",
98268
+ "network-link",
98269
+ "notifier",
98270
+ "numeric-sensor",
98271
+ "osd",
98272
+ "pet-feeder",
98273
+ "power-meter",
98274
+ "presence",
98275
+ "pressure-sensor",
98276
+ "privacy-mask",
98277
+ "ptz",
98278
+ "ptz-autotrack",
98279
+ "recording-archive",
98280
+ "recording-onboard",
98281
+ "recording-signal",
98282
+ "running-state",
98283
+ "scene-monitor",
98284
+ "script-runner",
98285
+ "smoke",
98286
+ "snapshot",
98287
+ "stream-params",
98288
+ "switch",
98289
+ "tamper",
98290
+ "temperature-sensor",
98291
+ "update",
98292
+ "vacuum-control",
98293
+ "valve",
98294
+ "vibration",
98295
+ "water-heater",
98296
+ "weather"
98297
+ ];
98298
+ //#endregion
98299
+ //#region src/generated/capability-router-map.ts
98300
+ var CAPABILITY_NAMES = {
98301
+ accessories: "accessories",
98302
+ addonPages: "addon-pages",
98303
+ addonPagesSource: "addon-pages-source",
98304
+ addonRoutes: "addon-routes",
98305
+ addonSettings: "addon-settings",
98306
+ addonWidgets: "addon-widgets",
98307
+ addonWidgetsSource: "addon-widgets-source",
98308
+ addons: "addons",
98309
+ adminUi: "admin-ui",
98310
+ airQualitySensor: "air-quality-sensor",
98311
+ alarmPanel: "alarm-panel",
98312
+ alerts: "alerts",
98313
+ ambientLightSensor: "ambient-light-sensor",
98314
+ audioAnalysis: "audio-analysis",
98315
+ audioAnalyzer: "audio-analyzer",
98316
+ audioCodec: "audio-codec",
98317
+ audioMetrics: "audio-metrics",
98318
+ authProvider: "auth-provider",
98319
+ automationControl: "automation-control",
98320
+ backup: "backup",
98321
+ battery: "battery",
98322
+ binary: "binary",
98323
+ brightness: "brightness",
98324
+ broker: "broker",
98325
+ button: "button",
98326
+ calendarSource: "calendar-source",
98327
+ calendars: "calendars",
98328
+ cameraCredentials: "camera-credentials",
98329
+ cameraGridLayout: "camera-grid-layout",
98330
+ cameraPipelineConfig: "camera-pipeline-config",
98331
+ cameraStreams: "camera-streams",
98332
+ carbonMonoxide: "carbon-monoxide",
98333
+ climateControl: "climate-control",
98334
+ color: "color",
98335
+ composer: "composer",
98336
+ connectionTest: "connection-test",
98337
+ connectivity: "connectivity",
98338
+ consumables: "consumables",
98339
+ contact: "contact",
98340
+ control: "control",
98341
+ coreBlocks: "core-blocks",
98342
+ cover: "cover",
98343
+ customModelRegistry: "custom-model-registry",
98344
+ dataStoreProvider: "data-store-provider",
98345
+ databaseSnapshot: "database-snapshot",
98346
+ dayNight: "day-night",
98347
+ decoder: "decoder",
98348
+ detectionPipeline: "detection-pipeline",
98349
+ deviceAdminLink: "device-admin-link",
98350
+ deviceAdoption: "device-adoption",
98351
+ deviceCredentials: "device-credentials",
98352
+ deviceDiscovery: "device-discovery",
98353
+ deviceExport: "device-export",
98354
+ deviceExtension: "device-extension",
98355
+ deviceHistory: "device-history",
98356
+ deviceManager: "device-manager",
98357
+ deviceOps: "device-ops",
98358
+ deviceProvider: "device-provider",
98359
+ deviceRemovalHook: "device-removal-hook",
98360
+ deviceState: "device-state",
98361
+ deviceStatus: "device-status",
98362
+ dishwasher: "dishwasher",
98363
+ displayPalette: "display-palette",
98364
+ doorbell: "doorbell",
98365
+ embeddingEncoder: "embedding-encoder",
98366
+ enumSensor: "enum-sensor",
98367
+ eventEmitter: "event-emitter",
98368
+ faceGallery: "face-gallery",
98369
+ failureContribution: "failure-contribution",
98370
+ fanControl: "fan-control",
98371
+ featureProbe: "feature-probe",
98372
+ filesystemBrowse: "filesystem-browse",
98373
+ flood: "flood",
98374
+ gas: "gas",
98375
+ heatingValve: "heating-valve",
98376
+ humidifier: "humidifier",
98377
+ humiditySensor: "humidity-sensor",
98378
+ image: "image",
98379
+ imageSettings: "image-settings",
98380
+ integrations: "integrations",
98381
+ intercom: "intercom",
98382
+ keychain: "keychain",
98383
+ keychainAdmin: "keychain-admin",
98384
+ lawnMowerControl: "lawn-mower-control",
98385
+ llm: "llm",
98386
+ llmRuntime: "llm-runtime",
98387
+ loadContribution: "load-contribution",
98388
+ localNetwork: "local-network",
98389
+ lockControl: "lock-control",
98390
+ logChannels: "log-channels",
98391
+ logDestination: "log-destination",
98392
+ loginMethod: "login-method",
98393
+ mediaPlayer: "media-player",
98394
+ meshNetwork: "mesh-network",
98395
+ metricsProvider: "metrics-provider",
98396
+ modelConvert: "model-convert",
98397
+ modelDistributor: "model-distributor",
98398
+ motion: "motion",
98399
+ motionDetection: "motion-detection",
98400
+ motionTrigger: "motion-trigger",
98401
+ motionZones: "motion-zones",
98402
+ mqttBroker: "mqtt-broker",
98403
+ nativeObjectDetection: "native-object-detection",
98404
+ navigation: "navigation",
98405
+ networkAccess: "network-access",
98406
+ networkLink: "network-link",
98407
+ networkQuality: "network-quality",
98408
+ nodeCertificates: "node-certificates",
98409
+ nodes: "nodes",
98410
+ notificationOutput: "notification-output",
98411
+ notificationRules: "notification-rules",
98412
+ notifier: "notifier",
98413
+ numericSensor: "numeric-sensor",
98414
+ oauthIntegration: "oauth-integration",
98415
+ oidcConnections: "oidc-connections",
98416
+ osd: "osd",
98417
+ osdManager: "osd-manager",
98418
+ petFeeder: "pet-feeder",
98419
+ pipelineAnalytics: "pipeline-analytics",
98420
+ pipelineExecutor: "pipeline-executor",
98421
+ pipelineOrchestrator: "pipeline-orchestrator",
98422
+ pipelineRunner: "pipeline-runner",
98423
+ plateGallery: "plate-gallery",
98424
+ platformProbe: "platform-probe",
98425
+ powerMeter: "power-meter",
98426
+ presence: "presence",
98427
+ pressureSensor: "pressure-sensor",
98428
+ privacyMask: "privacy-mask",
98429
+ ptz: "ptz",
98430
+ ptzAutotrack: "ptz-autotrack",
98431
+ reboot: "reboot",
98432
+ recordEntries: "record-entries",
98433
+ recording: "recording",
98434
+ recordingArchive: "recording-archive",
98435
+ recordingExport: "recording-export",
98436
+ recordingOnboard: "recording-onboard",
98437
+ recordingSignal: "recording-signal",
98438
+ records: "records",
98439
+ runningState: "running-state",
98440
+ sceneMonitor: "scene-monitor",
98441
+ scriptRunner: "script-runner",
98442
+ serverManagement: "server-management",
98443
+ settingsStore: "settings-store",
98444
+ smoke: "smoke",
98445
+ smtpProvider: "smtp-provider",
98446
+ snapshot: "snapshot",
98447
+ ssoBridge: "sso-bridge",
98448
+ storage: "storage",
98449
+ storageAdmin: "storage-admin",
98450
+ storageEvictable: "storage-evictable",
98451
+ storageMigration: "storage-migration",
98452
+ storageOccupancy: "storage-occupancy",
98453
+ storageProvider: "storage-provider",
98454
+ streamBroker: "stream-broker",
98455
+ streamCatalog: "stream-catalog",
98456
+ streamParams: "stream-params",
98457
+ streamSignals: "stream-signals",
98458
+ switch: "switch",
98459
+ system: "system",
98460
+ tamper: "tamper",
98461
+ temperatureSensor: "temperature-sensor",
98462
+ terminalSession: "terminal-session",
98463
+ toast: "toast",
98464
+ training: "training",
98465
+ trainingProvider: "training-provider",
98466
+ turnProvider: "turn-provider",
98467
+ update: "update",
98468
+ userManagement: "user-management",
98469
+ userPasskeys: "user-passkeys",
98470
+ vacuumControl: "vacuum-control",
98471
+ valve: "valve",
98472
+ vectorStore: "vector-store",
98473
+ vibration: "vibration",
98474
+ videoclips: "videoclips",
98475
+ viewerUi: "viewer-ui",
98476
+ waterHeater: "water-heater",
98477
+ weather: "weather",
98478
+ webrtcSession: "webrtc-session",
98479
+ zoneAnalytics: "zone-analytics",
98480
+ zoneRules: "zone-rules",
98481
+ zones: "zones"
98482
+ };
98483
+ /** Router key → capability name mapping for auto-mount. */
98484
+ var CAPABILITY_ROUTER_KEYS = [
98485
+ {
98486
+ key: "accessories",
98487
+ name: "accessories"
98488
+ },
98489
+ {
98490
+ key: "addonPages",
98491
+ name: "addon-pages"
98492
+ },
98493
+ {
98494
+ key: "addonPagesSource",
98495
+ name: "addon-pages-source"
98496
+ },
98497
+ {
98498
+ key: "addonRoutes",
98499
+ name: "addon-routes"
98500
+ },
98501
+ {
98502
+ key: "addonSettings",
98503
+ name: "addon-settings"
98504
+ },
98505
+ {
98506
+ key: "addonWidgets",
98507
+ name: "addon-widgets"
98508
+ },
98509
+ {
98510
+ key: "addonWidgetsSource",
98511
+ name: "addon-widgets-source"
98512
+ },
98513
+ {
98514
+ key: "addons",
98515
+ name: "addons"
98516
+ },
98517
+ {
98518
+ key: "adminUi",
98519
+ name: "admin-ui"
98520
+ },
98521
+ {
98522
+ key: "airQualitySensor",
98523
+ name: "air-quality-sensor"
98524
+ },
98525
+ {
98526
+ key: "alarmPanel",
98527
+ name: "alarm-panel"
98528
+ },
98529
+ {
98530
+ key: "alerts",
98531
+ name: "alerts"
98532
+ },
98533
+ {
98534
+ key: "ambientLightSensor",
98535
+ name: "ambient-light-sensor"
98536
+ },
98537
+ {
98538
+ key: "audioAnalysis",
98539
+ name: "audio-analysis"
98540
+ },
98541
+ {
98542
+ key: "audioAnalyzer",
98543
+ name: "audio-analyzer"
98544
+ },
98545
+ {
98546
+ key: "audioCodec",
98547
+ name: "audio-codec"
98548
+ },
98549
+ {
98550
+ key: "audioMetrics",
98551
+ name: "audio-metrics"
98552
+ },
98553
+ {
98554
+ key: "authProvider",
98555
+ name: "auth-provider"
98556
+ },
98557
+ {
98558
+ key: "automationControl",
98559
+ name: "automation-control"
98560
+ },
98561
+ {
98562
+ key: "backup",
98563
+ name: "backup"
98564
+ },
98565
+ {
98566
+ key: "battery",
98567
+ name: "battery"
98568
+ },
98569
+ {
98570
+ key: "binary",
98571
+ name: "binary"
98572
+ },
98573
+ {
98574
+ key: "brightness",
98575
+ name: "brightness"
98576
+ },
98577
+ {
98578
+ key: "broker",
98579
+ name: "broker"
98580
+ },
98581
+ {
98582
+ key: "button",
98583
+ name: "button"
98584
+ },
98585
+ {
98586
+ key: "calendarSource",
98587
+ name: "calendar-source"
98588
+ },
98589
+ {
98590
+ key: "calendars",
98591
+ name: "calendars"
98592
+ },
98593
+ {
98594
+ key: "cameraCredentials",
98595
+ name: "camera-credentials"
98596
+ },
98597
+ {
98598
+ key: "cameraGridLayout",
98599
+ name: "camera-grid-layout"
98600
+ },
98601
+ {
98602
+ key: "cameraPipelineConfig",
98603
+ name: "camera-pipeline-config"
98604
+ },
98605
+ {
98606
+ key: "cameraStreams",
98607
+ name: "camera-streams"
98608
+ },
98609
+ {
98610
+ key: "carbonMonoxide",
98611
+ name: "carbon-monoxide"
98612
+ },
98613
+ {
98614
+ key: "climateControl",
98615
+ name: "climate-control"
98616
+ },
98617
+ {
98618
+ key: "color",
98619
+ name: "color"
98620
+ },
98621
+ {
98622
+ key: "composer",
98623
+ name: "composer"
98624
+ },
98625
+ {
98626
+ key: "connectionTest",
98627
+ name: "connection-test"
98628
+ },
98629
+ {
98630
+ key: "connectivity",
98631
+ name: "connectivity"
98632
+ },
98633
+ {
98634
+ key: "consumables",
98635
+ name: "consumables"
98636
+ },
98637
+ {
98638
+ key: "contact",
98639
+ name: "contact"
98640
+ },
98641
+ {
98642
+ key: "control",
98643
+ name: "control"
98644
+ },
98645
+ {
98646
+ key: "coreBlocks",
98647
+ name: "core-blocks"
98648
+ },
98649
+ {
98650
+ key: "cover",
98651
+ name: "cover"
98652
+ },
98653
+ {
98654
+ key: "customModelRegistry",
98655
+ name: "custom-model-registry"
98656
+ },
98657
+ {
98658
+ key: "dataStoreProvider",
98659
+ name: "data-store-provider"
98660
+ },
98661
+ {
98662
+ key: "databaseSnapshot",
98663
+ name: "database-snapshot"
98664
+ },
98665
+ {
98666
+ key: "dayNight",
98667
+ name: "day-night"
98668
+ },
98669
+ {
98670
+ key: "decoder",
98671
+ name: "decoder"
98672
+ },
98673
+ {
98674
+ key: "detectionPipeline",
98675
+ name: "detection-pipeline"
98676
+ },
98677
+ {
98678
+ key: "deviceAdminLink",
98679
+ name: "device-admin-link"
98680
+ },
98681
+ {
98682
+ key: "deviceAdoption",
98683
+ name: "device-adoption"
98684
+ },
98685
+ {
98686
+ key: "deviceCredentials",
98687
+ name: "device-credentials"
98688
+ },
98689
+ {
98690
+ key: "deviceDiscovery",
98691
+ name: "device-discovery"
98692
+ },
98693
+ {
98694
+ key: "deviceExport",
98695
+ name: "device-export"
98696
+ },
98697
+ {
98698
+ key: "deviceExtension",
98699
+ name: "device-extension"
98700
+ },
98701
+ {
98702
+ key: "deviceHistory",
98703
+ name: "device-history"
98704
+ },
98705
+ {
98706
+ key: "deviceManager",
98707
+ name: "device-manager"
98708
+ },
98709
+ {
98710
+ key: "deviceOps",
98711
+ name: "device-ops"
98712
+ },
98713
+ {
98714
+ key: "deviceProvider",
98715
+ name: "device-provider"
98716
+ },
98717
+ {
98718
+ key: "deviceRemovalHook",
98719
+ name: "device-removal-hook"
98720
+ },
98721
+ {
98722
+ key: "deviceState",
98723
+ name: "device-state"
98724
+ },
98725
+ {
98726
+ key: "deviceStatus",
98727
+ name: "device-status"
98728
+ },
98729
+ {
98730
+ key: "dishwasher",
98731
+ name: "dishwasher"
98732
+ },
98733
+ {
98734
+ key: "displayPalette",
98735
+ name: "display-palette"
98736
+ },
98737
+ {
98738
+ key: "doorbell",
98739
+ name: "doorbell"
98740
+ },
98741
+ {
98742
+ key: "embeddingEncoder",
98743
+ name: "embedding-encoder"
98744
+ },
98745
+ {
98746
+ key: "enumSensor",
98747
+ name: "enum-sensor"
98748
+ },
98749
+ {
98750
+ key: "eventEmitter",
98751
+ name: "event-emitter"
98752
+ },
98753
+ {
98754
+ key: "faceGallery",
98755
+ name: "face-gallery"
98756
+ },
98757
+ {
98758
+ key: "failureContribution",
98759
+ name: "failure-contribution"
98760
+ },
98761
+ {
98762
+ key: "fanControl",
98763
+ name: "fan-control"
98764
+ },
98765
+ {
98766
+ key: "featureProbe",
98767
+ name: "feature-probe"
98768
+ },
98769
+ {
98770
+ key: "filesystemBrowse",
98771
+ name: "filesystem-browse"
98772
+ },
98773
+ {
98774
+ key: "flood",
98775
+ name: "flood"
98776
+ },
98777
+ {
98778
+ key: "gas",
98779
+ name: "gas"
98780
+ },
98781
+ {
98782
+ key: "heatingValve",
98783
+ name: "heating-valve"
98784
+ },
98785
+ {
98786
+ key: "humidifier",
98787
+ name: "humidifier"
98788
+ },
98789
+ {
98790
+ key: "humiditySensor",
98791
+ name: "humidity-sensor"
98792
+ },
98793
+ {
98794
+ key: "image",
98795
+ name: "image"
98796
+ },
98797
+ {
98798
+ key: "imageSettings",
98799
+ name: "image-settings"
98800
+ },
98801
+ {
98802
+ key: "integrations",
98803
+ name: "integrations"
98804
+ },
98805
+ {
98806
+ key: "intercom",
98807
+ name: "intercom"
98808
+ },
98809
+ {
98810
+ key: "keychain",
98811
+ name: "keychain"
98812
+ },
98813
+ {
98814
+ key: "keychainAdmin",
98815
+ name: "keychain-admin"
98816
+ },
98817
+ {
98818
+ key: "lawnMowerControl",
98819
+ name: "lawn-mower-control"
98820
+ },
98821
+ {
98822
+ key: "llm",
98823
+ name: "llm"
98824
+ },
98825
+ {
98826
+ key: "llmRuntime",
98827
+ name: "llm-runtime"
98828
+ },
98829
+ {
98830
+ key: "loadContribution",
98831
+ name: "load-contribution"
98832
+ },
98833
+ {
98834
+ key: "localNetwork",
98835
+ name: "local-network"
98836
+ },
98837
+ {
98838
+ key: "lockControl",
98839
+ name: "lock-control"
98840
+ },
98841
+ {
98842
+ key: "logChannels",
98843
+ name: "log-channels"
98844
+ },
98845
+ {
98846
+ key: "logDestination",
98847
+ name: "log-destination"
98848
+ },
98849
+ {
98850
+ key: "loginMethod",
98851
+ name: "login-method"
98852
+ },
98853
+ {
98854
+ key: "mediaPlayer",
98855
+ name: "media-player"
98856
+ },
98857
+ {
98858
+ key: "meshNetwork",
98859
+ name: "mesh-network"
98860
+ },
98861
+ {
98862
+ key: "metricsProvider",
98863
+ name: "metrics-provider"
98864
+ },
98865
+ {
98866
+ key: "modelConvert",
98867
+ name: "model-convert"
98868
+ },
98869
+ {
98870
+ key: "modelDistributor",
98871
+ name: "model-distributor"
98872
+ },
98873
+ {
98874
+ key: "motion",
98875
+ name: "motion"
98876
+ },
98877
+ {
98878
+ key: "motionDetection",
98879
+ name: "motion-detection"
98880
+ },
98881
+ {
98882
+ key: "motionTrigger",
98883
+ name: "motion-trigger"
98884
+ },
98885
+ {
98886
+ key: "motionZones",
98887
+ name: "motion-zones"
98888
+ },
98889
+ {
98890
+ key: "mqttBroker",
98891
+ name: "mqtt-broker"
98892
+ },
98893
+ {
98894
+ key: "nativeObjectDetection",
98895
+ name: "native-object-detection"
98896
+ },
98897
+ {
98898
+ key: "navigation",
98899
+ name: "navigation"
98900
+ },
98901
+ {
98902
+ key: "networkAccess",
98903
+ name: "network-access"
98904
+ },
98905
+ {
98906
+ key: "networkLink",
98907
+ name: "network-link"
98908
+ },
98909
+ {
98910
+ key: "networkQuality",
98911
+ name: "network-quality"
98912
+ },
98913
+ {
98914
+ key: "nodeCertificates",
98915
+ name: "node-certificates"
98916
+ },
98917
+ {
98918
+ key: "nodes",
98919
+ name: "nodes"
98920
+ },
98921
+ {
98922
+ key: "notificationOutput",
98923
+ name: "notification-output"
98924
+ },
98925
+ {
98926
+ key: "notificationRules",
98927
+ name: "notification-rules"
98928
+ },
98929
+ {
98930
+ key: "notifier",
98931
+ name: "notifier"
98932
+ },
98933
+ {
98934
+ key: "numericSensor",
98935
+ name: "numeric-sensor"
98936
+ },
98937
+ {
98938
+ key: "oauthIntegration",
98939
+ name: "oauth-integration"
98940
+ },
98941
+ {
98942
+ key: "oidcConnections",
98943
+ name: "oidc-connections"
98944
+ },
98945
+ {
98946
+ key: "osd",
98947
+ name: "osd"
98948
+ },
98949
+ {
98950
+ key: "osdManager",
98951
+ name: "osd-manager"
98952
+ },
98953
+ {
98954
+ key: "petFeeder",
98955
+ name: "pet-feeder"
98956
+ },
98957
+ {
98958
+ key: "pipelineAnalytics",
98959
+ name: "pipeline-analytics"
98960
+ },
98961
+ {
98962
+ key: "pipelineExecutor",
98963
+ name: "pipeline-executor"
98964
+ },
98965
+ {
98966
+ key: "pipelineOrchestrator",
98967
+ name: "pipeline-orchestrator"
98968
+ },
98969
+ {
98970
+ key: "pipelineRunner",
98971
+ name: "pipeline-runner"
98972
+ },
98973
+ {
98974
+ key: "plateGallery",
98975
+ name: "plate-gallery"
98976
+ },
98977
+ {
98978
+ key: "platformProbe",
98979
+ name: "platform-probe"
98980
+ },
98981
+ {
98982
+ key: "powerMeter",
98983
+ name: "power-meter"
98984
+ },
98985
+ {
98986
+ key: "presence",
98987
+ name: "presence"
98988
+ },
98989
+ {
98990
+ key: "pressureSensor",
98991
+ name: "pressure-sensor"
98992
+ },
98993
+ {
98994
+ key: "privacyMask",
98995
+ name: "privacy-mask"
98996
+ },
98997
+ {
98998
+ key: "ptz",
98999
+ name: "ptz"
99000
+ },
99001
+ {
99002
+ key: "ptzAutotrack",
99003
+ name: "ptz-autotrack"
99004
+ },
99005
+ {
99006
+ key: "reboot",
99007
+ name: "reboot"
99008
+ },
99009
+ {
99010
+ key: "recordEntries",
99011
+ name: "record-entries"
99012
+ },
99013
+ {
99014
+ key: "recording",
99015
+ name: "recording"
99016
+ },
99017
+ {
99018
+ key: "recordingArchive",
99019
+ name: "recording-archive"
99020
+ },
99021
+ {
99022
+ key: "recordingExport",
99023
+ name: "recording-export"
99024
+ },
99025
+ {
99026
+ key: "recordingOnboard",
99027
+ name: "recording-onboard"
99028
+ },
99029
+ {
99030
+ key: "recordingSignal",
99031
+ name: "recording-signal"
99032
+ },
99033
+ {
99034
+ key: "records",
99035
+ name: "records"
99036
+ },
99037
+ {
99038
+ key: "runningState",
99039
+ name: "running-state"
99040
+ },
99041
+ {
99042
+ key: "sceneMonitor",
99043
+ name: "scene-monitor"
99044
+ },
99045
+ {
99046
+ key: "scriptRunner",
99047
+ name: "script-runner"
99048
+ },
99049
+ {
99050
+ key: "serverManagement",
99051
+ name: "server-management"
99052
+ },
99053
+ {
99054
+ key: "settingsStore",
99055
+ name: "settings-store"
99056
+ },
99057
+ {
99058
+ key: "smoke",
99059
+ name: "smoke"
99060
+ },
99061
+ {
99062
+ key: "smtpProvider",
99063
+ name: "smtp-provider"
99064
+ },
99065
+ {
99066
+ key: "snapshot",
99067
+ name: "snapshot"
99068
+ },
99069
+ {
99070
+ key: "ssoBridge",
99071
+ name: "sso-bridge"
99072
+ },
99073
+ {
99074
+ key: "storage",
99075
+ name: "storage"
99076
+ },
99077
+ {
99078
+ key: "storageAdmin",
99079
+ name: "storage-admin"
99080
+ },
99081
+ {
99082
+ key: "storageEvictable",
99083
+ name: "storage-evictable"
99084
+ },
99085
+ {
99086
+ key: "storageMigration",
99087
+ name: "storage-migration"
99088
+ },
99089
+ {
99090
+ key: "storageOccupancy",
99091
+ name: "storage-occupancy"
99092
+ },
99093
+ {
99094
+ key: "storageProvider",
99095
+ name: "storage-provider"
99096
+ },
99097
+ {
99098
+ key: "streamBroker",
99099
+ name: "stream-broker"
99100
+ },
99101
+ {
99102
+ key: "streamCatalog",
99103
+ name: "stream-catalog"
99104
+ },
99105
+ {
99106
+ key: "streamParams",
99107
+ name: "stream-params"
99108
+ },
99109
+ {
99110
+ key: "streamSignals",
99111
+ name: "stream-signals"
99112
+ },
99113
+ {
99114
+ key: "switch",
99115
+ name: "switch"
99116
+ },
99117
+ {
99118
+ key: "system",
99119
+ name: "system"
99120
+ },
99121
+ {
99122
+ key: "tamper",
99123
+ name: "tamper"
99124
+ },
99125
+ {
99126
+ key: "temperatureSensor",
99127
+ name: "temperature-sensor"
99128
+ },
99129
+ {
99130
+ key: "terminalSession",
99131
+ name: "terminal-session"
99132
+ },
99133
+ {
99134
+ key: "toast",
99135
+ name: "toast"
99136
+ },
99137
+ {
99138
+ key: "training",
99139
+ name: "training"
99140
+ },
99141
+ {
99142
+ key: "trainingProvider",
99143
+ name: "training-provider"
99144
+ },
99145
+ {
99146
+ key: "turnProvider",
99147
+ name: "turn-provider"
99148
+ },
99149
+ {
99150
+ key: "update",
99151
+ name: "update"
99152
+ },
99153
+ {
99154
+ key: "userManagement",
99155
+ name: "user-management"
99156
+ },
99157
+ {
99158
+ key: "userPasskeys",
99159
+ name: "user-passkeys"
99160
+ },
99161
+ {
99162
+ key: "vacuumControl",
99163
+ name: "vacuum-control"
99164
+ },
99165
+ {
99166
+ key: "valve",
99167
+ name: "valve"
99168
+ },
99169
+ {
99170
+ key: "vectorStore",
99171
+ name: "vector-store"
99172
+ },
99173
+ {
99174
+ key: "vibration",
99175
+ name: "vibration"
99176
+ },
99177
+ {
99178
+ key: "videoclips",
99179
+ name: "videoclips"
99180
+ },
99181
+ {
99182
+ key: "viewerUi",
99183
+ name: "viewer-ui"
99184
+ },
99185
+ {
99186
+ key: "waterHeater",
99187
+ name: "water-heater"
99188
+ },
99189
+ {
99190
+ key: "weather",
99191
+ name: "weather"
99192
+ },
99193
+ {
99194
+ key: "webrtcSession",
99195
+ name: "webrtc-session"
99196
+ },
99197
+ {
99198
+ key: "zoneAnalytics",
99199
+ name: "zone-analytics"
99200
+ },
99201
+ {
99202
+ key: "zoneRules",
99203
+ name: "zone-rules"
99204
+ },
99205
+ {
99206
+ key: "zones",
99207
+ name: "zones"
99208
+ }
99209
+ ];
99255
99210
  /**
99256
- * Runtime list of cap names with status. Used by the settings
99257
- * aggregator to enumerate caps whose `status` should be polled +
99258
- * streamed via `subscribeDeviceStatusAggregate`.
99211
+ * Every CapabilityDefinition shipped by `@camstack/types`. The hub
99212
+ * iterates this array at boot to declare each cap on the registry
99213
+ * before addons (in-process or via the Moleculer bridge) attempt
99214
+ * `registerProvider`. Adding a new cap means dropping a `*.cap.ts`
99215
+ * file in `packages/types/src/capabilities/` and re-running
99216
+ * `npx tsx scripts/generate-capability-router-types.ts` — no manual
99217
+ * edit to `main.ts` required.
99259
99218
  */
99260
- var CAP_NAMES_WITH_STATUS = [
99261
- "accessories",
99262
- "air-quality-sensor",
99263
- "alarm-panel",
99264
- "ambient-light-sensor",
99265
- "automation-control",
99266
- "battery",
99267
- "binary",
99268
- "brightness",
99269
- "broker",
99270
- "camera-credentials",
99271
- "carbon-monoxide",
99272
- "climate-control",
99273
- "color",
99274
- "connectivity",
99275
- "consumables",
99276
- "contact",
99277
- "control",
99278
- "cover",
99279
- "day-night",
99280
- "device-adoption",
99281
- "device-discovery",
99282
- "device-export",
99283
- "device-status",
99284
- "dishwasher",
99285
- "doorbell",
99286
- "enum-sensor",
99287
- "event-emitter",
99288
- "fan-control",
99289
- "feature-probe",
99290
- "flood",
99291
- "gas",
99292
- "heating-valve",
99293
- "humidifier",
99294
- "humidity-sensor",
99295
- "image",
99296
- "image-settings",
99297
- "intercom",
99298
- "lawn-mower-control",
99299
- "lock-control",
99300
- "media-player",
99301
- "motion",
99302
- "motion-trigger",
99303
- "motion-zones",
99304
- "mqtt-broker",
99305
- "native-object-detection",
99306
- "navigation",
99307
- "network-link",
99308
- "notifier",
99309
- "numeric-sensor",
99310
- "osd",
99311
- "pet-feeder",
99312
- "power-meter",
99313
- "presence",
99314
- "pressure-sensor",
99315
- "privacy-mask",
99316
- "ptz",
99317
- "ptz-autotrack",
99318
- "recording-archive",
99319
- "recording-onboard",
99320
- "recording-signal",
99321
- "running-state",
99322
- "scene-monitor",
99323
- "script-runner",
99324
- "smoke",
99325
- "snapshot",
99326
- "stream-params",
99327
- "switch",
99328
- "tamper",
99329
- "temperature-sensor",
99330
- "update",
99331
- "vacuum-control",
99332
- "valve",
99333
- "vibration",
99334
- "water-heater",
99335
- "weather"
99219
+ var ALL_CAPABILITY_DEFINITIONS = [
99220
+ accessoriesCapability,
99221
+ addonPagesCapability,
99222
+ addonPagesSourceCapability,
99223
+ addonRoutesCapability,
99224
+ addonSettingsCapability,
99225
+ addonWidgetsCapability,
99226
+ addonWidgetsSourceCapability,
99227
+ addonsCapability,
99228
+ require_sleep.adminUiCapability,
99229
+ airQualitySensorCapability,
99230
+ alarmPanelCapability,
99231
+ alertsCapability,
99232
+ ambientLightSensorCapability,
99233
+ audioAnalysisCapability,
99234
+ audioAnalyzerCapability,
99235
+ audioCodecCapability,
99236
+ audioMetricsCapability,
99237
+ authProviderCapability,
99238
+ automationControlCapability,
99239
+ backupCapability,
99240
+ batteryCapability,
99241
+ binaryCapability,
99242
+ brightnessCapability,
99243
+ brokerCapability,
99244
+ buttonCapability,
99245
+ calendarSourceCapability,
99246
+ calendarsCapability,
99247
+ cameraCredentialsCapability,
99248
+ cameraGridLayoutCapability,
99249
+ cameraPipelineConfigCapability,
99250
+ cameraStreamsCapability,
99251
+ carbonMonoxideCapability,
99252
+ climateControlCapability,
99253
+ colorCapability,
99254
+ composerCapability,
99255
+ connectionTestCapability,
99256
+ connectivityCapability,
99257
+ consumablesCapability,
99258
+ contactCapability,
99259
+ controlCapability,
99260
+ coreBlocksCapability,
99261
+ coverCapability,
99262
+ customModelRegistryCapability,
99263
+ dataStoreProviderCapability,
99264
+ databaseSnapshotCapability,
99265
+ dayNightCapability,
99266
+ decoderCapability,
99267
+ detectionPipelineCapability,
99268
+ deviceAdminLinkCapability,
99269
+ deviceAdoptionCapability,
99270
+ deviceCredentialsCapability,
99271
+ deviceDiscoveryCapability,
99272
+ deviceExportCapability,
99273
+ deviceExtensionCapability,
99274
+ deviceHistoryCapability,
99275
+ deviceManagerCapability,
99276
+ require_sleep.deviceOpsCapability,
99277
+ deviceProviderCapability,
99278
+ deviceRemovalHookCapability,
99279
+ deviceStateCapability,
99280
+ deviceStatusCapability,
99281
+ dishwasherCapability,
99282
+ displayPaletteCapability,
99283
+ doorbellCapability,
99284
+ embeddingEncoderCapability,
99285
+ enumSensorCapability,
99286
+ eventEmitterCapability,
99287
+ faceGalleryCapability,
99288
+ failureContributionCapability,
99289
+ fanControlCapability,
99290
+ featureProbeCapability,
99291
+ filesystemBrowseCapability,
99292
+ floodCapability,
99293
+ gasCapability,
99294
+ heatingValveCapability,
99295
+ humidifierCapability,
99296
+ humiditySensorCapability,
99297
+ imageCapability,
99298
+ imageSettingsCapability,
99299
+ integrationsCapability,
99300
+ intercomCapability,
99301
+ keychainCapability,
99302
+ keychainAdminCapability,
99303
+ lawnMowerControlCapability,
99304
+ llmCapability,
99305
+ llmRuntimeCapability,
99306
+ loadContributionCapability,
99307
+ localNetworkCapability,
99308
+ lockControlCapability,
99309
+ logChannelsCapability,
99310
+ logDestinationCapability,
99311
+ loginMethodCapability,
99312
+ mediaPlayerCapability,
99313
+ meshNetworkCapability,
99314
+ metricsProviderCapability,
99315
+ modelConvertCapability,
99316
+ modelDistributorCapability,
99317
+ motionCapability,
99318
+ motionDetectionCapability,
99319
+ motionTriggerCapability,
99320
+ motionZonesCapability,
99321
+ mqttBrokerCapability,
99322
+ nativeObjectDetectionCapability,
99323
+ navigationCapability,
99324
+ networkAccessCapability,
99325
+ networkLinkCapability,
99326
+ networkQualityCapability,
99327
+ nodeCertificatesCapability,
99328
+ nodesCapability,
99329
+ notificationOutputCapability,
99330
+ notificationRulesCapability,
99331
+ notifierCapability,
99332
+ numericSensorCapability,
99333
+ oauthIntegrationCapability,
99334
+ oidcConnectionsCapability,
99335
+ osdCapability,
99336
+ osdManagerCapability,
99337
+ petFeederCapability,
99338
+ pipelineAnalyticsCapability,
99339
+ pipelineExecutorCapability,
99340
+ pipelineOrchestratorCapability,
99341
+ pipelineRunnerCapability,
99342
+ plateGalleryCapability,
99343
+ platformProbeCapability,
99344
+ powerMeterCapability,
99345
+ presenceCapability,
99346
+ pressureSensorCapability,
99347
+ privacyMaskCapability,
99348
+ ptzCapability,
99349
+ ptzAutotrackCapability,
99350
+ rebootCapability,
99351
+ recordEntriesCapability,
99352
+ recordingCapability,
99353
+ recordingArchiveCapability,
99354
+ recordingExportCapability,
99355
+ recordingOnboardCapability,
99356
+ recordingSignalCapability,
99357
+ recordsCapability,
99358
+ runningStateCapability,
99359
+ sceneMonitorCapability,
99360
+ scriptRunnerCapability,
99361
+ serverManagementCapability,
99362
+ settingsStoreCapability,
99363
+ smokeCapability,
99364
+ smtpProviderCapability,
99365
+ snapshotCapability,
99366
+ ssoBridgeCapability,
99367
+ storageCapability,
99368
+ storageAdminCapability,
99369
+ storageEvictableCapability,
99370
+ storageMigrationCapability,
99371
+ storageOccupancyCapability,
99372
+ storageProviderCapability,
99373
+ streamBrokerCapability,
99374
+ streamCatalogCapability,
99375
+ streamParamsCapability,
99376
+ streamSignalsCapability,
99377
+ switchCapability,
99378
+ systemCapability,
99379
+ tamperCapability,
99380
+ temperatureSensorCapability,
99381
+ terminalSessionCapability,
99382
+ toastCapability,
99383
+ trainingCapability,
99384
+ trainingProviderCapability,
99385
+ turnProviderCapability,
99386
+ updateCapability,
99387
+ userManagementCapability,
99388
+ userPasskeysCapability,
99389
+ vacuumControlCapability,
99390
+ valveCapability,
99391
+ vectorStoreCapability,
99392
+ vibrationCapability,
99393
+ videoclipsCapability,
99394
+ require_sleep.viewerUiCapability,
99395
+ waterHeaterCapability,
99396
+ weatherCapability,
99397
+ webrtcSessionCapability,
99398
+ zoneAnalyticsCapability,
99399
+ zoneRulesCapability,
99400
+ zonesCapability
99336
99401
  ];
99337
99402
  //#endregion
99338
99403
  //#region src/generated/method-device-selectors.ts
@@ -103259,6 +103324,11 @@ var PulseOverrideDraftSchema = zod.z.object({
103259
103324
  targetId: zod.z.string().min(1),
103260
103325
  enabled: zod.z.boolean(),
103261
103326
  debounceMs: zod.z.number().nonnegative(),
103327
+ edges: zod.z.array(zod.z.enum([
103328
+ "rising",
103329
+ "button",
103330
+ "native-event"
103331
+ ])).min(1).optional(),
103262
103332
  sources: zod.z.array(OverrideSourceSchema).min(1)
103263
103333
  });
103264
103334
  var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: zod.z.enum([
@@ -104909,7 +104979,7 @@ var LABEL_CONDITION_IDS = new Set(["sensorKinds"]);
104909
104979
  * maps COCO onto the macro and drops the rest). A sub-type therefore names a key
104910
104980
  * that does not exist — the counter is 0 forever and the rule cannot fire.
104911
104981
  *
104912
- * Live cost, 2026-08-12: two rules on device 617 were authored with `car`
104982
+ * Live cost, 2026-08-12: two rules on device 102 were authored with `car`
104913
104983
  * because this picker offered the whole taxonomy. They were silent for a day.
104914
104984
  */
104915
104985
  var COUNT_CLASS_CONDITION_IDS = new Set(["occupancy"]);
@@ -107421,7 +107491,7 @@ var STATE_SUMMARY_SECTION_VARS = [
107421
107491
  {
107422
107492
  name: "summaryStreams",
107423
107493
  label: "Summary: streams offline",
107424
- example: "Ingresso (high) — since 06:40",
107494
+ example: "Front door (high) — since 06:40",
107425
107495
  kinds: ["stream-offline", "stream-online"]
107426
107496
  },
107427
107497
  {
@@ -107439,13 +107509,13 @@ var STATE_SUMMARY_SECTION_VARS = [
107439
107509
  {
107440
107510
  name: "summaryDetection",
107441
107511
  label: "Summary: cameras detecting nothing",
107442
- example: "Ingresso — since 05:10",
107512
+ example: "Front door — since 05:10",
107443
107513
  kinds: ["detection-blind"]
107444
107514
  },
107445
107515
  {
107446
107516
  name: "summaryNodes",
107447
107517
  label: "Summary: nodes",
107448
- example: "little-unraid — offline since 03:00",
107518
+ example: "agent-a — offline since 03:00",
107449
107519
  kinds: [
107450
107520
  "node-offline",
107451
107521
  "node-online",
@@ -107529,7 +107599,7 @@ var NC_TEMPLATE_VARS = [
107529
107599
  {
107530
107600
  name: "camera",
107531
107601
  label: "Camera",
107532
- example: "Ingresso",
107602
+ example: "Front door",
107533
107603
  group: "subject",
107534
107604
  families: ["rule", "timelapse"],
107535
107605
  systemEventKinds: [...DEVICE_EVENTS, "export-completed"]
@@ -107697,7 +107767,7 @@ var NC_TEMPLATE_VARS = [
107697
107767
  {
107698
107768
  name: "rule",
107699
107769
  label: "Rule name",
107700
- example: "Ingresso notte",
107770
+ example: "Front door notte",
107701
107771
  group: "rule",
107702
107772
  families: [
107703
107773
  "rule",
@@ -107798,7 +107868,7 @@ var NC_TEMPLATE_VARS = [
107798
107868
  {
107799
107869
  name: "deviceName",
107800
107870
  label: "Device",
107801
- example: "Ingresso",
107871
+ example: "Front door",
107802
107872
  group: "system",
107803
107873
  families: ["rule"],
107804
107874
  fields: [...RULE_TEXT],
@@ -107808,7 +107878,7 @@ var NC_TEMPLATE_VARS = [
107808
107878
  {
107809
107879
  name: "locations",
107810
107880
  label: "Intrusion locations",
107811
- example: "Ingresso, Corridoio, Salone",
107881
+ example: "Front door, Hallway, Hall",
107812
107882
  group: "system",
107813
107883
  families: ["rule"],
107814
107884
  fields: [...RULE_TEXT],
@@ -107818,7 +107888,7 @@ var NC_TEMPLATE_VARS = [
107818
107888
  {
107819
107889
  name: "deviceId",
107820
107890
  label: "Device id",
107821
- example: "617",
107891
+ example: "102",
107822
107892
  group: "system",
107823
107893
  families: ["rule"],
107824
107894
  fields: [...RULE_TEXT],
@@ -107906,7 +107976,7 @@ var NC_TEMPLATE_VARS = [
107906
107976
  {
107907
107977
  name: "nodeName",
107908
107978
  label: "Node name",
107909
- example: "little-unraid",
107979
+ example: "agent-a",
107910
107980
  group: "system",
107911
107981
  families: ["rule"],
107912
107982
  fields: [...RULE_TEXT],
@@ -107927,7 +107997,7 @@ var NC_TEMPLATE_VARS = [
107927
107997
  name: "devices",
107928
107998
  label: "Devices",
107929
107999
  description: "node-inference-unavailable: the affected cameras, comma-joined. Alarm arm / arming / refusal: HOW MANY devices are armed (or open).",
107930
- example: "Ingresso, Garage",
108000
+ example: "Front door, Garage",
107931
108001
  group: "system",
107932
108002
  families: ["rule"],
107933
108003
  fields: [...RULE_TEXT],
@@ -108128,7 +108198,7 @@ var NC_TEMPLATE_VARS = [
108128
108198
  name: "nodes",
108129
108199
  label: "Nodes",
108130
108200
  description: "Comma-joined node ids, when an update spans more than one — the single-node case names it through {{nodeId}} instead. `incomingFromUpdateAvailable` (event-intake.ts) fills `nodes` from ONE shared textParams object for both addon- and server-update-available, exactly like packageName/currentVersion/latestVersion/count — only the shipped TEXT (system.server-update-available.body.onNodes) reads it today, but the var is real on both kinds.",
108131
- example: "hub, little-unraid",
108201
+ example: "hub, agent-a",
108132
108202
  group: "system",
108133
108203
  families: ["rule"],
108134
108204
  fields: [...RULE_TEXT],
@@ -108239,7 +108309,7 @@ var NC_TEMPLATE_VARS = [
108239
108309
  {
108240
108310
  name: "title",
108241
108311
  label: "Export or alert title",
108242
- example: "Ingresso 08:00",
108312
+ example: "Front door 08:00",
108243
108313
  group: "system",
108244
108314
  families: ["rule"],
108245
108315
  fields: [...RULE_TEXT],
@@ -108353,7 +108423,7 @@ var NC_TEMPLATE_VARS = [
108353
108423
  name: "names",
108354
108424
  label: "Device names",
108355
108425
  description: "Armed / arming: the Active devices (or every skipped name when none are Active). Refusal: the open sensors.",
108356
- example: "Ingresso, Garage",
108426
+ example: "Front door, Garage",
108357
108427
  group: "system",
108358
108428
  families: ["rule"],
108359
108429
  fields: [...RULE_TEXT],
@@ -108401,7 +108471,7 @@ var NC_TEMPLATE_VARS = [
108401
108471
  name: "bypassedNames",
108402
108472
  label: "Bypassed sensors",
108403
108473
  description: "Sensors the operator armed around because they were open.",
108404
- example: "Finestra veranda",
108474
+ example: "Finestra porch",
108405
108475
  group: "system",
108406
108476
  families: ["rule"],
108407
108477
  fields: [...RULE_TEXT],
@@ -109829,7 +109899,7 @@ var TimelapseRuleInputSchema = zod.z.object({
109829
109899
  * The caption a rule that never set one gets.
109830
109900
  *
109831
109901
  * Rendered through the ordinary `{{var}}` pass at delivery, so a rule created
109832
- * before this field existed still reads "Timelapse Videocamera ingresso" and
109902
+ * before this field existed still reads "Timelapse Camera front door" and
109833
109903
  * not the literal braces.
109834
109904
  */
109835
109905
  var DEFAULT_TIMELAPSE_PREVIEW_TEXT = "Timelapse {{camera}}";
@@ -111471,7 +111541,7 @@ function classifyRegion(region, uncovered) {
111471
111541
  * The pass report counts the passes that RAN, so "the second pass stops running
111472
111542
  * when a person is beside the dog" — a plausible reading of
111473
111543
  * {@link RECOVERY_MAX_REGION_FRAME_FRACTION} and
111474
- * {@link RECOVERY_MIN_UNCOVERED_FRACTION}, and a live hypothesis on camera 615
111544
+ * {@link RECOVERY_MIN_UNCOVERED_FRACTION}, and a live hypothesis on camera 101
111475
111545
  * — could not be confirmed or killed from the logs at all. This classifies the
111476
111546
  * regions a frame offered, against the same predicate the planner filters on.
111477
111547
  */
@@ -111794,7 +111864,7 @@ function planMotionCropRegions(input) {
111794
111864
  * — and ceilinged at {@link RECOVERY_CROP_MAX_SIDE_PX}. The ceiling is NOT a
111795
111865
  * simplification either: at 1024 px the same 320 model scored the reference
111796
111866
  * dog 0.52–0.76, and at 1280 px lost it entirely
111797
- * (`docs/benchmarks/pipeline-frame-model-eval.md`, case `miss-dog-615`). A
111867
+ * (`docs/benchmarks/pipeline-frame-model-eval.md`, case `miss-dog-101`). A
111798
111868
  * region longer than the ceiling is TILED along its longer axis, never zoomed
111799
111869
  * out.
111800
111870
  */
@@ -112820,7 +112890,7 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
112820
112890
  *
112821
112891
  * So `entry.providerAddonId === this.ctx.id` is silently, permanently false
112822
112892
  * for a builtin — and only for a builtin, which is why it survives a green
112823
- * suite whose fake supplies the bare id. That is exactly how camera 615's
112893
+ * suite whose fake supplies the bare id. That is exactly how camera 101's
112824
112894
  * virtual doorbell (retired since, D671) latched `unbound` for twelve hours on
112825
112895
  * 2026-08-07 while its binding was intact ([D72](../../../../docs/decisions/adr-0072.md)).
112826
112896
  *
@@ -114875,10 +114945,6 @@ exports.FEEDER_EXAMPLE_ADDON_ID = FEEDER_EXAMPLE_ADDON_ID;
114875
114945
  exports.FEEDER_EXAMPLE_HA_DEVICE_ID = FEEDER_EXAMPLE_HA_DEVICE_ID;
114876
114946
  exports.FFMPEG_PATH_ENV = require_composition.FFMPEG_PATH_ENV;
114877
114947
  exports.FIRST_LEVEL_MACRO_CLASSES = FIRST_LEVEL_MACRO_CLASSES;
114878
- exports.FRIGATE_PLUS_CLASS_FLOORS = FRIGATE_PLUS_CLASS_FLOORS;
114879
- exports.FRIGATE_PLUS_TO_MACRO = FRIGATE_PLUS_TO_MACRO;
114880
- exports.FRIGATE_PLUS_UNMAPPED_LABELS = FRIGATE_PLUS_UNMAPPED_LABELS;
114881
- exports.FRIGATE_STOCK_CLASS_FLOORS = FRIGATE_STOCK_CLASS_FLOORS;
114882
114948
  exports.FULL_IMAGE_BBOX = FULL_IMAGE_BBOX;
114883
114949
  exports.FailureContributionSchema = FailureContributionSchema;
114884
114950
  exports.FailureCounters = FailureCounters;
@@ -115519,6 +115585,10 @@ exports.PIPELINE_ANALYTICS_CAP_NAME = PIPELINE_ANALYTICS_CAP_NAME;
115519
115585
  exports.PIPELINE_FLOW_CAPABILITY_NAMES = PIPELINE_FLOW_CAPABILITY_NAMES;
115520
115586
  exports.PIPELINE_OWNER_CAPABILITY_NAMES = PIPELINE_OWNER_CAPABILITY_NAMES;
115521
115587
  exports.PIPELINE_RAMP = PIPELINE_RAMP;
115588
+ exports.PLUS_CATALOG_CLASS_FLOORS = PLUS_CATALOG_CLASS_FLOORS;
115589
+ exports.PLUS_CATALOG_STOCK_CLASS_FLOORS = PLUS_CATALOG_STOCK_CLASS_FLOORS;
115590
+ exports.PLUS_CATALOG_TO_MACRO = PLUS_CATALOG_TO_MACRO;
115591
+ exports.PLUS_CATALOG_UNMAPPED_LABELS = PLUS_CATALOG_UNMAPPED_LABELS;
115522
115592
  exports.PREFERENCES_MAX_DEVICE_ID_LENGTH = PREFERENCES_MAX_DEVICE_ID_LENGTH;
115523
115593
  exports.PREFERENCES_MAX_NAMESPACES = PREFERENCES_MAX_NAMESPACES;
115524
115594
  exports.PREFERENCES_MAX_VALUE_BYTES = PREFERENCES_MAX_VALUE_BYTES;
@@ -116266,10 +116336,10 @@ exports.buildDeviceEnrollmentLink = buildDeviceEnrollmentLink;
116266
116336
  exports.buildDeviceSignatureMessage = buildDeviceSignatureMessage;
116267
116337
  exports.buildEventKindDescriptor = buildEventKindDescriptor;
116268
116338
  exports.buildFfmpegArgs = require_composition.buildFfmpegArgs;
116269
- exports.buildFrigateClassMap = buildFrigateClassMap;
116270
116339
  exports.buildInputArgs = require_composition.buildInputArgs;
116271
116340
  exports.buildModelVariantGroups = buildModelVariantGroups;
116272
116341
  exports.buildNcTaxonomy = buildNcTaxonomy;
116342
+ exports.buildPlusCatalogClassMap = buildPlusCatalogClassMap;
116273
116343
  exports.buildRoleScopes = buildRoleScopes;
116274
116344
  exports.buildSecretRef = require_sleep.buildSecretRef;
116275
116345
  exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
@@ -116558,8 +116628,6 @@ exports.formatParkedFor = formatParkedFor;
116558
116628
  exports.formatSecretScope = require_sleep.formatSecretScope;
116559
116629
  exports.formulaProblem = formulaProblem;
116560
116630
  exports.freshResults = freshResults;
116561
- exports.frigateDefaultClassFloors = frigateDefaultClassFloors;
116562
- exports.frigateLabelFields = frigateLabelFields;
116563
116631
  exports.fuseRecoveredDetections = fuseRecoveredDetections;
116564
116632
  exports.gasCapability = gasCapability;
116565
116633
  exports.gbToBytes = gbToBytes;
@@ -116856,6 +116924,8 @@ exports.planMotionCrops = planMotionCrops;
116856
116924
  exports.planRecoveryCrops = planRecoveryCrops;
116857
116925
  exports.plateGalleryCapability = plateGalleryCapability;
116858
116926
  exports.platformProbeCapability = platformProbeCapability;
116927
+ exports.plusCatalogDefaultClassFloors = plusCatalogDefaultClassFloors;
116928
+ exports.plusCatalogLabelFields = plusCatalogLabelFields;
116859
116929
  exports.poolMemoryThreshold = poolMemoryThreshold;
116860
116930
  exports.powerMeterCapability = powerMeterCapability;
116861
116931
  exports.prepareNotification = prepareNotification;