@camstack/addon-pipeline 1.2.623 → 1.2.624

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 (35) hide show
  1. package/dist/audio-analyzer/index.js +3 -3
  2. package/dist/audio-analyzer/index.mjs +3 -3
  3. package/dist/{custom-model-catalog-BTBdgN2p.js → custom-model-catalog-6zwaRe6H.js} +2 -2
  4. package/dist/{custom-model-catalog-D5zTw1LU.mjs → custom-model-catalog-Dx6W1kAo.mjs} +2 -2
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-BVo3wa7s.js → dist-63VVVhpw.js} +735 -169
  8. package/dist/{dist-opSx6v5i.mjs → dist-BK3z-nti.mjs} +735 -169
  9. package/dist/{model-catalogs-rIvLUVlw.mjs → model-catalogs-CllYj2Q2.mjs} +1 -1
  10. package/dist/{model-catalogs-CQytR2AN.js → model-catalogs-DyOMg-xZ.js} +1 -1
  11. package/dist/motion-wasm/index.js +1 -1
  12. package/dist/motion-wasm/index.mjs +1 -1
  13. package/dist/{node-CGIYuJMN.mjs → node-BAcWHimZ.mjs} +2 -2
  14. package/dist/{node-DqLsuN_A.js → node-DdaBnHEq.js} +2 -2
  15. package/dist/pipeline-runner/index.js +3 -3
  16. package/dist/pipeline-runner/index.mjs +3 -3
  17. package/dist/{process-memory-DyxG-0mG.js → process-memory-CUlknrLl.js} +1 -1
  18. package/dist/{process-memory-Bd-TuWfM.mjs → process-memory-OZwib1pK.mjs} +1 -1
  19. package/dist/recorder/index.js +21 -2
  20. package/dist/recorder/index.mjs +21 -2
  21. package/dist/{segment-demux-js-CdVRzwSd.mjs → segment-demux-js-C3rhCLCG.mjs} +1 -1
  22. package/dist/{segment-demux-js-B4bfTQpK.js → segment-demux-js-WNlg0SXP.js} +1 -1
  23. package/dist/stream-broker/_stub.js +2 -2
  24. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DF3FGCR8.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Di7t7N3r.mjs} +2 -2
  25. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DDRGMoJ1.mjs +26 -0
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CPQe09h1.mjs +26 -0
  27. package/dist/stream-broker/demux-worker-child.js +1 -1
  28. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  29. package/dist/stream-broker/{hostInit-BiyFzSqq.mjs → hostInit-CMDvBrqv.mjs} +2 -2
  30. package/dist/stream-broker/index.js +4 -4
  31. package/dist/stream-broker/index.mjs +4 -4
  32. package/dist/stream-broker/remoteEntry.js +1 -1
  33. package/package.json +1 -1
  34. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-oUZNn2Kr.mjs +0 -26
  35. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bb-ETNGC.mjs +0 -26
@@ -1,5 +1,5 @@
1
1
  let node_crypto = require("node:crypto");
2
- //#region ../types/dist/event-category-fDPduoeC.mjs
2
+ //#region ../types/dist/event-category-Ceif8n-v.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -471,6 +471,10 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
471
471
  * on the device detail page.
472
472
  */
473
473
  EventCategory["DoorbellOnPressed"] = "doorbell.onPressed";
474
+ /** Mirrors `runningStateCapability.events.onStarted`. */
475
+ EventCategory["RunningStarted"] = "running.started";
476
+ /** Mirrors `runningStateCapability.events.onFinished`. */
477
+ EventCategory["RunningFinished"] = "running.finished";
474
478
  /**
475
479
  * Cap event fired by every device that registers the `event-emitter`
476
480
  * capability. Mirrors `eventEmitterCapability.events.onEvent`. Carries
@@ -5563,7 +5567,7 @@ var ZodIssueCode = {
5563
5567
  var ZodFirstPartyTypeKind;
5564
5568
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5565
5569
  //#endregion
5566
- //#region ../types/dist/sleep-CHIEEJkY.mjs
5570
+ //#region ../types/dist/sleep-CYfIZzGv.mjs
5567
5571
  /**
5568
5572
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5569
5573
  * window to float samples (D455).
@@ -5934,7 +5938,7 @@ Object.fromEntries([
5934
5938
  * `hydrateSchema` to skip the `value` injection for structural-only fields.
5935
5939
  */
5936
5940
  function isValuelessField(field) {
5937
- return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button";
5941
+ return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button" || field.type === "account-sign-in" || field.type === "secret-presence";
5938
5942
  }
