@camstack/addon-pipeline 1.2.314 → 1.2.315

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 (31) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-Es1-dvFU.mjs → default-detection-model-BTlf5MpT.mjs} +1 -1
  4. package/dist/{default-detection-model-BvxtQEcb.js → default-detection-model-CteW4o8U.js} +1 -1
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-E1Z_K22_.mjs → dist-C8W_MWSz.mjs} +156 -114
  8. package/dist/{dist-Jvi2SOxI.js → dist-sCjZdzKn.js} +161 -119
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-DHe-9_tm.mjs → node-CnLKPz1A.mjs} +1 -1
  12. package/dist/{node-EjcZQh8D.js → node-D4xdwpPU.js} +1 -1
  13. package/dist/pipeline-runner/index.js +19 -58
  14. package/dist/pipeline-runner/index.mjs +17 -56
  15. package/dist/{process-memory-BUtnSPYK.js → process-memory-CMnhjGyE.js} +1 -1
  16. package/dist/{process-memory-IQcwHauP.mjs → process-memory-DqTBUteS.mjs} +1 -1
  17. package/dist/recorder/index.js +3 -3
  18. package/dist/recorder/index.mjs +3 -3
  19. package/dist/{segment-demux-js-CR58wpzs.mjs → segment-demux-js-CCSsDyMw.mjs} +1 -1
  20. package/dist/{segment-demux-js-Il0EkSOb.js → segment-demux-js-DGpdNqsG.js} +1 -1
  21. package/dist/stream-broker/_stub.js +1 -1
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CBvGGDX_.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BOKNSh-e.mjs} +2 -2
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BTvQXobK.mjs +26 -0
  24. package/dist/stream-broker/demux-worker-child.js +1 -1
  25. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  26. package/dist/stream-broker/{hostInit-CjvrBwfh.mjs → hostInit-BkvtmJ2D.mjs} +2 -2
  27. package/dist/stream-broker/index.js +3 -3
  28. package/dist/stream-broker/index.mjs +3 -3
  29. package/dist/stream-broker/remoteEntry.js +1 -1
  30. package/package.json +1 -1
  31. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D0BR9vFO.mjs +0 -26
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Jvi2SOxI.js");
7
- const require_process_memory = require("../process-memory-BUtnSPYK.js");
6
+ const require_dist = require("../dist-sCjZdzKn.js");
7
+ const require_process_memory = require("../process-memory-CMnhjGyE.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_chunk.__toESM(node_fs);
10
10
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { E as HF_BASE_URL, En as nodePin, G as audioAnalyzerCapability, Kt as resolvePoolMemoryPolicy, Sn as hydrateSchema, St as mapAudioLabelToMacro, Un as EventCategory, W as audioAnalysisCapability, _n as audioChunkBytesPerSample, fn as errMsg, j as PoolMemoryWatchdog, m as DEFAULT_AUDIO_ANALYZER_CONFIG, mn as BaseAddon, r as AUDIO_BACKEND_CHOICES, xn as expandAudioChunkToF32le } from "../dist-E1Z_K22_.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-IQcwHauP.mjs";
2
+ import { A as PoolMemoryWatchdog, E as HF_BASE_URL, En as nodePin, Kt as resolvePoolMemoryPolicy, Sn as hydrateSchema, St as mapAudioLabelToMacro, U as audioAnalysisCapability, Un as EventCategory, W as audioAnalyzerCapability, _n as audioChunkBytesPerSample, fn as errMsg, m as DEFAULT_AUDIO_ANALYZER_CONFIG, mn as BaseAddon, r as AUDIO_BACKEND_CHOICES, xn as expandAudioChunkToF32le } from "../dist-C8W_MWSz.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DqTBUteS.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
6
6
  import { downloadFile } from "@camstack/system/addon-utils";
@@ -1,4 +1,4 @@
1
- import { K as audioKindId, Yt as stepModelRunsOnFormat, _t as hfModelUrl, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, p as COCO_TO_MACRO, vt as inferModelProvider, y as DEVICE_BACKEND_TO_FORMAT } from "./dist-E1Z_K22_.mjs";
1
+ import { G as audioKindId, Yt as stepModelRunsOnFormat, _t as hfModelUrl, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, p as COCO_TO_MACRO, vt as inferModelProvider, y as DEVICE_BACKEND_TO_FORMAT } from "./dist-C8W_MWSz.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/registry/effective-confidence.ts
4
4
  /** The default in force: the model's own floor, else the step's. */
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-Jvi2SOxI.js");
1
+ const require_dist = require("./dist-sCjZdzKn.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/registry/effective-confidence.ts
4
4
  /** The default in force: the model's own floor, else the step's. */
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Jvi2SOxI.js");
7
- const require_node = require("../node-EjcZQh8D.js");
8
- const require_default_detection_model = require("../default-detection-model-BvxtQEcb.js");
6
+ const require_dist = require("../dist-sCjZdzKn.js");
7
+ const require_node = require("../node-D4xdwpPU.js");
8
+ const require_default_detection_model = require("../default-detection-model-CteW4o8U.js");
9
9
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
10
- const require_process_memory = require("../process-memory-BUtnSPYK.js");
10
+ const require_process_memory = require("../process-memory-CMnhjGyE.js");
11
11
  let node_os = require("node:os");
12
12
  node_os = require_chunk.__toESM(node_os);
13
13
  let node_fs = require("node:fs");
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { An as sleep, At as overlayClusterStepSettings, Dn as parseJsonUnknown, En as nodePin, Ft as pipelineExecutorCapability, H as YAMNET_TO_MACRO, Hn as union, Ht as resolveClusterStepModelId, Jt as runtimeDevices$1, Kt as resolvePoolMemoryPolicy, Mn as array, Mt as pickClusterStepSettings, Rn as object, Sn as hydrateSchema, Un as EventCategory, Vn as string, Yt as stepModelRunsOnFormat, bt as loadContributionCapability, ct as evaluateZoneRules, d as CLUSTER_MODEL_SCOPED_STEPS, en as supportedRuntimes$1, et as defaultDeviceFor$1, fn as errMsg, h as DEFAULT_CLUSTER_STEP_SETTINGS, it as detectionPipelineCapability, j as PoolMemoryWatchdog, mn as BaseAddon, n as APPLE_SA_TO_MACRO, st as enumerateInferenceDevices, vn as createEvent, y as DEVICE_BACKEND_TO_FORMAT } from "../dist-E1Z_K22_.mjs";
3
- import { s as readProcessCost } from "../node-DHe-9_tm.mjs";
4
- import { _ as resolveModelForFormat, a as buildSubtreeCanRun, b as resolveModelDefaultConfidence, c as macroGateVerdict, f as ALL_PIPELINE_STEPS, g as getStepDefinition, h as getStep, i as mergeCustomModels, m as getDefaultModelForFormat, n as resolveDefaultDetectionModel, p as ALL_STEPS, r as CustomModelCatalog, u as localFrameRegistry, y as landmarkPrecisionVerdict } from "../default-detection-model-Es1-dvFU.mjs";
2
+ import { A as PoolMemoryWatchdog, An as sleep, At as overlayClusterStepSettings, Dn as parseJsonUnknown, En as nodePin, Ft as pipelineExecutorCapability, Hn as union, Ht as resolveClusterStepModelId, Jt as runtimeDevices$1, Kt as resolvePoolMemoryPolicy, Mn as array, Mt as pickClusterStepSettings, Rn as object, Sn as hydrateSchema, Un as EventCategory, V as YAMNET_TO_MACRO, Vn as string, Yt as stepModelRunsOnFormat, bt as loadContributionCapability, ct as evaluateZoneRules, d as CLUSTER_MODEL_SCOPED_STEPS, en as supportedRuntimes$1, et as defaultDeviceFor$1, fn as errMsg, h as DEFAULT_CLUSTER_STEP_SETTINGS, it as detectionPipelineCapability, mn as BaseAddon, n as APPLE_SA_TO_MACRO, st as enumerateInferenceDevices, vn as createEvent, y as DEVICE_BACKEND_TO_FORMAT } from "../dist-C8W_MWSz.mjs";
3
+ import { s as readProcessCost } from "../node-CnLKPz1A.mjs";
4
+ import { _ as resolveModelForFormat, a as buildSubtreeCanRun, b as resolveModelDefaultConfidence, c as macroGateVerdict, f as ALL_PIPELINE_STEPS, g as getStepDefinition, h as getStep, i as mergeCustomModels, m as getDefaultModelForFormat, n as resolveDefaultDetectionModel, p as ALL_STEPS, r as CustomModelCatalog, u as localFrameRegistry, y as landmarkPrecisionVerdict } from "../default-detection-model-BTlf5MpT.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-IQcwHauP.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DqTBUteS.mjs";
7
7
  import * as os from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- //#region ../types/dist/event-category-C5xZWqz6.mjs
2
+ //#region ../types/dist/event-category-BGmz_oxW.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -532,6 +532,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
532
532
  */
533
533
  EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
534
534
  EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
535
+ /**
536
+ * A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
537
+ * data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
538
+ * consumer is the orchestrator's camera-sensors bridge, which re-emits the
539
+ * camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
540
+ * for a camera with no attached sensor). Providers must not emit
541
+ * `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
542
+ * keeps it so (camera-grid is a named, deferred exception).
543
+ */
535
544
  EventCategory["ProviderMotion"] = "provider.motion";
536
545
  EventCategory["ProviderDetection"] = "provider.detection";
537
546
  EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
@@ -5370,7 +5379,7 @@ var ZodIssueCode = {
5370
5379
  var ZodFirstPartyTypeKind;
5371
5380
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5372
5381
  //#endregion
5373
- //#region ../types/dist/sleep-gU6hqv4_.mjs
5382
+ //#region ../types/dist/sleep-CDCONfkt.mjs
5374
5383
  /**
5375
5384
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5376
5385
  * window to float samples (D455).
@@ -7684,7 +7693,7 @@ function errMsg(err) {
7684
7693
  return String(err);
7685
7694
  }
7686
7695
  //#endregion
7687
- //#region ../types/dist/composition-Dq42XWp0.mjs
7696
+ //#region ../types/dist/composition-43aqsZQj.mjs
7688
7697
  var AUDIO_ENCODER_BY_CODEC = {
7689
7698
  opus: "libopus",
7690
7699
  aac: "aac",
@@ -8448,13 +8457,12 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
8448
8457
  * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
8449
8458
  * valutatore puro del suo FRONTE.
8450
8459
  *
8451
- * Viveva dentro il builtin virtual-doorbell
8452
- * (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
8453
- * predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
8454
- * `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
8455
- * tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
8456
- * fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
8457
- * SPOSTA qui e il doorbell la ri-esporta.
8460
+ * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
8461
+ * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
8462
+ * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
8463
+ * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
8464
+ * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
8465
+ * sensore fa suonare il campanello ma non registra" — è esattamente D62.
8458
8466
  *
8459
8467
  * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
8460
8468
  * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
@@ -10678,7 +10686,7 @@ var RecordingTriggersSchema = object({
10678
10686
  *
10679
10687
  * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
10680
10688
  * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
10681
- * la stessa che il virtual-doorbell usa dal 2026-08-05. Ed è il FRONTE, non
10689
+ * la stessa del campanello composto (D671). Ed è il FRONTE, non
10682
10690
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
10683
10691
  * registrare.
10684
10692
  */
@@ -17948,28 +17956,10 @@ method(object({
17948
17956
  deviceIds: array(number()).readonly(),
17949
17957
  caps: array(string()).readonly().optional()
17950
17958
  }), record(string(), record(string(), unknown().nullable())));
17951
- object({
17952
- /** Ms epoch of the last press. null = never observed since this provider started. */
17953
- lastPressedAt: number().nullable(),
17954
- /** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
17955
- pressCountSinceStart: number()
17956
- });
17957
- object({
17958
- deviceId: number(),
17959
- timestamp: number()
17960
- });
17961
- /**
17962
- * The `doorbell-source` extension slot's editable value (D648): the camera's
17963
- * virtual-doorbell trigger devices, exactly what the wrapper's
17964
- * `doorbellSources` persists (as `{ deviceId }` records).
17965
- */
17966
- var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
17959
+ var ExtensionSlotIdSchema = _enum(["linked-devices"]);
17967
17960
  DeviceType.Camera;
17968
- DeviceType.Button, DeviceType.Camera;
17969
- var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
17970
- DeviceType.Camera, DeviceType.Camera;
17971
17961
  /** A slot's editable value, discriminated on `slot`. */
17972
- var ExtensionSlotValueSchema = discriminatedUnion("slot", [DoorbellSourceSlotValueSchema.extend({ slot: literal("doorbell-source") }), LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
17962
+ var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
17973
17963
  DeviceType.Camera;
17974
17964
  var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
17975
17965
  state: literal("unreachable"),
@@ -18006,10 +17996,11 @@ var ExtensionSlotSourceSchema = object({
18006
17996
  });
18007
17997
  /**
18008
17998
  * A DIFFERENT authority that gates whether the slot's sources do anything —
18009
- * reported read-only, named, never written through this contract (D62). The
18010
- * virtual doorbell's sources ring only while the wrapper is bound to the
18011
- * camera, and that binding belongs to `deviceManager.setWrapperActive`.
18012
- * `unknown` means the gate could not be read; it is not "inactive" (D315).
17999
+ * reported read-only, named, never written through this contract (D62) — e.g.
18000
+ * a slot whose sources act only while a wrapper is bound to the host, a
18001
+ * binding that belongs to `deviceManager.setWrapperActive`. No slot reports
18002
+ * one today (`linked-devices` answers `null`). `unknown` means the gate could
18003
+ * not be read; it is not "inactive" (D315).
18013
18004
  */
18014
18005
  var ExtensionSlotActivationSchema = object({
18015
18006
  state: _enum([
@@ -18025,7 +18016,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
18025
18016
  /** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
18026
18017
  slotRef: string(),
18027
18018
  slot: ExtensionSlotIdSchema,
18028
- /** Names the store written (D62), e.g. `virtual-doorbell:doorbellSources`. */
18019
+ /** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
18029
18020
  authority: string(),
18030
18021
  activation: ExtensionSlotActivationSchema.nullable(),
18031
18022
  value: ExtensionSlotValueSchema,
@@ -23506,12 +23497,26 @@ var CameraSensorRefSchema = object({
23506
23497
  function cameraSensorRefKey(ref) {
23507
23498
  return `${ref.addonId}/${ref.stableId}`;
23508
23499
  }
23509
- /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
23510
- var CameraSensorsModeSchema = _enum(["in-addition"]);
23511
- var CameraSensorsConfigSchema = object({
23512
- mode: CameraSensorsModeSchema,
23513
- sensors: array(CameraSensorRefSchema).min(1).max(8)
23514
- }).superRefine((value, ctx) => {
23500
+ /**
23501
+ * A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
23502
+ * `replace`: its motion is the camera's, and while one is READY the camera's
23503
+ * own motion no longer counts on its own. `confirm`: while one is READY the
23504
+ * camera's own motion counts only while a confirm sensor is active — with or
23505
+ * without a replace sensor (spec C2, the controller's ruling on Q1).
23506
+ */
23507
+ var CameraSensorModeSchema = _enum([
23508
+ "in-addition",
23509
+ "confirm",
23510
+ "replace"
23511
+ ]);
23512
+ /** A stored sensor with no mode — every CS-1 row — is in addition. */
23513
+ var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
23514
+ /**
23515
+ * A camera's attached sensors. A CS-1 row carried an envelope
23516
+ * `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
23517
+ * what the write stores (D672 rule 3), so it is never written again.
23518
+ */
23519
+ var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
23515
23520
  const seen = /* @__PURE__ */ new Set();
23516
23521
  value.sensors.forEach((ref, index) => {
23517
23522
  const key = cameraSensorRefKey(ref);
@@ -23523,39 +23528,41 @@ var CameraSensorsConfigSchema = object({
23523
23528
  seen.add(key);
23524
23529
  });
23525
23530
  });
23526
- var RefFields = {
23531
+ /** Every attachment names its mode; an older orchestrator that does not is in addition. */
23532
+ var AttachmentFields = {
23527
23533
  addonId: string(),
23528
- stableId: string()
23534
+ stableId: string(),
23535
+ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
23529
23536
  };
23530
23537
  var CameraSensorAttachmentSchema = discriminatedUnion("state", [
23531
23538
  object({
23532
- ...RefFields,
23539
+ ...AttachmentFields,
23533
23540
  state: literal("ready"),
23534
23541
  deviceId: number(),
23535
23542
  name: string(),
23536
23543
  caps: array(string()).readonly()
23537
23544
  }),
23538
23545
  object({
23539
- ...RefFields,
23546
+ ...AttachmentFields,
23540
23547
  state: literal("offline"),
23541
23548
  deviceId: number(),
23542
23549
  name: string(),
23543
23550
  reason: _enum(["offline", "disabled"])
23544
23551
  }),
23545
23552
  object({
23546
- ...RefFields,
23553
+ ...AttachmentFields,
23547
23554
  state: literal("missing"),
23548
23555
  reason: string()
23549
23556
  }),
23550
23557
  object({
23551
- ...RefFields,
23558
+ ...AttachmentFields,
23552
23559
  state: literal("unsupported"),
23553
23560
  deviceId: number(),
23554
23561
  name: string(),
23555
23562
  reason: string()
23556
23563
  }),
23557
23564
  object({
23558
- ...RefFields,
23565
+ ...AttachmentFields,
23559
23566
  state: literal("unreadable"),
23560
23567
  reason: string()
23561
23568
  })
@@ -23568,17 +23575,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
23568
23575
  * say.
23569
23576
  */
23570
23577
  var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
23578
+ /** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
23579
+ var CameraOwnMotionSchema = _enum([
23580
+ "always",
23581
+ "when-confirmed",
23582
+ "never"
23583
+ ]);
23584
+ /** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
23585
+ var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
23586
+ /**
23587
+ * The camera's OWN onboard motion (D696): the raw input the bridge combines,
23588
+ * never the effective value. The camera's `motion` slice is the effective one,
23589
+ * so a view of the camera's own row reads this.
23590
+ * - `atMs`: when the bridge received the camera's last own edge.
23591
+ * - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
23592
+ * AND it is younger than the window the bridge counts the camera's own motion
23593
+ * for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
23594
+ * sends a clear (heartbeats only) therefore reads `false` once no push came
23595
+ * within the window; a status read is a snapshot, so a live view re-asks.
23596
+ * Absent = this orchestrator has not received the camera's own motion since it
23597
+ * started (unknown, never "quiet"), or an orchestrator older than D696.
23598
+ */
23599
+ var CameraRawLevelSchema = object({
23600
+ detected: boolean(),
23601
+ atMs: number()
23602
+ });
23571
23603
  var CameraSensorsStatusSchema = discriminatedUnion("state", [
23572
- object({ state: literal("not-configured") }),
23604
+ object({
23605
+ state: literal("not-configured"),
23606
+ cameraLevel: CameraRawLevelSchema.optional()
23607
+ }),
23573
23608
  object({
23574
23609
  state: literal("unreadable"),
23575
- reason: string()
23610
+ reason: string(),
23611
+ cameraLevel: CameraRawLevelSchema.optional()
23576
23612
  }),
23577
23613
  object({
23578
23614
  state: literal("configured"),
23579
- mode: CameraSensorsModeSchema,
23615
+ cameraLevel: CameraRawLevelSchema.optional(),
23580
23616
  sensors: array(CameraSensorAttachmentSchema).readonly(),
23581
- notForwarded: CameraSensorsNotForwardedSchema.optional()
23617
+ /** Absent = an orchestrator older than CS-2: it does not say (D315). */
23618
+ cameraMotion: CameraOwnMotionSchema.optional(),
23619
+ notForwarded: CameraSensorsNotForwardedSchema.optional(),
23620
+ notEnforced: CameraSensorsNotEnforcedSchema.optional()
23582
23621
  })
23583
23622
  ]);
23584
23623
  Object.freeze({
@@ -27012,8 +27051,10 @@ var RunnerCameraConfigSchema = object({
27012
27051
  * - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
27013
27052
  * analyzer providers) running on decoded frames in this runner.
27014
27053
  * - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
27015
- * analytics). The provider emits ProviderMotion
27016
- * events; the orchestrator forwards to `reportMotion`.
27054
+ * analytics). The provider emits its raw push as `ProviderMotion`
27055
+ * (D673); the orchestrator's camera-sensors bridge re-emits the camera's
27056
+ * effective motion as `MotionOnMotionChanged`, which is what reaches
27057
+ * `reportMotion`.
27017
27058
  */
27018
27059
  motionSources: MotionSourcesSchema.default(["analyzer"]),
27019
27060
  /**
@@ -27190,7 +27231,15 @@ var RunnerLocalLoadSchema = object({
27190
27231
  hasGpu: boolean(),
27191
27232
  inferenceBackend: string().optional(),
27192
27233
  cpuCores: number().optional()
27193
- })
27234
+ }),
27235
+ /**
27236
+ * Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
27237
+ * runner never writes it. ABSENT = a runner older than D696, which still
27238
+ * writes the slice from its phase machine; the orchestrator does not write
27239
+ * while any runner node is absent-or-unanswered, so one slice never has two
27240
+ * writers.
27241
+ */
27242
+ motionSliceWriter: literal("orchestrator").optional()
27194
27243
  });
27195
27244
  /**
27196
27245
  * Aggregate runtime metrics for the runner's whole local pool. Mirrors the
@@ -32698,6 +32747,17 @@ object({
32698
32747
  deviceId: number(),
32699
32748
  status: DeviceStatusSchema
32700
32749
  });
32750
+ object({
32751
+ /** Ms epoch of the last press. null = never observed since this provider started. */
32752
+ lastPressedAt: number().nullable(),
32753
+ /** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
32754
+ pressCountSinceStart: number()
32755
+ });
32756
+ object({
32757
+ deviceId: number(),
32758
+ timestamp: number()
32759
+ });
32760
+ DeviceType.Button, DeviceType.Camera;
32701
32761
  /**
32702
32762
  * Enum-state sensor — a string value picked from a finite option set.
32703
32763
  * Drives HA `sensor` entries with `state_class: enum` (HVAC action
@@ -34337,39 +34397,14 @@ authKey: string().optional() }), object({
34337
34397
  /** Human-readable error when `ok: false`. */
34338
34398
  error: string().optional()
34339
34399
  }), { kind: "mutation" });
34340
- /**
34341
- * Hardware / firmware motion sensor cap — binary detected state plus
34342
- * a timestamp of the last observation. Distinct from
34343
- * `motion-detection.cap.ts` which owns the LOCAL ML motion pipeline;
34344
- * `motion` is the lightweight readout from on-camera motion (Reolink
34345
- * `GetMdState`, Baichuan push `type: motion`, ONVIF analytics).
34346
- *
34347
- * Native-motion providers also fan out to `detection.camera-native`
34348
- * with `source: 'onboard'` so cross-cutting system services
34349
- * (alert-center, advanced-notifier) can subscribe once and receive
34350
- * motion from every camera.
34351
- */
34352
- /**
34353
- * How long after a camera's last rising edge `pipeline-analytics` closes the
34354
- * motion EPISODE row it kept open for it (D475) — "il delay della cap", in
34355
- * the operator's words. One authority for the whole system: every provider
34356
- * that seeds `autoClearAfterMs` on a `Camera` device writes this SAME
34357
- * constant while `detected: true` (never its own number — Hikvision used to
34358
- * seed its internal 3 s inactivity timer here, which is a different clock for
34359
- * a different purpose), and `MotionEpisodeTracker` imports it directly rather
34360
- * than reading the live cap value on the hot path. A `Sensor` device (HA
34361
- * binary sensor, Homematic) gets a genuine push both ways and has no episode
34362
- * to close on a timer, so it writes `null`, never this constant.
34363
- */
34364
- var MOTION_CLOSE_AFTER_MS = 15e3;
34365
34400
  object({
34366
34401
  detected: boolean(),
34367
34402
  /** Ms epoch of the last detected-true observation. Null if never detected. */
34368
34403
  lastDetectedAt: number().nullable(),
34369
34404
  /**
34370
- * `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device,
34371
- * `null` while false and on every `Sensor` device (D475) — see that
34372
- * constant's doc for the one-authority rule.
34405
+ * `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
34406
+ * orchestrator writes it, D696), `null` while false and on every `Sensor`
34407
+ * device (D475) — see that constant's doc for the one-authority rule.
34373
34408
  *
34374
34409
  * ## Reading this field still arms nothing
34375
34410
  *
@@ -34387,38 +34422,41 @@ object({
34387
34422
  * `addon-export-alexa/src/motion-clear-hold.ts` and
34388
34423
  * `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
34389
34424
  *
34390
- * ## Who writes it
34391
- *
34392
- * - **Cameras** — the runner's phase machine, `active → watching` on
34393
- * `cooldown_expired`, which then writes this slice with
34394
- * `detected: false` (`handlePhaseChanged` in
34395
- * `pipeline-runner/index.ts`). It produces the FALLING edge, which
34396
- * matters most for the sources that only ever push a rising one:
34397
- * Reolink emits `MotionOnMotionChanged { detected: true }` and never
34398
- * a false.
34399
- * - **Sensors** (Home Assistant binary sensors, Homematic) — the
34400
- * provider pushes the false itself, from the upstream system's own
34401
- * state change. No phase machine is involved.
34402
- *
34403
- * ### The phase machine is CANONICAL, not sole — and that is a defect
34404
- *
34405
- * An earlier revision of this docblock (mine, 2026-09-12) claimed the
34406
- * phase machine is the sole writer for a camera. It is not.
34407
- * `hikvision-camera.ts:3464` and `amcrest-camera.ts:445` both call
34408
- * `setCapSlice(motionCapability, …)` on their own rising edge, and
34409
- * Hikvision's comment says why: it read THIS docblock, agreed the
34410
- * runner is canonical, and wrote anyway to avoid per-tick churn. So
34411
- * two authorities can disagree about one slice, which this repo
34412
- * forbids, and the doc said otherwise — which is worse than saying
34413
- * nothing, because it reads as verification.
34414
- *
34415
- * This predates D475 and is not fixed there: the fix touches every
34416
- * camera provider. Recorded in D475's Consequences. Do not restore the
34417
- * "sole writer" wording without also removing the other writers.
34425
+ * ## Who writes it (D696)
34426
+ *
34427
+ * - **Cameras** — the orchestrator, and nothing else. It writes the camera's
34428
+ * EFFECTIVE motion (`addon-pipeline-orchestrator`
34429
+ * `camera-sensors/motion-slice.ts`), alongside the effective
34430
+ * `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
34431
+ * for a split camera, an unsplit emitter's direct event, the analyzer and
34432
+ * device activity, as the camera's `motionSources` counts them. A source
34433
+ * that never sends a clear falls one window after its last `true`.
34434
+ * `lastDetectedAt` moves only on an effective rise. No camera provider
34435
+ * writes this slice (not even a boot seed), and neither does the runner's
34436
+ * phase machine: its phase is "a session is attached" for every on-motion
34437
+ * session, not motion, and it now has its own `DetectionPhaseTransition`.
34438
+ * A provider's `isDetected` answers from the hub's slice.
34439
+ * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
34440
+ * imports) — the provider pushes both edges itself, from the upstream
34441
+ * system's own state change. That is the sensor's own fact.
34442
+ *
34443
+ * `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
34444
+ * `motion` slice; each sensor writer is a named exemption.
34445
+ *
34446
+ * This replaces the D475 §4 rule ("the phase machine is the sole writer").
34447
+ * That rule was never true: Hikvision and Amcrest wrote the slice raw beside
34448
+ * it, every provider seeded it at boot, and every session left it
34449
+ * `detected: true` after its detach.
34418
34450
  */
34419
34451
  autoClearAfterMs: number().nullable()
34420
34452
  });
34421
- object({
34453
+ /**
34454
+ * Payload of `motion.onMotionChanged` event + the corresponding bus
34455
+ * event `EventCategory.MotionOnMotionChanged`. Single source of truth
34456
+ * — both the cap event surface and the bus payload type alias to this
34457
+ * schema.
34458
+ */
34459
+ var MotionOnMotionChangedDataSchema = object({
34422
34460
  deviceId: number(),
34423
34461
  detected: boolean(),
34424
34462
  timestamp: number(),
@@ -51484,6 +51522,10 @@ TimelapseRuleInputSchema.extend({
51484
51522
  createdAt: number(),
51485
51523
  updatedAt: number()
51486
51524
  });
51525
+ function cameraOwnsMotionViaSensor(motionSources) {
51526
+ return motionSources.some((s) => s !== "analyzer");
51527
+ }
51528
+ MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
51487
51529
  /** True when `model` ships a build for `format`. */
51488
51530
  function hasBuild(model, format) {
51489
51531
  return Boolean(model.formats[format]);
@@ -52699,4 +52741,4 @@ function enumerateInferenceDevices(hw) {
52699
52741
  return out;
52700
52742
  }
52701
52743
  //#endregion
52702
- export { declareLogChannel as $, stripRetiredBandPreBufferSec as $t, OpsLogEntrySchema as A, sleep as An, overlayClusterStepSettings as At, VIDEOCLIPS_MAX_OFFER_BYTES as B, record as Bn, recordingExportCapability as Bt, ExportRecordSchema as C, isEvent as Cn, maskUrlCredentials as Ct, MOTION_CLOSE_AFTER_MS as D, parseJsonUnknown as Dn, migrateLegacyDeviceSignalConfig as Dt, HF_BASE_URL as E, nodePin as En, memoizePinnedFfmpeg as Et, RECORDING_SOURCE_CAMSTACK as F, lazy as Fn, pipelineExecutorCapability as Ft, audioAnalyzerCapability as G, resolveLocationMode as Gt, YAMNET_TO_MACRO as H, union as Hn, resolveClusterStepModelId as Ht, RECORDING_SOURCE_CAMSTACK_ADDON as I, literal as In, pipelineRunnerCapability as It, cameraStreamsCapability as J, runtimeDevices as Jt, audioKindId as K, resolvePoolMemoryPolicy as Kt, RecordingConfigSchema as L, number as Ln, rankStreams as Lt, RATE_CONTROL_RELAXED as M, array as Mn, pickClusterStepSettings as Mt, RATE_CONTROL_TIGHT as N, boolean as Nn, pickDetailCropConvention as Nt, NativeLeaseAdmissionSchema as O, parseProfileBrokerId as On, modeMayWrite as Ot, RECORDING_EXPORT_MAX_READ_BYTES as P, discriminatedUnion as Pn, pickNativeLeaseOverride as Pt, createLogChannelsProvider as Q, streamBrokerCapability as Qt, RecordingSignalStatusSchema as R, object as Rn, recordingArchiveCapability as Rt, EncodeProfileSchema as S, hydrateSchema as Sn, mapAudioLabelToMacro as St, G711_SCALE_CORRECTION_DB as T, makeSourceBrokerId as Tn, mayWriteToLocation as Tt, addonWidgetsSourceCapability as U, EventCategory as Un, resolveCreateExportSubject as Ut, VISIT_MERGE_GAP_MS as V, string as Vn, recordingSignalCapability as Vt, audioAnalysisCapability as W, resolveEgressDecodeHwAccel as Wt, clipExportFailureOf as X, storageEvictableCapability as Xt, clipExportFailure as Y, stepModelRunsOnFormat as Yt, createHwAccelCache as Z, storageOccupancyCapability as Zt, DEFAULT_EVENTS_BAND_BUFFER_SEC as _, audioChunkBytesPerSample as _n, hfModelUrl as _t, BackgroundRunRegistry as a, Fmp4BoxSplitter as an, egressTranscodeSharingKey as at, EVENT_OWNER_TYPES as b, defineCustomActions as bn, loadContributionCapability as bt, CLIP_STILL_REASON_CODE_HEADER as c, invocationFromEncodeProfile as cn, evaluateZoneRules as ct, CLUSTER_MODEL_SCOPED_STEPS as d, DeviceType as dn, exportSubjectOf as dt, supportedRuntimes as en, defaultDeviceFor as et, COCO_80_LABELS as f, errMsg as fn, failureContributionCapability as ft, DEFAULT_DETAIL_CROP_CONVENTION as g, CamProfileSchema as gn, gifFromMp4Args as gt, DEFAULT_CLUSTER_STEP_SETTINGS as h, CAM_PROFILE_ORDER as hn, gifDeriveSpeed as ht, AUDIO_MACRO_LABELS as i, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as in, detectionPipelineCapability as it, PoolMemoryWatchdog as j, _enum as jn, parseProcStatus as jt, NativeLeaseSettingsSchema as k, selectAssignedProfileSlots as kn, motionDetectionCapability as kt, CLIP_STILL_REASON_HEADER as l, isSoftwareDecode as ln, evictionPolicyForMode as lt, DEFAULT_AUDIO_ANALYZER_CONFIG as m, BaseAddon as mn, gbToBytes as mt, APPLE_SA_TO_MACRO as n, webrtcSessionCapability as nn, deriveDetailCropRect as nt, BatteryStatusSchema as o, buildFfmpegArgs as on, egressTransportFromRequest as ot, COCO_TO_MACRO as p, BOOT_RECOVERY_BACKOFF_MS as pn, ffmpegRate as pt, batteryCapability as q, resolveRecordingProfiles as qt, AUDIO_BACKEND_CHOICES as r, AUDIO_PRESETS as rn, deriveRecordingMode as rt, CLIP_BROKER_PACED_RATES as s, evaluateSensorEdge as sn, enumerateInferenceDevices as st, APPEARANCE_BLOCKS as t, videoclipsCapability as tn, deriveBatteryPresence as tt, CLIP_STREAM_TRANSPORT_HEADER as u, DeviceFeature as un, evictionPolicyOfLocation as ut, DEFAULT_NATIVE_LEASE_SETTINGS as v, createEvent as vn, inferModelProvider as vt, FailureCounters as w, makeProfileBrokerId as wn, mayReadLocation as wt, EVENT_PAD_MS as x, expandAudioChunkToF32le as xn, logChannelsCapability as xt, DEVICE_BACKEND_TO_FORMAT as y, customAction as yn, isFirstLevelMacroClass as yt, RingBuffer as z, preprocess as zn, recordingCapability as zt };
52744
+ export { declareLogChannel as $, stripRetiredBandPreBufferSec as $t, PoolMemoryWatchdog as A, sleep as An, overlayClusterStepSettings as At, VISIT_MERGE_GAP_MS as B, record as Bn, recordingExportCapability as Bt, ExportRecordSchema as C, isEvent as Cn, maskUrlCredentials as Ct, NativeLeaseAdmissionSchema as D, parseJsonUnknown as Dn, migrateLegacyDeviceSignalConfig as Dt, HF_BASE_URL as E, nodePin as En, memoizePinnedFfmpeg as Et, RECORDING_SOURCE_CAMSTACK_ADDON as F, lazy as Fn, pipelineExecutorCapability as Ft, audioKindId as G, resolveLocationMode as Gt, addonWidgetsSourceCapability as H, union as Hn, resolveClusterStepModelId as Ht, RecordingConfigSchema as I, literal as In, pipelineRunnerCapability as It, cameraStreamsCapability as J, runtimeDevices as Jt, batteryCapability as K, resolvePoolMemoryPolicy as Kt, RecordingSignalStatusSchema as L, number as Ln, rankStreams as Lt, RATE_CONTROL_TIGHT as M, array as Mn, pickClusterStepSettings as Mt, RECORDING_EXPORT_MAX_READ_BYTES as N, boolean as Nn, pickDetailCropConvention as Nt, NativeLeaseSettingsSchema as O, parseProfileBrokerId as On, modeMayWrite as Ot, RECORDING_SOURCE_CAMSTACK as P, discriminatedUnion as Pn, pickNativeLeaseOverride as Pt, createLogChannelsProvider as Q, streamBrokerCapability as Qt, RingBuffer as R, object as Rn, recordingArchiveCapability as Rt, EncodeProfileSchema as S, hydrateSchema as Sn, mapAudioLabelToMacro as St, G711_SCALE_CORRECTION_DB as T, makeSourceBrokerId as Tn, mayWriteToLocation as Tt, audioAnalysisCapability as U, EventCategory as Un, resolveCreateExportSubject as Ut, YAMNET_TO_MACRO as V, string as Vn, recordingSignalCapability as Vt, audioAnalyzerCapability as W, resolveEgressDecodeHwAccel as Wt, clipExportFailureOf as X, storageEvictableCapability as Xt, clipExportFailure as Y, stepModelRunsOnFormat as Yt, createHwAccelCache as Z, storageOccupancyCapability as Zt, DEFAULT_EVENTS_BAND_BUFFER_SEC as _, audioChunkBytesPerSample as _n, hfModelUrl as _t, BackgroundRunRegistry as a, Fmp4BoxSplitter as an, egressTranscodeSharingKey as at, EVENT_OWNER_TYPES as b, defineCustomActions as bn, loadContributionCapability as bt, CLIP_STILL_REASON_CODE_HEADER as c, invocationFromEncodeProfile as cn, evaluateZoneRules as ct, CLUSTER_MODEL_SCOPED_STEPS as d, DeviceType as dn, exportSubjectOf as dt, supportedRuntimes as en, defaultDeviceFor as et, COCO_80_LABELS as f, errMsg as fn, failureContributionCapability as ft, DEFAULT_DETAIL_CROP_CONVENTION as g, CamProfileSchema as gn, gifFromMp4Args as gt, DEFAULT_CLUSTER_STEP_SETTINGS as h, CAM_PROFILE_ORDER as hn, gifDeriveSpeed as ht, AUDIO_MACRO_LABELS as i, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as in, detectionPipelineCapability as it, RATE_CONTROL_RELAXED as j, _enum as jn, parseProcStatus as jt, OpsLogEntrySchema as k, selectAssignedProfileSlots as kn, motionDetectionCapability as kt, CLIP_STILL_REASON_HEADER as l, isSoftwareDecode as ln, evictionPolicyForMode as lt, DEFAULT_AUDIO_ANALYZER_CONFIG as m, BaseAddon as mn, gbToBytes as mt, APPLE_SA_TO_MACRO as n, webrtcSessionCapability as nn, deriveDetailCropRect as nt, BatteryStatusSchema as o, buildFfmpegArgs as on, egressTransportFromRequest as ot, COCO_TO_MACRO as p, BOOT_RECOVERY_BACKOFF_MS as pn, ffmpegRate as pt, cameraOwnsMotionViaSensor as q, resolveRecordingProfiles as qt, AUDIO_BACKEND_CHOICES as r, AUDIO_PRESETS as rn, deriveRecordingMode as rt, CLIP_BROKER_PACED_RATES as s, evaluateSensorEdge as sn, enumerateInferenceDevices as st, APPEARANCE_BLOCKS as t, videoclipsCapability as tn, deriveBatteryPresence as tt, CLIP_STREAM_TRANSPORT_HEADER as u, DeviceFeature as un, evictionPolicyOfLocation as ut, DEFAULT_NATIVE_LEASE_SETTINGS as v, createEvent as vn, inferModelProvider as vt, FailureCounters as w, makeProfileBrokerId as wn, mayReadLocation as wt, EVENT_PAD_MS as x, expandAudioChunkToF32le as xn, logChannelsCapability as xt, DEVICE_BACKEND_TO_FORMAT as y, customAction as yn, isFirstLevelMacroClass as yt, VIDEOCLIPS_MAX_OFFER_BYTES as z, preprocess as zn, recordingCapability as zt };