5939
5943
  function hydrateSchema(schema, values, options = {}) {
5940
5944
  return {
@@ -9435,7 +9439,7 @@ function errMsg(err) {
9435
9439
  return String(err);
9436
9440
  }
9437
9441
  //#endregion
9438
- //#region ../types/dist/composition-CB6PMT9p.mjs
9442
+ //#region ../types/dist/composition-BJ8iAZb3.mjs
9439
9443
  var AUDIO_ENCODER_BY_CODEC = {
9440
9444
  opus: "libopus",
9441
9445
  aac: "aac",
@@ -10202,7 +10206,7 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
10202
10206
  * ONE table for everyone who asks "is this device HIGH?": the
10203
10207
  * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
10204
10208
  * sensor markers, the orchestrator's camera-sensors bridge and
10205
- * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
10209
+ * the sources of a pulse (`compilePulseOverride`, D936).
10206
10210
  * A second copy would diverge at the first cap added, and the symptom — "the
10207
10211
  * sensor rings the doorbell but does not record" — is exactly D62.
10208
10212
  *
@@ -10572,6 +10576,20 @@ var table = {
10572
10576
  apply: () => {
10573
10577
  throw new ExpressionEvalError("count: stateful evaluation context is required");
10574
10578
  }
10579
+ },
10580
+ dwell: {
10581
+ minArgs: 3,
10582
+ maxArgs: 3,
10583
+ apply: () => {
10584
+ throw new ExpressionEvalError("dwell: stateful evaluation context is required");
10585
+ }
10586
+ },
10587
+ latchedAt: {
10588
+ minArgs: 1,
10589
+ maxArgs: 1,
10590
+ apply: () => {
10591
+ throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
10592
+ }
10575
10593
  }
10576
10594
  };
10577
10595
  Object.freeze(Object.assign(Object.create(null), table));
@@ -19179,6 +19197,13 @@ var ComposerUnreadableBlockSchema = object({
19179
19197
  /** The parse error, in the operator's words. */
19180
19198
  error: string()
19181
19199
  });
19200
+ /** A confirmed release the hub did not accept. `deviceId` is the claim's device. */
19201
+ var UnreleasedClaimSchema = object({
19202
+ deviceId: number().int(),
19203
+ capName: string(),
19204
+ owner: string(),
19205
+ error: string()
19206
+ });
19182
19207
  method(object({
19183
19208
  /** The shared Blocks integration; null until `core-blocks` has reconciled it. */
19184
19209
  integrationId: string().nullable(),
@@ -19188,7 +19213,13 @@ method(object({
19188
19213
  /** Operator restarts: rebuild these runtimes and re-resolve their sources. Stores nothing (D62). */
19189
19214
  restartBlockIds: array(string()),
19190
19215
  /** Composition rows that exist but do not parse: held, never withdrawn, reported failed. */
19191
- unreadableBlocks: array(ComposerUnreadableBlockSchema)
19216
+ unreadableBlocks: array(ComposerUnreadableBlockSchema),
19217
+ /**
19218
+ * Operator-confirmed deletions. Their claims are released on this apply,
19219
+ * before any replacement block claims. A block that merely vanished from the
19220
+ * snapshot is not listed here and still waits for two applies (D49).
19221
+ */
19222
+ retiredBlockIds: array(string()).optional()
19192
19223
  }), object({
19193
19224
  blocks: array(object({
19194
19225
  blockId: string(),
@@ -19200,7 +19231,13 @@ method(object({
19200
19231
  * integration unknown, its own rows unread or read empty once). An empty
19201
19232
  * apply the caller owes is paid off only by one the composer acted on (D49).
19202
19233
  */
19203
- acted: boolean()
19234
+ acted: boolean(),
19235
+ /**
19236
+ * Confirmed releases this apply tried and the hub did not accept. Empty when
19237
+ * every one landed (or there was nothing to hand back). Absent on a result
19238
+ * that never got that far.
19239
+ */
19240
+ unreleasedClaims: array(UnreleasedClaimSchema).optional()
19204
19241
  }), {
19205
19242
  kind: "mutation",
19206
19243
  auth: "admin"
@@ -19243,7 +19280,15 @@ Object.freeze({
19243
19280
  kind: "fixed",
19244
19281
  result: ["number", "null"]
19245
19282
  },
19246
- count: NUMBER
19283
+ count: NUMBER,
19284
+ dwell: {
19285
+ kind: "fixed",
19286
+ result: ["boolean", "null"]
19287
+ },
19288
+ latchedAt: {
19289
+ kind: "fixed",
19290
+ result: ["number", "null"]
19291
+ }
19247
19292
  });
19248
19293
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
19249
19294
  /**
@@ -45500,6 +45545,381 @@ function mapAudioLabelToMacro(label) {
45500
45545
  return _macroLookup.get(label.toLowerCase()) ?? null;
45501
45546
  }
45502
45547
  /**
45548
+ * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
45549
+ * not entries. `heatmapScrub` is a mark, not an event kind.
45550
+ */
45551
+ var PALETTE_ENTRY_IDS = [
45552
+ "motion",
45553
+ "audio",
45554
+ "recording",
45555
+ "live",
45556
+ "heatmapScrub",
45557
+ "person",
45558
+ "vehicle",
45559
+ "animal",
45560
+ "package",
45561
+ "sensor",
45562
+ "control",
45563
+ "face",
45564
+ "plate",
45565
+ "car",
45566
+ "truck",
45567
+ "bus",
45568
+ "motorcycle",
45569
+ "bicycle",
45570
+ "airplane",
45571
+ "boat",
45572
+ "train",
45573
+ "bird",
45574
+ "dog",
45575
+ "cat",
45576
+ "horse",
45577
+ "sheep",
45578
+ "cow",
45579
+ "elephant",
45580
+ "bear",
45581
+ "zebra",
45582
+ "giraffe",
45583
+ "package-delivered",
45584
+ "package-picked-up",
45585
+ "suitcase",
45586
+ "backpack",
45587
+ "handbag",
45588
+ "contact",
45589
+ "motion-sensor",
45590
+ "smoke",
45591
+ "flood",
45592
+ "gas",
45593
+ "carbon-monoxide",
45594
+ "vibration",
45595
+ "tamper",
45596
+ "presence",
45597
+ "enum-sensor",
45598
+ "device-event",
45599
+ "lock",
45600
+ "cover",
45601
+ "switch",
45602
+ "siren",
45603
+ "button",
45604
+ "doorbell"
45605
+ ];
45606
+ var AUDIO_ENTRY_ID = "audio";
45607
+ /** Six rungs, quiet → loud. The opaque end is the entry's hex. */
45608
+ var AUDIO_GRADIENT_ALPHAS = [
45609
+ .3,
45610
+ .42,
45611
+ .55,
45612
+ .7,
45613
+ .85,
45614
+ 1
45615
+ ];
45616
+ var PALETTE_PRESET_IDS = [
45617
+ "camstack",
45618
+ "high-contrast",
45619
+ "okabe-ito"
45620
+ ];
45621
+ /** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
45622
+ var CAMSTACK_HEX = {
45623
+ motion: "#d946ef",
45624
+ audio: "#059eb8",
45625
+ recording: "#ef4444",
45626
+ live: "#8d7a00",
45627
+ heatmapScrub: "#4b32ff",
45628
+ person: "#11a64c",
45629
+ vehicle: "#3b82f6",
45630
+ animal: "#ea6a09",
45631
+ package: "#924667",
45632
+ sensor: "#624bbc",
45633
+ control: "#944d24",
45634
+ face: "#ed4f8d",
45635
+ plate: "#4b7027",
45636
+ car: "#9684cf",
45637
+ truck: "#0f9b89",
45638
+ bus: "#a734a9",
45639
+ motorcycle: "#c1133a",
45640
+ bicycle: "#0e6a9b",
45641
+ airplane: "#7c9928",
45642
+ boat: "#b17933",
45643
+ train: "#ad6ca3",
45644
+ bird: "#0f7c55",
45645
+ dog: "#c82700",
45646
+ cat: "#7268f2",
45647
+ horse: "#cb795e",
45648
+ sheep: "#b8636b",
45649
+ cow: "#cb2969",
45650
+ elephant: "#1158d2",
45651
+ bear: "#8d5e00",
45652
+ zebra: "#0097d6",
45653
+ giraffe: "#8f61bb",
45654
+ "package-delivered": "#cd3f9b",
45655
+ "package-picked-up": "#388a08",
45656
+ suitcase: "#666800",
45657
+ backpack: "#ec5022",
45658
+ handbag: "#a76ef8",
45659
+ contact: "#ab5a49",
45660
+ "motion-sensor": "#b95d1a",
45661
+ smoke: "#dd3858",
45662
+ flood: "#b31e7d",
45663
+ gas: "#5b70b5",
45664
+ "carbon-monoxide": "#7b4e8e",
45665
+ vibration: "#e65bba",
45666
+ tamper: "#98464b",
45667
+ presence: "#3a9468",
45668
+ "enum-sensor": "#7885f8",
45669
+ "device-event": "#8c43c8",
45670
+ lock: "#649653",
45671
+ cover: "#c67597",
45672
+ switch: "#7a812a",
45673
+ siren: "#ac5d7f",
45674
+ button: "#b276cd",
45675
+ doorbell: "#0087ab"
45676
+ };
45677
+ var CAMSTACK_FALLBACK = [
45678
+ "#b34dc7",
45679
+ "#1d7d34",
45680
+ "#db6b6c",
45681
+ "#a43d29",
45682
+ "#0e6ee6",
45683
+ "#29a10b",
45684
+ "#a98731",
45685
+ "#0181c6"
45686
+ ];
45687
+ var HIGH_CONTRAST_HEX = {
45688
+ motion: "#964360",
45689
+ audio: "#23a132",
45690
+ recording: "#2494ca",
45691
+ live: "#bd7e2b",
45692
+ heatmapScrub: "#ad6eea",
45693
+ person: "#62611e",
45694
+ vehicle: "#f4534c",
45695
+ animal: "#1556cd",
45696
+ package: "#9c4415",
45697
+ sensor: "#066c48",
45698
+ control: "#f2479f",
45699
+ face: "#139d8a",
45700
+ plate: "#909024",
45701
+ car: "#8e35ab",
45702
+ truck: "#bd0b2b",
45703
+ bus: "#7a88ca",
45704
+ motorcycle: "#e26725",
45705
+ bicycle: "#a6679b",
45706
+ airplane: "#7c5720",
45707
+ boat: "#467a1b",
45708
+ train: "#6f65a4",
45709
+ bird: "#cb717f",
45710
+ dog: "#c62490",
45711
+ cat: "#b36850",
45712
+ horse: "#1872ac",
45713
+ sheep: "#927939",
45714
+ cow: "#428a5c",
45715
+ elephant: "#d41160",
45716
+ bear: "#799453",
45717
+ zebra: "#a85455",
45718
+ giraffe: "#746be8",
45719
+ "package-delivered": "#824a80",
45720
+ "package-picked-up": "#614ac1",
45721
+ suitcase: "#2f77f3",
45722
+ backpack: "#fa476d",
45723
+ handbag: "#c14cbe",
45724
+ contact: "#c83921",
45725
+ "motion-sensor": "#a07ebd",
45726
+ smoke: "#a25b13",
45727
+ flood: "#526bab",
45728
+ gas: "#924938",
45729
+ "carbon-monoxide": "#bb7e53",
45730
+ vibration: "#b66182",
45731
+ tamper: "#3c6931",
45732
+ presence: "#6c851d",
45733
+ "enum-sensor": "#ad2d48",
45734
+ "device-event": "#5e9b04",
45735
+ lock: "#00a062",
45736
+ cover: "#ad8624",
45737
+ switch: "#d05259",
45738
+ siren: "#cd67b3",
45739
+ button: "#c9746a",
45740
+ doorbell: "#338eeb"
45741
+ };
45742
+ var HIGH_CONTRAST_FALLBACK = [
45743
+ "#817f3b",
45744
+ "#a0733e",
45745
+ "#8658b2",
45746
+ "#956301",
45747
+ "#bc652d",
45748
+ "#647331",
45749
+ "#a14c9e",
45750
+ "#d14e71"
45751
+ ];
45752
+ var OKABE_ITO_HEX = {
45753
+ motion: "#b88128",
45754
+ audio: "#1096c8",
45755
+ recording: "#009e73",
45756
+ live: "#9c8c22",
45757
+ heatmapScrub: "#0072b2",
45758
+ person: "#d55e00",
45759
+ vehicle: "#c0739f",
45760
+ animal: "#226d18",
45761
+ package: "#91446c",
45762
+ sensor: "#217b56",
45763
+ control: "#648647",
45764
+ face: "#c22998",
45765
+ plate: "#fa4575",
45766
+ car: "#956301",
45767
+ truck: "#2f77f3",
45768
+ bus: "#7a4e86",
45769
+ motorcycle: "#f54597",
45770
+ bicycle: "#bb3e75",
45771
+ airplane: "#e054c0",
45772
+ boat: "#457942",
45773
+ train: "#867afa",
45774
+ bird: "#88914c",
45775
+ dog: "#1556cd",
45776
+ cat: "#71702c",
45777
+ horse: "#9b4fa4",
45778
+ sheep: "#c0559d",
45779
+ cow: "#d14f65",
45780
+ elephant: "#98470f",
45781
+ bear: "#595896",
45782
+ zebra: "#96790e",
45783
+ giraffe: "#cb717b",
45784
+ "package-delivered": "#139d8a",
45785
+ "package-picked-up": "#906ead",
45786
+ suitcase: "#d02939",
45787
+ backpack: "#d41160",
45788
+ handbag: "#f64f54",
45789
+ contact: "#7258d2",
45790
+ "motion-sensor": "#b66182",
45791
+ smoke: "#627abb",
45792
+ flood: "#b86ae4",
45793
+ gas: "#a95261",
45794
+ "carbon-monoxide": "#c65d3c",
45795
+ vibration: "#7a40b7",
45796
+ tamper: "#914b34",
45797
+ presence: "#9481c3",
45798
+ "enum-sensor": "#ac6d47",
45799
+ "device-event": "#7b6fce",
45800
+ lock: "#c67662",
45801
+ cover: "#a6564d",
45802
+ switch: "#ad2c4e",
45803
+ siren: "#348e08",
45804
+ button: "#d27303",
45805
+ doorbell: "#55770f"
45806
+ };
45807
+ var OKABE_ITO_FALLBACK = [
45808
+ "#9a3784",
45809
+ "#a7392c",
45810
+ "#409d50",
45811
+ "#6987e7",
45812
+ "#ee5b3d",
45813
+ "#c0430d",
45814
+ "#af79b3",
45815
+ "#4b6628"
45816
+ ];
45817
+ /**
45818
+ * The display palette (D939). One table of colours, three presets, one
45819
+ * validator. Taxonomy colours and every consumer read this — there is no
45820
+ * second hex table.
45821
+ */
45822
+ var paletteHexSchema = string().regex(/^#[0-9a-f]{6}$/);
45823
+ var paletteSwatchSchema = discriminatedUnion("form", [object({
45824
+ form: literal("solid"),
45825
+ hex: paletteHexSchema
45826
+ }), object({
45827
+ form: literal("gradient"),
45828
+ hex: paletteHexSchema,
45829
+ alphas: array(number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
45830
+ })]);
45831
+ var paletteReadySchema = object({
45832
+ status: literal("ready"),
45833
+ presetId: _enum(PALETTE_PRESET_IDS),
45834
+ customized: boolean(),
45835
+ source: _enum(["stored", "unconfigured"]),
45836
+ swatches: record(string(), paletteSwatchSchema),
45837
+ fallbacks: array(paletteHexSchema).length(8)
45838
+ });
45839
+ var paletteResultSchema = discriminatedUnion("status", [paletteReadySchema, object({
45840
+ status: literal("unknown"),
45841
+ reason: string()
45842
+ })]);
45843
+ var setPaletteInputSchema = union$1([object({ presetId: string() }), object({
45844
+ presetId: string(),
45845
+ overrides: record(string(), paletteSwatchSchema)
45846
+ })]);
45847
+ object({
45848
+ presetId: string(),
45849
+ overrides: record(string(), paletteSwatchSchema)
45850
+ });
45851
+ function solid(hex) {
45852
+ return {
45853
+ form: "solid",
45854
+ hex
45855
+ };
45856
+ }
45857
+ function audioGradient(hex) {
45858
+ return {
45859
+ form: "gradient",
45860
+ hex,
45861
+ alphas: [...AUDIO_GRADIENT_ALPHAS]
45862
+ };
45863
+ }
45864
+ function swatchesFrom(hexes) {
45865
+ const out = {};
45866
+ for (const id of PALETTE_ENTRY_IDS) {
45867
+ const hex = hexes[id];
45868
+ if (hex === void 0) throw new Error(`palette table missing ${id}`);
45869
+ out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
45870
+ }
45871
+ return out;
45872
+ }
45873
+ function preset(id, name, hexes, fallbacks) {
45874
+ return {
45875
+ id,
45876
+ name,
45877
+ swatches: swatchesFrom(hexes),
45878
+ fallbacks
45879
+ };
45880
+ }
45881
+ var DISPLAY_PRESETS = [
45882
+ preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
45883
+ preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
45884
+ preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
45885
+ ];
45886
+ function presetById(id) {
45887
+ return DISPLAY_PRESETS.find((item) => item.id === id);
45888
+ }
45889
+ function bundledCamstack() {
45890
+ const presetRow = presetById("camstack");
45891
+ if (presetRow === void 0) throw new Error("CamStack preset missing");
45892
+ return readyOf(presetRow, "unconfigured", false);
45893
+ }
45894
+ function readyOf(row, source, customized) {
45895
+ return {
45896
+ status: "ready",
45897
+ presetId: row.id,
45898
+ customized,
45899
+ source,
45900
+ swatches: row.swatches,
45901
+ fallbacks: [...row.fallbacks]
45902
+ };
45903
+ }
45904
+ function hashFallback(kind, fallbacks) {
45905
+ let hash = 0;
45906
+ for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
45907
+ const hex = fallbacks[hash % fallbacks.length];
45908
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
45909
+ return hex;
45910
+ }
45911
+ /** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
45912
+ function paintHex(swatches, fallbacks, kind) {
45913
+ const key = kind.trim().toLowerCase();
45914
+ if (key.startsWith("audio-")) {
45915
+ const audio = swatches[AUDIO_ENTRY_ID];
45916
+ return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
45917
+ }
45918
+ const direct = swatches[key];
45919
+ if (direct !== void 0) return direct.hex;
45920
+ return hashFallback(key, fallbacks);
45921
+ }
45922
+ /**
45503
45923
  * Unified event-kind taxonomy — THE single source of truth for
45504
45924
  * `kind → { parentKind, category, level, color, iconId, labelKey, label,
45505
45925
  * icon }`.
@@ -45513,109 +45933,88 @@ function mapAudioLabelToMacro(label) {
45513
45933
  * - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
45514
45934
  * - the COCO / audio class maps (macro ↔ sub relationships)
45515
45935
  *
45516
- * The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
45517
- * `@camstack/types`. The UI-side mapping `iconId → lucide component` and
45518
- * `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
45519
- * color or an icon: they read this dictionary (server descriptors carry the
45520
- * fields inline; the client resolves color/icon/label from `iconId`/`kind`).
45936
+ * The DATA (serializable — parentKind / iconId / labelKey) lives here in
45937
+ * `@camstack/types`. Colour is NOT a second table: each entry's `color` is
45938
+ * the bundled CamStack display palette (D939). The effective cluster palette
45939
+ * is the `display-palette` capability. The UI-side mapping `iconId → lucide
45940
+ * component` and `labelKey → t()` lives in `@camstack/ui-library`.
45521
45941
  *
45522
45942
  * Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
45523
45943
  */
45524
- var TAXONOMY_COLORS = {
45525
- motion: "#f59e0b",
45526
- audio: "#06b6d4",
45527
- person: "#22c55e",
45528
- vehicle: "#3b82f6",
45529
- animal: "#f97316",
45530
- package: "#a855f7",
45531
- sensor: "#8b5cf6",
45532
- control: "#10b981",
45533
- genericDetection: "#64748b"
45534
- };
45535
- var DETECTION_SUB_COLORS = {
45536
- car: "#f59e0b",
45537
- truck: "#d97706",
45538
- bus: "#b45309",
45539
- motorcycle: "#eab308",
45540
- bicycle: "#ca8a04",
45541
- airplane: "#60a5fa",
45542
- boat: "#2563eb",
45543
- train: "#1d4ed8",
45544
- bird: "#14b8a6",
45545
- dog: "#84cc16",
45546
- cat: "#f97316",
45547
- horse: "#a16207",
45548
- sheep: "#a3a3a3",
45549
- cow: "#78716c",
45550
- elephant: "#6b7280",
45551
- bear: "#7c2d12",
45552
- zebra: "#404040",
45553
- giraffe: "#d4a373"
45554
- };
45944
+ var BUNDLED_PALETTE = bundledCamstack();
45945
+ function kindColor(kind) {
45946
+ return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
45947
+ }
45948
+ function firstFallback(fallbacks) {
45949
+ const hex = fallbacks[0];
45950
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
45951
+ return hex;
45952
+ }
45953
+ firstFallback(BUNDLED_PALETTE.fallbacks);
45555
45954
  function titleCase(id) {
45556
45955
  return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
45557
45956
  }
45558
45957
  var entries = /* @__PURE__ */ new Map();
45559
- function macro(kind, category, color, iconId, label) {
45958
+ function macro(kind, category, iconId, label) {
45560
45959
  entries.set(kind, {
45561
45960
  kind,
45562
45961
  parentKind: null,
45563
45962
  level: "macro",
45564
45963
  category,
45565
- color,
45964
+ color: kindColor(kind),
45566
45965
  iconId,
45567
45966
  labelKey: `eventKind.${kind}`,
45568
45967
  label
45569
45968
  });
45570
45969
  }
45571
- function sub(kind, parentKind, category, color, iconId, label) {
45970
+ function sub(kind, parentKind, category, iconId, label) {
45572
45971
  entries.set(kind, {
45573
45972
  kind,
45574
45973
  parentKind,
45575
45974
  level: "sub",
45576
45975
  category,
45577
- color,
45976
+ color: kindColor(kind),
45578
45977
  iconId,
45579
45978
  labelKey: `eventKind.${kind}`,
45580
45979
  label
45581
45980
  });
45582
45981
  }
45583
- macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
45584
- macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
45585
- macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
45586
- macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
45587
- macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
45588
- macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
45589
- macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
45590
- macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
45982
+ macro("motion", "motion", "motion", "Motion");
45983
+ macro("audio", "audio", "audio", "Audio");
45984
+ macro("person", "detection", "person", "Person");
45985
+ macro("vehicle", "detection", "vehicle", "Vehicle");
45986
+ macro("animal", "detection", "animal", "Animal");
45987
+ macro("package", "package", "package", "Package");
45988
+ macro("sensor", "sensor", "sensor", "Sensor");
45989
+ macro("control", "control", "control", "Control");
45591
45990
  for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
45592
45991
  if (macroClass !== "vehicle" && macroClass !== "animal") continue;
45593
45992
  if (entries.has(cocoClass)) continue;
45594
- sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
45993
+ sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
45595
45994
  }
45596
- sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
45597
- sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
45598
- sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
45599
- sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
45600
- sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
45601
- sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
45602
- sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
45603
- sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
45604
- sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
45605
- sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
45606
- sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
45607
- sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
45608
- sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
45609
- sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
45610
- sub("cover", "control", "control", "#0ea5e9", "door", "Cover");
45611
- sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
45612
- sub("siren", "control", "control", "#dc2626", "siren", "Siren");
45613
- sub("button", "control", "control", "#10b981", "button", "Button");
45614
- sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
45995
+ sub("package-delivered", "package", "package", "package", "Package delivered");
45996
+ sub("package-picked-up", "package", "package", "package", "Package picked up");
45997
+ sub("contact", "sensor", "sensor", "door", "Contact");
45998
+ sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
45999
+ sub("smoke", "sensor", "sensor", "smoke", "Smoke");
46000
+ sub("flood", "sensor", "sensor", "water", "Water leak");
46001
+ sub("gas", "sensor", "sensor", "gas", "Gas");
46002
+ sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
46003
+ sub("vibration", "sensor", "sensor", "vibration", "Vibration");
46004
+ sub("tamper", "sensor", "sensor", "tamper", "Tamper");
46005
+ sub("presence", "sensor", "sensor", "presence", "Presence");
46006
+ sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
46007
+ sub("device-event", "sensor", "sensor", "button", "Device event");
46008
+ sub("lock", "control", "control", "lock", "Lock");
46009
+ sub("cover", "control", "control", "door", "Cover");
46010
+ sub("switch", "control", "control", "switch", "Switch");
46011
+ sub("siren", "control", "control", "siren", "Siren");
46012
+ sub("button", "control", "control", "button", "Button");
46013
+ sub("doorbell", "control", "control", "doorbell", "Doorbell");
45615
46014
  for (const l of AUDIO_MACRO_LABELS) {
45616
46015
  const kind = `audio-${l.id}`;
45617
46016
  if (entries.has(kind)) continue;
45618
- sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
46017
+ sub(kind, "audio", "audio", kind, l.name);
45619
46018
  }
45620
46019
  /** The complete taxonomy dictionary, keyed by kind. */
45621
46020
  var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
@@ -45882,9 +46281,6 @@ var NcSystemEventKindSchema = _enum([
45882
46281
  "device-battery-normal",
45883
46282
  "device-consumable-low",
45884
46283
  "device-consumable-normal",
45885
- "device-tank-low",
45886
- "device-tank-full",
45887
- "device-tank-normal",
45888
46284
  "stream-online",
45889
46285
  "stream-offline",
45890
46286
  "node-online",
@@ -45931,13 +46327,14 @@ var NcSystemEventKindSchema = _enum([
45931
46327
  "camera-enabled"
45932
46328
  ]);
45933
46329
  /** The legacy tail of {@link NcSystemEventKindSchema} — see its docblock. */
45934
- var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
46330
+ var NC_LEGACY_SYSTEM_EVENT_KINDS = [
45935
46331
  "camera-online",
45936
46332
  "camera-offline",
45937
46333
  "camera-disabled",
45938
46334
  "camera-enabled"
45939
- ]);
45940
- NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
46335
+ ];
46336
+ var NC_LEGACY_SYSTEM_EVENT_KIND_SET = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
46337
+ NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KIND_SET.has(kind));
45941
46338
  /**
45942
46339
  * The panel's transitions, as ONE list.
45943
46340
  *
@@ -47056,18 +47453,11 @@ var NcRuleSchema = NcRuleInputSchema.extend({
47056
47453
  */
47057
47454
  disabledTargetIds: array(string()).default([])
47058
47455
  });
47059
- /**
47060
- * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
47061
- * report a still-true state. `addons` is the crash-looped addons only and
47062
- * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
47063
- * job is not an open state, and the alarm stays instant.
47064
- */
47065
47456
  var NcStateSummarySectionIdSchema = _enum([
47066
47457
  "device-state",
47067
47458
  "streams",
47068
47459
  "battery",
47069
47460
  "consumables",
47070
- "tanks",
47071
47461
  "detection-blind",
47072
47462
  "nodes",
47073
47463
  "addons",
@@ -58271,20 +58661,68 @@ var BatteryStatusSchema = object({
58271
58661
  */
58272
58662
  binary: boolean().optional()
58273
58663
  });
58664
+ var BATTERY_DEVICE_TYPES = [
58665
+ DeviceType.Camera,
58666
+ DeviceType.Sensor,
58667
+ DeviceType.Button,
58668
+ DeviceType.Switch,
58669
+ DeviceType.PetFeeder,
58670
+ DeviceType.Container,
58671
+ DeviceType.Thermostat
58672
+ ];
58673
+ /** Generic Customize target for the percentage reading (D936). */
58674
+ var batteryCustomize = {
58675
+ version: 1,
58676
+ targets: [{
58677
+ id: "percentage",
58678
+ cardinality: "scalar",
58679
+ vocabulary: {
58680
+ cap: "battery",
58681
+ stateField: "percentage"
58682
+ },
58683
+ deviceTypes: BATTERY_DEVICE_TYPES,
58684
+ apply: "add-or-replace",
58685
+ path: "percentage",
58686
+ sources: [{
58687
+ kind: "field",
58688
+ valueKinds: ["number", "string"],
58689
+ transforms: [{ kind: "identity" }, {
58690
+ kind: "linear",
58691
+ defaultScale: 1,
58692
+ defaultOffset: 0,
58693
+ clampMin: 0,
58694
+ clampMax: 100
58695
+ }]
58696
+ }],
58697
+ companions: [
58698
+ {
58699
+ kind: "constant",
58700
+ path: "charging",
58701
+ value: "unknown",
58702
+ when: "add"
58703
+ },
58704
+ {
58705
+ kind: "constant",
58706
+ path: "sleeping",
58707
+ value: false,
58708
+ when: "add"
58709
+ },
58710
+ {
58711
+ kind: "clock",
58712
+ path: "lastUpdated",
58713
+ when: "add"
58714
+ }
58715
+ ],
58716
+ sourceReport: { status: "assignment-status" },
58717
+ advancedExpression: true
58718
+ }]
58719
+ };
58274
58720
  var batteryCapability = {
58275
58721
  name: "battery",
58276
58722
  scope: "device",
58277
58723
  deviceNative: true,
58278
58724
  mode: "singleton",
58279
- deviceTypes: [
58280
- DeviceType.Camera,
58281
- DeviceType.Sensor,
58282
- DeviceType.Button,
58283
- DeviceType.Switch,
58284
- DeviceType.PetFeeder,
58285
- DeviceType.Container,
58286
- DeviceType.Thermostat
58287
- ],
58725
+ deviceTypes: BATTERY_DEVICE_TYPES,
58288
58726
  methods: {
58289
58727
  /**
58290
58728
  * Explicitly wake the camera from low-power sleep ahead of a
@@ -58368,6 +58806,7 @@ onStatusChanged: { data: object({
58368
58806
  kind: "gauge",
58369
58807
  unit: "%"
58370
58808
  } } },
58809
+ customize: batteryCustomize,
58371
58810
  /** Clock fields: written, but excluded from the compare that decides
58372
58811
  * whether persisting is worth a SQLite commit. */
58373
58812
  volatileStateFields: ["lastUpdated"]
@@ -59070,6 +59509,7 @@ var ConsumablesStatusSchema = object({
59070
59509
  })),
59071
59510
  lastChangedAt: number()
59072
59511
  });
59512
+ Object.values(DeviceType), [...ConsumableRemainingUnitSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
59073
59513
  Object.values(DeviceType), method(object({
59074
59514
  deviceId: number().int().nonnegative(),
59075
59515
  key: string().min(1)
@@ -59262,6 +59702,30 @@ DeviceType.Camera, method(object({ deviceId: number() }), DayNightOptionsSchema)
59262
59702
  auth: "admin"
59263
59703
  });
59264
59704
  /**
59705
+ * display-palette — the cluster's one colour table (D939).
59706
+ *
59707
+ * Hub singleton. `getPalette` reports `unknown` when the settings store
59708
+ * cannot be read; it does not pretend the bundled preset was stored.
59709
+ * `setPalette` refuses a palette that fails the ΔE / contrast rule and names
59710
+ * the pairs.
59711
+ */
59712
+ var presetSummarySchema = object({
59713
+ id: string(),
59714
+ name: string(),
59715
+ swatches: record(string(), paletteSwatchSchema),
59716
+ fallbacks: array(string())
59717
+ });
59718
+ method(_void(), paletteResultSchema, {
59719
+ auth: "protected",
59720
+ role: "viewer"
59721
+ }), method(_void(), array(presetSummarySchema).readonly(), {
59722
+ auth: "protected",
59723
+ role: "viewer"
59724
+ }), method(setPaletteInputSchema, paletteReadySchema, {
59725
+ kind: "mutation",
59726
+ auth: "admin"
59727
+ });
59728
+ /**
59265
59729
  * Generic device-level status snapshot. Auto-registered by `BaseDevice`
59266
59730
  * for every device, regardless of provider — the kernel needs a uniform
59267
59731
  * cap-keyed slice for the basic device flags every consumer expects to
@@ -59541,6 +60005,7 @@ DeviceType.Dishwasher, method(object({
59541
60005
  kind: "mutation",
59542
60006
  auth: "protected"
59543
60007
  }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
60008
+ DeviceType.Camera;
59544
60009
  object({
59545
60010
  /** Ms epoch of the last press. null = never observed since this provider started. */
59546
60011
  lastPressedAt: number().nullable(),
@@ -61333,6 +61798,7 @@ authKey: string().optional() }), object({
61333
61798
  /** Human-readable error when `ok: false`. */
61334
61799
  error: string().optional()
61335
61800
  }), { kind: "mutation" });
61801
+ DeviceType.Camera;
61336
61802
  object({
61337
61803
  detected: boolean(),
61338
61804
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -63396,6 +63862,24 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
63396
63862
  deviceId: number(),
63397
63863
  status: PtzAutotrackStatusSchema
63398
63864
  });
63865
+ var RunningStateSourceSchema = _enum(["native", "assigned"]);
63866
+ object({
63867
+ /** null = unknown — never coerced to false (D393). */
63868
+ running: boolean().nullable(),
63869
+ /** Epoch ms the current boolean began; null while `running` is null. */
63870
+ since: number().nullable(),
63871
+ source: RunningStateSourceSchema,
63872
+ phase: string().nullable(),
63873
+ /** null until a reading has been published (D393). */
63874
+ lastFetchedAt: number().nullable()
63875
+ });
63876
+ object({
63877
+ deviceId: number(),
63878
+ since: number().nullable(),
63879
+ phase: string().nullable()
63880
+ });
63881
+ Object.values(DeviceType);
63882
+ DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
63399
63883
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
63400
63884
  kind: "mutation",
63401
63885
  auth: "admin"
@@ -70722,6 +71206,27 @@ Object.freeze({
70722
71206
  access: "create",
70723
71207
  role: "viewer"
70724
71208
  },
71209
+ "displayPalette.getPalette": {
71210
+ capName: "display-palette",
71211
+ capScope: "system",
71212
+ addonId: null,
71213
+ access: "view",
71214
+ role: "viewer"
71215
+ },
71216
+ "displayPalette.listPresets": {
71217
+ capName: "display-palette",
71218
+ capScope: "system",
71219
+ addonId: null,
71220
+ access: "view",
71221
+ role: "viewer"
71222
+ },
71223
+ "displayPalette.setPalette": {
71224
+ capName: "display-palette",
71225
+ capScope: "system",
71226
+ addonId: null,
71227
+ access: "create",
71228
+ role: "admin"
71229
+ },
70725
71230
  "doorbell.getStatus": {
70726
71231
  capName: "doorbell",
70727
71232
  capScope: "device",
@@ -75272,6 +75777,13 @@ Object.freeze({
75272
75777
  access: "create",
75273
75778
  role: "admin"
75274
75779
  },
75780
+ "runningState.getStatus": {
75781
+ capName: "running-state",
75782
+ capScope: "device",
75783
+ addonId: null,
75784
+ access: "view",
75785
+ role: "viewer"
75786
+ },
75275
75787
  "sceneMonitor.captureReference": {
75276
75788
  capName: "scene-monitor",
75277
75789
  capScope: "device",
@@ -79986,6 +80498,32 @@ var APPLIANCE_CAP_VOCABULARY = {
79986
80498
  }],
79987
80499
  events: { onSent: { notOperatorFacing: "a delivery receipt of a send this system made — not a fact about the world" } }
79988
80500
  },
80501
+ "running-state": {
80502
+ scope: "device",
80503
+ noun: t("Running", "In funzione"),
80504
+ state: [{
80505
+ kind: "boolean",
80506
+ field: "running",
80507
+ label: t("Running", "In funzione"),
80508
+ whenTrue: t("When {device} starts", "Quando {device} inizia"),
80509
+ whenFalse: t("When {device} finishes", "Quando {device} finisce"),
80510
+ icon: "play"
80511
+ }],
80512
+ events: {
80513
+ onStarted: {
80514
+ category: EventCategory.RunningStarted,
80515
+ label: t("Started running", "Ha iniziato a funzionare"),
80516
+ phrase: t("When {device} starts running", "Quando {device} inizia a funzionare"),
80517
+ icon: "play"
80518
+ },
80519
+ onFinished: {
80520
+ category: EventCategory.RunningFinished,
80521
+ label: t("Finished", "Ha finito"),
80522
+ phrase: t("When {device} finishes", "Quando {device} finisce"),
80523
+ icon: "square"
80524
+ }
80525
+ }
80526
+ },
79989
80527
  update: {
79990
80528
  scope: "device",
79991
80529
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -81145,6 +81683,7 @@ var SYSTEM_CAP_VOCABULARY = {
81145
81683
  "device-provider": system(INTERNAL),
81146
81684
  "device-removal-hook": system(INTERNAL),
81147
81685
  "device-state": system("the runtime-state mirror every trigger already reads through"),
81686
+ "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
81148
81687
  "embedding-encoder": system(ML),
81149
81688
  "face-gallery": system("the face gallery — curated on its own page"),
81150
81689
  "failure-contribution": system(INTERNAL),
@@ -83526,6 +84065,11 @@ Object.freeze({
83526
84065
  form: "single",
83527
84066
  optional: true
83528
84067
  }],
84068
+ "runningState.getStatus": [{
84069
+ name: "deviceId",
84070
+ form: "single",
84071
+ optional: false
84072
+ }],
83529
84073
  "sceneMonitor.captureReference": [{
83530
84074
  name: "deviceId",
83531
84075
  form: "single",
@@ -84024,6 +84568,96 @@ Object.freeze({
84024
84568
  "smtp-provider": "email"
84025
84569
  });
84026
84570
  DeviceType.Camera;
84571
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
84572
+ /**
84573
+ * A saved Customize assignment (D936). The schema is the type: callers use
84574
+ * `z.infer`, they do not restate the shape.
84575
+ */
84576
+ var OverrideSourceSchema = object({
84577
+ addonId: string().min(1),
84578
+ stableId: string().min(1),
84579
+ cap: string().min(1),
84580
+ fieldPath: string().min(1)
84581
+ });
84582
+ var CustomizeTransformDraftSchema = discriminatedUnion("kind", [
84583
+ object({ kind: literal("identity") }),
84584
+ object({ kind: literal("invert") }),
84585
+ object({
84586
+ kind: literal("threshold"),
84587
+ comparison: _enum(["gte", "lte"]),
84588
+ threshold: number(),
84589
+ startDwellMs: number().nonnegative(),
84590
+ stopDwellMs: number().nonnegative()
84591
+ }),
84592
+ object({
84593
+ kind: literal("linear"),
84594
+ scale: number(),
84595
+ offset: number(),
84596
+ clampMin: number().optional(),
84597
+ clampMax: number().optional()
84598
+ }),
84599
+ object({
84600
+ kind: literal("enum-map"),
84601
+ mapping: record(string(), string().nullable())
84602
+ }),
84603
+ object({ kind: literal("number") })
84604
+ ]);
84605
+ var ScalarOverrideDraftSchema = object({
84606
+ kind: literal("scalar"),
84607
+ cap: string().min(1),
84608
+ targetId: string().min(1),
84609
+ source: OverrideSourceSchema,
84610
+ transform: CustomizeTransformDraftSchema
84611
+ });
84612
+ var KeyedArrayOverrideDraftSchema = object({
84613
+ kind: literal("keyedArray"),
84614
+ cap: string().min(1),
84615
+ targetId: string().min(1),
84616
+ key: string().min(1),
84617
+ label: string().min(1),
84618
+ fieldPath: string().min(1),
84619
+ source: OverrideSourceSchema,
84620
+ transform: CustomizeTransformDraftSchema
84621
+ });
84622
+ var PulseOverrideDraftSchema = object({
84623
+ kind: literal("pulse"),
84624
+ cap: string().min(1),
84625
+ targetId: string().min(1),
84626
+ enabled: boolean(),
84627
+ debounceMs: number().nonnegative(),
84628
+ sources: array(OverrideSourceSchema).min(1)
84629
+ });
84630
+ var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
84631
+ "in-addition",
84632
+ "confirm",
84633
+ "replace"
84634
+ ]).optional() });
84635
+ discriminatedUnion("kind", [
84636
+ ScalarOverrideDraftSchema,
84637
+ KeyedArrayOverrideDraftSchema,
84638
+ PulseOverrideDraftSchema,
84639
+ object({
84640
+ kind: literal("span"),
84641
+ cap: string().min(1),
84642
+ targetId: string().min(1),
84643
+ timeoutMs: number().nonnegative(),
84644
+ cooldownMs: number().nonnegative().optional(),
84645
+ sources: array(SpanSourceDraftSchema)
84646
+ })
84647
+ ]);
84648
+ object({
84649
+ targetId: string().min(1),
84650
+ configured: boolean(),
84651
+ source: _enum(["native", "assigned"]),
84652
+ state: _enum([
84653
+ "active",
84654
+ "stale",
84655
+ "released",
84656
+ "unavailable"
84657
+ ]),
84658
+ reason: string().nullable()
84659
+ });
84660
+ String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
84027
84661
  var G711_SCALE_CORRECTION_DB = {
84028
84662
  PCMU: 20 * Math.log10(4),
84029
84663
  PCMA: 20 * Math.log10(8)
@@ -84126,40 +84760,7 @@ var NC_AUDIO_DEFAULTS = {
84126
84760
  samplingSeconds: 10
84127
84761
  };
84128
84762
  new Set(["devices", "classes"]);
84129
- /**
84130
- * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
84131
- * consumed by the rule ENGINE and by every rule EDITOR.
84132
- *
84133
- * ── The failure this file exists for ───────────────────────────────────────
84134
- * `NcSystemEventConditionSchema` carries four optional narrowing lists
84135
- * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
84136
- * `kinds` gate. They are not four filters over one vocabulary: each belongs to
84137
- * a FAMILY of kinds and is meaningless outside it. A node going away has no
84138
- * device type; a completed export has no package; `stream-offline` deliberately
84139
- * carries no device type at all (a stream belongs to a camera by construction).
84140
- *
84141
- * The engine applied all four to every kind, so a filter from one family failed
84142
- * a kind from another family CLOSED. The operator's live rule "Eventi di
84143
- * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
84144
- * way to say "only my cameras" about the two liveness kinds — and NINE of the
84145
- * eleven silently stopped being deliverable. Four days of history contained
84146
- * `device-online` and `device-offline` and nothing else, across a window in
84147
- * which agents were restarted and addons were updated.
84148
- *
84149
- * Both editors already computed this scoping, to decide which filter boxes to
84150
- * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
84151
- * to these device TYPES"). Only the engine disagreed, and it disagreed in the
84152
- * destructive direction. So the rule is stated ONCE, here, and the engine and
84153
- * the editors are readers of it rather than three independent authors.
84154
- *
84155
- * ── The direction ─────────────────────────────────────────────────────────
84156
- * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
84157
- * hides a box has already told the operator this filter does not speak about
84158
- * these kinds, so honouring it as an exclusion contradicts the only
84159
- * explanation the operator was ever given. Inside its family the filter still
84160
- * narrows, and still fails CLOSED on a subject that cannot produce the identity
84161
- * it tests (a device the mirror cannot name is not evidence of a camera).
84162
- */
84763
+ new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
84163
84764
  /**
84164
84765
  * Every filter, for the callers that must cover all of them (guards, tests).
84165
84766
  *
@@ -84185,9 +84786,6 @@ new Map(Object.entries({
84185
84786
  "device-battery-normal": "device-events",
84186
84787
  "device-consumable-low": "device-events",
84187
84788
  "device-consumable-normal": "device-events",
84188
- "device-tank-low": "device-events",
84189
- "device-tank-full": "device-events",
84190
- "device-tank-normal": "device-events",
84191
84789
  "stream-online": "device-events",
84192
84790
  "stream-offline": "device-events",
84193
84791
  "detection-blind": "device-events",
@@ -84264,16 +84862,6 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
84264
84862
  label: "Consumables",
84265
84863
  kinds: ["device-consumable-low", "device-consumable-normal"]
84266
84864
  },
84267
- {
84268
- id: "tanks",
84269
- family: "device-events",
84270
- label: "Tanks",
84271
- kinds: [
84272
- "device-tank-low",
84273
- "device-tank-full",
84274
- "device-tank-normal"
84275
- ]
84276
- },
84277
84865
  {
84278
84866
  id: "detection-blind",
84279
84867
  family: "device-events",
@@ -84431,11 +85019,6 @@ var RULE_BODY_ONLY = ["body"];
84431
85019
  var RULE_TEXT = ["title", "body"];
84432
85020
  var BATTERY = ["device-battery-low", "device-battery-normal"];
84433
85021
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
84434
- var TANK = [
84435
- "device-tank-low",
84436
- "device-tank-full",
84437
- "device-tank-normal"
84438
- ];
84439
85022
  var ALERT_EPISODE = [
84440
85023
  "alert-critical",
84441
85024
  "alert-error",
@@ -84467,7 +85050,6 @@ var DEVICE_EVENTS = [
84467
85050
  "device-enabled",
84468
85051
  ...BATTERY,
84469
85052
  ...CONSUMABLE,
84470
- ...TANK,
84471
85053
  "stream-online",
84472
85054
  "stream-offline",
84473
85055
  "detection-blind",
@@ -84513,12 +85095,6 @@ var STATE_SUMMARY_SECTION_VARS = [
84513
85095
  example: "Robot — filter 10 %",
84514
85096
  kinds: CONSUMABLE
84515
85097
  },
84516
- {
84517
- name: "summaryTanks",
84518
- label: "Summary: tanks",
84519
- example: "Robot — clean water low",
84520
- kinds: TANK
84521
- },
84522
85098
  {
84523
85099
  name: "summaryDetection",
84524
85100
  label: "Summary: cameras detecting nothing",
@@ -84634,8 +85210,7 @@ var STATE_SUMMARY_VARS = [
84634
85210
  ([...RULE_TEXT], [...COMBINED_ALARM]),
84635
85211
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
84636
85212
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
84637
- ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
84638
- ([...RULE_TEXT], [...TANK]),
85213
+ ([...RULE_TEXT], [...CONSUMABLE]),
84639
85214
  [...RULE_TEXT],
84640
85215
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
84641
85216
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
@@ -84739,15 +85314,6 @@ new Map([
84739
85314
  snapshotLabel: "Consumables low now",
84740
85315
  snapshotSection: "consumables"
84741
85316
  },
84742
- {
84743
- id: "tanks",
84744
- family: "device-events",
84745
- label: "Tanks (low or full / back to normal)",
84746
- bad: ["device-tank-low", "device-tank-full"],
84747
- recovery: ["device-tank-normal"],
84748
- snapshotLabel: "Tanks low or full now",
84749
- snapshotSection: "tanks"
84750
- },
84751
85317
  {
84752
85318
  id: "motion-noise",
84753
85319
  family: "device-events",