@camstack/addon-pipeline 1.2.243 → 1.2.245

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 (33) 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-Bq_xdwWw.js → default-detection-model-DLFtoi4W.js} +1 -1
  4. package/dist/{default-detection-model-IKNS25_s.mjs → default-detection-model-UXQCoRj_.mjs} +1 -1
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-Zw3eICiX.js → dist-CWWQf3ci.js} +117 -2
  8. package/dist/{dist-CswFZdi6.mjs → dist-CoZwNgzu.mjs} +117 -2
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-BAzE1jef.js → node-DLZWItaN.js} +1 -1
  12. package/dist/{node-0m0RkbvB.mjs → node-Uh59Eo57.mjs} +1 -1
  13. package/dist/pipeline-runner/index.js +63 -3
  14. package/dist/pipeline-runner/index.mjs +63 -3
  15. package/dist/{process-memory-BcqRS5L_.mjs → process-memory-BnFnR_nP.mjs} +1 -1
  16. package/dist/{process-memory-BkGgkl4T.js → process-memory-Bv9SiLn-.js} +1 -1
  17. package/dist/recorder/index.js +2 -2
  18. package/dist/recorder/index.mjs +2 -2
  19. package/dist/{segment-demux-js-AQvsdVSO.mjs → segment-demux-js-7DukFIT6.mjs} +1 -1
  20. package/dist/{segment-demux-js-mwoA6eC7.js → segment-demux-js-C6B53KjT.js} +1 -1
  21. package/dist/stream-broker/_stub.js +2 -2
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Chu9oUjF.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B20FCUk4.mjs} +3 -3
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DVqDp5VD.mjs +26 -0
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CJunbWSo.mjs +26 -0
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-BVmX2y-u.mjs → hostInit-DCTAdB0n.mjs} +3 -3
  28. package/dist/stream-broker/index.js +501 -47
  29. package/dist/stream-broker/index.mjs +501 -47
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/package.json +2 -2
  32. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-aawWFyGL.mjs +0 -26
  33. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C3P2fV1x.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-Zw3eICiX.js");
7
- const require_process_memory = require("../process-memory-BkGgkl4T.js");
6
+ const require_dist = require("../dist-CWWQf3ci.js");
7
+ const require_process_memory = require("../process-memory-Bv9SiLn-.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 { $t as hydrateSchema, Jt as audioChunkBytesPerSample, Lt as errMsg, N as audioAnalysisCapability, Ot as resolvePoolMemoryPolicy, P as audioAnalyzerCapability, Qt as expandAudioChunkToF32le, Wt as BaseAddon, bn as EventCategory, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, rn as nodePin, s as DEFAULT_AUDIO_ANALYZER_CONFIG, w as PoolMemoryWatchdog, y as HF_BASE_URL } from "../dist-CswFZdi6.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BcqRS5L_.mjs";
2
+ import { $t as hydrateSchema, Jt as audioChunkBytesPerSample, Lt as errMsg, N as audioAnalysisCapability, Ot as resolvePoolMemoryPolicy, P as audioAnalyzerCapability, Qt as expandAudioChunkToF32le, Wt as BaseAddon, bn as EventCategory, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, rn as nodePin, s as DEFAULT_AUDIO_ANALYZER_CONFIG, w as PoolMemoryWatchdog, y as HF_BASE_URL } from "../dist-CoZwNgzu.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BnFnR_nP.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
- const require_dist = require("./dist-Zw3eICiX.js");
1
+ const require_dist = require("./dist-CWWQf3ci.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-CswFZdi6.mjs";
1
+ import { F as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-CoZwNgzu.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -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-Zw3eICiX.js");
7
- const require_node = require("../node-BAzE1jef.js");
8
- const require_default_detection_model = require("../default-detection-model-Bq_xdwWw.js");
6
+ const require_dist = require("../dist-CWWQf3ci.js");
7
+ const require_node = require("../node-DLZWItaN.js");
8
+ const require_default_detection_model = require("../default-detection-model-DLFtoi4W.js");
9
9
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
10
- const require_process_memory = require("../process-memory-BkGgkl4T.js");
10
+ const require_process_memory = require("../process-memory-Bv9SiLn-.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 { $t as hydrateSchema, At as runtimeDevices$1, Ft as supportedRuntimes$1, G as detectionPipelineCapability, J as enumerateInferenceDevices, Lt as errMsg, Ot as resolvePoolMemoryPolicy, Tt as resolveClusterStepModelId, V as defaultDeviceFor$1, Wt as BaseAddon, X as evaluateZoneRules, Yt as createEvent, bn as EventCategory, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as object, ht as pickClusterStepModels, in as parseJsonUnknown, it as loadContributionCapability, j as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, ln as array, m as DEVICE_BACKEND_TO_FORMAT, nt as inferModelProvider, pt as overlayClusterStepSettings, rn as nodePin, sn as sleep, t as APPLE_SA_TO_MACRO, vn as string, w as PoolMemoryWatchdog, yn as union, yt as pipelineExecutorCapability } from "../dist-CswFZdi6.mjs";
3
- import { o as readProcessCost } from "../node-0m0RkbvB.mjs";
4
- import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-IKNS25_s.mjs";
2
+ import { $t as hydrateSchema, At as runtimeDevices$1, Ft as supportedRuntimes$1, G as detectionPipelineCapability, J as enumerateInferenceDevices, Lt as errMsg, Ot as resolvePoolMemoryPolicy, Tt as resolveClusterStepModelId, V as defaultDeviceFor$1, Wt as BaseAddon, X as evaluateZoneRules, Yt as createEvent, bn as EventCategory, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as object, ht as pickClusterStepModels, in as parseJsonUnknown, it as loadContributionCapability, j as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, ln as array, m as DEVICE_BACKEND_TO_FORMAT, nt as inferModelProvider, pt as overlayClusterStepSettings, rn as nodePin, sn as sleep, t as APPLE_SA_TO_MACRO, vn as string, w as PoolMemoryWatchdog, yn as union, yt as pipelineExecutorCapability } from "../dist-CoZwNgzu.mjs";
3
+ import { o as readProcessCost } from "../node-Uh59Eo57.mjs";
4
+ import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-UXQCoRj_.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BcqRS5L_.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BnFnR_nP.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";
@@ -5360,7 +5360,7 @@ var ZodIssueCode = {
5360
5360
  var ZodFirstPartyTypeKind;
5361
5361
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5362
5362
  //#endregion
5363
- //#region ../types/dist/sleep-BfJ2k1jm.mjs
5363
+ //#region ../types/dist/sleep-BDR76Ykr.mjs
5364
5364
  /**
5365
5365
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5366
5366
  * window to float samples (D455).
@@ -20514,6 +20514,48 @@ var NcAlarmConfigSchema = object({
20514
20514
  settings: NcAlarmSettingsSchema,
20515
20515
  coverage: array(NcAlarmModeCoverageSchema)
20516
20516
  });
20517
+ /**
20518
+ * ONE rule's demand on ONE camera's clip ring.
20519
+ *
20520
+ * A rule, not a camera: the broker takes the MAX over the asks that reach a
20521
+ * camera, so the answer stays a faithful description of the rules and the
20522
+ * bounding (the byte budget, the broker's own ceiling) stays where the cost
20523
+ * lives. A camera that appears in no ask is being told **nothing** — which is
20524
+ * a different thing from never having been told, and only the envelope
20525
+ * (`rulesLoaded`) can tell those apart.
20526
+ */
20527
+ var NcClipRetentionAskSchema = object({
20528
+ /**
20529
+ * The camera this ask is about. **Absent = every camera**, which is what a
20530
+ * rule with no `conditions.devices` means: it can fire anywhere, so it is
20531
+ * asking everywhere.
20532
+ */
20533
+ deviceId: number().int().nonnegative().optional(),
20534
+ /** Seconds of history the rule needs held for it. Never zero — a rule that
20535
+ * needs nothing produces no ask at all. */
20536
+ seconds: number().min(0).max(60),
20537
+ /** The profile the rule cuts from, when it named one. Absent = the cheapest
20538
+ * assigned, which is what the cut defaults to. */
20539
+ profile: CamProfileSchema.optional(),
20540
+ /** Who is asking — so a retention the operator did not expect names a rule. */
20541
+ ruleId: string(),
20542
+ ruleName: string(),
20543
+ /** Why this many seconds: the rule's own window, or the occupancy ceiling. */
20544
+ reason: _enum(["window", "occupancy"])
20545
+ });
20546
+ /**
20547
+ * The whole answer, with the one bit that keeps absence from reading as zero.
20548
+ *
20549
+ * `rulesLoaded` is false until the rule ledger has completed a load at least
20550
+ * once. A centre that is up but has not read its rules yet answers with an
20551
+ * empty ask list that means nothing at all — applying it would drop every
20552
+ * camera's ring to zero for the first events after a restart, which is the
20553
+ * footage this mechanism exists to keep.
20554
+ */
20555
+ var NcClipRetentionPlanSchema = object({
20556
+ rulesLoaded: boolean(),
20557
+ asks: array(NcClipRetentionAskSchema).readonly()
20558
+ });
20517
20559
  method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), method(object({ ruleId: string() }), object({ rule: NcRuleSchema.nullable() }), { auth: "admin" }), method(object({ rule: NcRuleInputSchema }), object({ rule: NcRuleSchema }), {
20518
20560
  kind: "mutation",
20519
20561
  auth: "admin",
@@ -20534,7 +20576,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20534
20576
  }), object({ success: literal(true) }), {
20535
20577
  kind: "mutation",
20536
20578
  auth: "admin"
20537
- }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
20579
+ }), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
20538
20580
  deviceId: number().int(),
20539
20581
  muted: boolean()
20540
20582
  }), object({ success: literal(true) }), {
@@ -24333,6 +24375,18 @@ var RunnerLocalMetricsSchema = object({
24333
24375
  * runner has zero knowledge of other agents, no global state, and never
24334
24376
  * makes assignment decisions itself.
24335
24377
  */
24378
+ /**
24379
+ * Why a runner declined to look at a camera out of band. Named rather than a
24380
+ * bare `false`: a camera asleep on battery (D173), one attached elsewhere, one
24381
+ * already mid-session and one already bursting are four different facts, and a
24382
+ * caller told only "no" cannot tell a protection from a bug.
24383
+ */
24384
+ var OccupancyBurstRefusalSchema = _enum([
24385
+ "not-attached",
24386
+ "battery-asleep",
24387
+ "not-watching",
24388
+ "already-bursting"
24389
+ ]);
24336
24390
  var pipelineRunnerCapability = {
24337
24391
  name: "pipeline-runner",
24338
24392
  scope: "system",
@@ -24369,6 +24423,50 @@ var pipelineRunnerCapability = {
24369
24423
  /** List the deviceIds currently attached to this runner. */
24370
24424
  getLocalCameras: method(_void(), array(number()).readonly()),
24371
24425
  /**
24426
+ * Look at a camera NOW, out of band, because something just happened that
24427
+ * only a fresh look can settle.
24428
+ *
24429
+ * The periodic recheck (`occupancyRecheckSec`, 300 s) exists to watch a
24430
+ * still scene. It is the wrong instrument for a QUESTION that has just been
24431
+ * asked: on device 617 a parked car's departure was observed, a departure
24432
+ * strike was armed — and then the motion session ended, the strike decayed
24433
+ * after its 30 s TTL, and the next periodic look arrived up to five minutes
24434
+ * later with nothing left to confirm. Every one of those departures was
24435
+ * settled by the entry ageing out 6 to 10 minutes of observed time later,
24436
+ * and the notification's clip showed an empty space with nothing leaving
24437
+ * it.
24438
+ *
24439
+ * Two numbers make the ask specific, and a caller that ignores them wastes
24440
+ * the burst: a confirmation must land at least
24441
+ * `DEPARTURE_CONFIRM_MIN_GAP_MS` (3 s) after the read that armed the
24442
+ * strike — before that it is the same optical event and is refused — and
24443
+ * `DEPARTURE_ABSENCE_MIN_READS` (5) consecutive unassociated frames are
24444
+ * needed, while `occupancyRecheckFrames` defaults to FOUR. A burst of four
24445
+ * can never confirm an absence; that is why two periodic looks were always
24446
+ * required.
24447
+ *
24448
+ * The runner answers whether it actually started one. A refusal is NAMED,
24449
+ * never a silent `false`: a camera that is asleep on battery (D173 — this
24450
+ * must not become a self-initiated wake), detached, mid-session or already
24451
+ * bursting are four different facts, and a caller told only "no" cannot
24452
+ * tell a protection from a bug.
24453
+ */
24454
+ requestOccupancyBurst: method(object({
24455
+ deviceId: number(),
24456
+ /** How many frames to collect. The caller sizes this against what its
24457
+ * own confirmation needs; the runner clamps it to the field's range. */
24458
+ frames: number().int().positive().optional(),
24459
+ /** Why, for the log. A burst nobody can attribute is a cost nobody can
24460
+ * defend — the periodic one at least has a timer to point at. */
24461
+ reason: string()
24462
+ }), object({
24463
+ started: boolean(),
24464
+ refusedBecause: OccupancyBurstRefusalSchema.optional()
24465
+ }), {
24466
+ auth: "admin",
24467
+ kind: "mutation"
24468
+ }),
24469
+ /**
24372
24470
  * Best-effort NATIVE-resolution crop of a retention-ring frame. Given the
24373
24471
  * `FrameHandle` that rode an inference-result event and a normalized `bbox`,
24374
24472
  * the runner asks the decode worker still holding that frame's NATIVE
@@ -37699,6 +37797,12 @@ Object.freeze({
37699
37797
  addonId: null,
37700
37798
  access: "view"
37701
37799
  },
37800
+ "notificationRules.getClipRetentionAsks": {
37801
+ capName: "notification-rules",
37802
+ capScope: "system",
37803
+ addonId: null,
37804
+ access: "view"
37805
+ },
37702
37806
  "notificationRules.getConditionCatalog": {
37703
37807
  capName: "notification-rules",
37704
37808
  capScope: "system",
@@ -38887,6 +38991,12 @@ Object.freeze({
38887
38991
  addonId: null,
38888
38992
  access: "create"
38889
38993
  },
38994
+ "pipelineRunner.requestOccupancyBurst": {
38995
+ capName: "pipeline-runner",
38996
+ capScope: "system",
38997
+ addonId: null,
38998
+ access: "create"
38999
+ },
38890
39000
  "pipelineRunner.runDetailSubtree": {
38891
39001
  capName: "pipeline-runner",
38892
39002
  capScope: "system",
@@ -42226,6 +42336,11 @@ Object.freeze({
42226
42336
  form: "single",
42227
42337
  optional: false
42228
42338
  }],
42339
+ "pipelineRunner.requestOccupancyBurst": [{
42340
+ name: "deviceId",
42341
+ form: "single",
42342
+ optional: false
42343
+ }],
42229
42344
  "pipelineRunner.runDetailSubtree": [{
42230
42345
  name: "deviceId",
42231
42346
  form: "single",
@@ -5360,7 +5360,7 @@ var ZodIssueCode = {
5360
5360
  var ZodFirstPartyTypeKind;
5361
5361
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5362
5362
  //#endregion
5363
- //#region ../types/dist/sleep-BfJ2k1jm.mjs
5363
+ //#region ../types/dist/sleep-BDR76Ykr.mjs
5364
5364
  /**
5365
5365
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5366
5366
  * window to float samples (D455).
@@ -20514,6 +20514,48 @@ var NcAlarmConfigSchema = object({
20514
20514
  settings: NcAlarmSettingsSchema,
20515
20515
  coverage: array(NcAlarmModeCoverageSchema)
20516
20516
  });
20517
+ /**
20518
+ * ONE rule's demand on ONE camera's clip ring.
20519
+ *
20520
+ * A rule, not a camera: the broker takes the MAX over the asks that reach a
20521
+ * camera, so the answer stays a faithful description of the rules and the
20522
+ * bounding (the byte budget, the broker's own ceiling) stays where the cost
20523
+ * lives. A camera that appears in no ask is being told **nothing** — which is
20524
+ * a different thing from never having been told, and only the envelope
20525
+ * (`rulesLoaded`) can tell those apart.
20526
+ */
20527
+ var NcClipRetentionAskSchema = object({
20528
+ /**
20529
+ * The camera this ask is about. **Absent = every camera**, which is what a
20530
+ * rule with no `conditions.devices` means: it can fire anywhere, so it is
20531
+ * asking everywhere.
20532
+ */
20533
+ deviceId: number().int().nonnegative().optional(),
20534
+ /** Seconds of history the rule needs held for it. Never zero — a rule that
20535
+ * needs nothing produces no ask at all. */
20536
+ seconds: number().min(0).max(60),
20537
+ /** The profile the rule cuts from, when it named one. Absent = the cheapest
20538
+ * assigned, which is what the cut defaults to. */
20539
+ profile: CamProfileSchema.optional(),
20540
+ /** Who is asking — so a retention the operator did not expect names a rule. */
20541
+ ruleId: string(),
20542
+ ruleName: string(),
20543
+ /** Why this many seconds: the rule's own window, or the occupancy ceiling. */
20544
+ reason: _enum(["window", "occupancy"])
20545
+ });
20546
+ /**
20547
+ * The whole answer, with the one bit that keeps absence from reading as zero.
20548
+ *
20549
+ * `rulesLoaded` is false until the rule ledger has completed a load at least
20550
+ * once. A centre that is up but has not read its rules yet answers with an
20551
+ * empty ask list that means nothing at all — applying it would drop every
20552
+ * camera's ring to zero for the first events after a restart, which is the
20553
+ * footage this mechanism exists to keep.
20554
+ */
20555
+ var NcClipRetentionPlanSchema = object({
20556
+ rulesLoaded: boolean(),
20557
+ asks: array(NcClipRetentionAskSchema).readonly()
20558
+ });
20517
20559
  method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), method(object({ ruleId: string() }), object({ rule: NcRuleSchema.nullable() }), { auth: "admin" }), method(object({ rule: NcRuleInputSchema }), object({ rule: NcRuleSchema }), {
20518
20560
  kind: "mutation",
20519
20561
  auth: "admin",
@@ -20534,7 +20576,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
20534
20576
  }), object({ success: literal(true) }), {
20535
20577
  kind: "mutation",
20536
20578
  auth: "admin"
20537
- }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
20579
+ }), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
20538
20580
  deviceId: number().int(),
20539
20581
  muted: boolean()
20540
20582
  }), object({ success: literal(true) }), {
@@ -24333,6 +24375,18 @@ var RunnerLocalMetricsSchema = object({
24333
24375
  * runner has zero knowledge of other agents, no global state, and never
24334
24376
  * makes assignment decisions itself.
24335
24377
  */
24378
+ /**
24379
+ * Why a runner declined to look at a camera out of band. Named rather than a
24380
+ * bare `false`: a camera asleep on battery (D173), one attached elsewhere, one
24381
+ * already mid-session and one already bursting are four different facts, and a
24382
+ * caller told only "no" cannot tell a protection from a bug.
24383
+ */
24384
+ var OccupancyBurstRefusalSchema = _enum([
24385
+ "not-attached",
24386
+ "battery-asleep",
24387
+ "not-watching",
24388
+ "already-bursting"
24389
+ ]);
24336
24390
  var pipelineRunnerCapability = {
24337
24391
  name: "pipeline-runner",
24338
24392
  scope: "system",
@@ -24369,6 +24423,50 @@ var pipelineRunnerCapability = {
24369
24423
  /** List the deviceIds currently attached to this runner. */
24370
24424
  getLocalCameras: method(_void(), array(number()).readonly()),
24371
24425
  /**
24426
+ * Look at a camera NOW, out of band, because something just happened that
24427
+ * only a fresh look can settle.
24428
+ *
24429
+ * The periodic recheck (`occupancyRecheckSec`, 300 s) exists to watch a
24430
+ * still scene. It is the wrong instrument for a QUESTION that has just been
24431
+ * asked: on device 617 a parked car's departure was observed, a departure
24432
+ * strike was armed — and then the motion session ended, the strike decayed
24433
+ * after its 30 s TTL, and the next periodic look arrived up to five minutes
24434
+ * later with nothing left to confirm. Every one of those departures was
24435
+ * settled by the entry ageing out 6 to 10 minutes of observed time later,
24436
+ * and the notification's clip showed an empty space with nothing leaving
24437
+ * it.
24438
+ *
24439
+ * Two numbers make the ask specific, and a caller that ignores them wastes
24440
+ * the burst: a confirmation must land at least
24441
+ * `DEPARTURE_CONFIRM_MIN_GAP_MS` (3 s) after the read that armed the
24442
+ * strike — before that it is the same optical event and is refused — and
24443
+ * `DEPARTURE_ABSENCE_MIN_READS` (5) consecutive unassociated frames are
24444
+ * needed, while `occupancyRecheckFrames` defaults to FOUR. A burst of four
24445
+ * can never confirm an absence; that is why two periodic looks were always
24446
+ * required.
24447
+ *
24448
+ * The runner answers whether it actually started one. A refusal is NAMED,
24449
+ * never a silent `false`: a camera that is asleep on battery (D173 — this
24450
+ * must not become a self-initiated wake), detached, mid-session or already
24451
+ * bursting are four different facts, and a caller told only "no" cannot
24452
+ * tell a protection from a bug.
24453
+ */
24454
+ requestOccupancyBurst: method(object({
24455
+ deviceId: number(),
24456
+ /** How many frames to collect. The caller sizes this against what its
24457
+ * own confirmation needs; the runner clamps it to the field's range. */
24458
+ frames: number().int().positive().optional(),
24459
+ /** Why, for the log. A burst nobody can attribute is a cost nobody can
24460
+ * defend — the periodic one at least has a timer to point at. */
24461
+ reason: string()
24462
+ }), object({
24463
+ started: boolean(),
24464
+ refusedBecause: OccupancyBurstRefusalSchema.optional()
24465
+ }), {
24466
+ auth: "admin",
24467
+ kind: "mutation"
24468
+ }),
24469
+ /**
24372
24470
  * Best-effort NATIVE-resolution crop of a retention-ring frame. Given the
24373
24471
  * `FrameHandle` that rode an inference-result event and a normalized `bbox`,
24374
24472
  * the runner asks the decode worker still holding that frame's NATIVE
@@ -37699,6 +37797,12 @@ Object.freeze({
37699
37797
  addonId: null,
37700
37798
  access: "view"
37701
37799
  },
37800
+ "notificationRules.getClipRetentionAsks": {
37801
+ capName: "notification-rules",
37802
+ capScope: "system",
37803
+ addonId: null,
37804
+ access: "view"
37805
+ },
37702
37806
  "notificationRules.getConditionCatalog": {
37703
37807
  capName: "notification-rules",
37704
37808
  capScope: "system",
@@ -38887,6 +38991,12 @@ Object.freeze({
38887
38991
  addonId: null,
38888
38992
  access: "create"
38889
38993
  },
38994
+ "pipelineRunner.requestOccupancyBurst": {
38995
+ capName: "pipeline-runner",
38996
+ capScope: "system",
38997
+ addonId: null,
38998
+ access: "create"
38999
+ },
38890
39000
  "pipelineRunner.runDetailSubtree": {
38891
39001
  capName: "pipeline-runner",
38892
39002
  capScope: "system",
@@ -42226,6 +42336,11 @@ Object.freeze({
42226
42336
  form: "single",
42227
42337
  optional: false
42228
42338
  }],
42339
+ "pipelineRunner.requestOccupancyBurst": [{
42340
+ name: "deviceId",
42341
+ form: "single",
42342
+ optional: false
42343
+ }],
42229
42344
  "pipelineRunner.runDetailSubtree": [{
42230
42345
  name: "deviceId",
42231
42346
  form: "single",
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-Zw3eICiX.js");
5
+ const require_dist = require("../dist-CWWQf3ci.js");
6
6
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { $t as hydrateSchema, Wt as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability, qt as DeviceType } from "../dist-CswFZdi6.mjs";
1
+ import { $t as hydrateSchema, Wt as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability, qt as DeviceType } from "../dist-CoZwNgzu.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-Zw3eICiX.js");
2
+ const require_dist = require("./dist-CWWQf3ci.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_fs = require("node:fs");
5
5
  node_fs = require_chunk.__toESM(node_fs, 1);
@@ -1,4 +1,4 @@
1
- import { Bt as buildFfmpegArgs, Ht as isSoftwareDecode, Lt as errMsg, zt as Fmp4BoxSplitter } from "./dist-CswFZdi6.mjs";
1
+ import { Bt as buildFfmpegArgs, Ht as isSoftwareDecode, Lt as errMsg, zt as Fmp4BoxSplitter } from "./dist-CoZwNgzu.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { realpathSync } from "node:fs";
4
4
  import path from "node:path";
@@ -3,9 +3,9 @@ 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-Zw3eICiX.js");
7
- const require_node = require("../node-BAzE1jef.js");
8
- const require_default_detection_model = require("../default-detection-model-Bq_xdwWw.js");
6
+ const require_dist = require("../dist-CWWQf3ci.js");
7
+ const require_node = require("../node-DLZWItaN.js");
8
+ const require_default_detection_model = require("../default-detection-model-DLFtoi4W.js");
9
9
  const require_worker_protocol = require("../worker-protocol-B2MfQLlu.js");
10
10
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
11
11
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
@@ -9627,6 +9627,66 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
9627
9627
  return [...this.attached.keys()];
9628
9628
  }
9629
9629
  /**
9630
+ * Look at one camera NOW, out of band — see the cap docblock for why the
9631
+ * periodic recheck cannot serve a question that was just asked.
9632
+ *
9633
+ * Every refusal is NAMED. The battery gate is the one that matters most: a
9634
+ * sleeping camera must not be woken by a burst (D173), and a caller told only
9635
+ * "no" cannot tell that protection from a bug.
9636
+ */
9637
+ requestOccupancyBurst(input) {
9638
+ const { deviceId } = input;
9639
+ const log = this.ctx.logger.child("occupancy-burst");
9640
+ if (!this.attached.has(deviceId)) {
9641
+ log.debug("out-of-band burst refused — camera not attached here", {
9642
+ tags: { deviceId },
9643
+ meta: { reason: input.reason }
9644
+ });
9645
+ return {
9646
+ started: false,
9647
+ refusedBecause: "not-attached"
9648
+ };
9649
+ }
9650
+ if (this.sleepingBatteryDevices.has(deviceId)) {
9651
+ log.debug("out-of-band burst refused — battery camera is sleeping", {
9652
+ tags: { deviceId },
9653
+ meta: { reason: input.reason }
9654
+ });
9655
+ return {
9656
+ started: false,
9657
+ refusedBecause: "battery-asleep"
9658
+ };
9659
+ }
9660
+ const phase = this.runner?.getPhase(deviceId);
9661
+ if (phase !== "watching") {
9662
+ log.debug("out-of-band burst refused — the camera is not watching", {
9663
+ tags: { deviceId },
9664
+ meta: {
9665
+ reason: input.reason,
9666
+ phase
9667
+ }
9668
+ });
9669
+ return {
9670
+ started: false,
9671
+ refusedBecause: "not-watching"
9672
+ };
9673
+ }
9674
+ if (this.occupancyBurstInFlight.has(deviceId) || this.occupancyQueued.has(deviceId)) return {
9675
+ started: false,
9676
+ refusedBecause: "already-bursting"
9677
+ };
9678
+ const frames = Math.max(1, Math.min(input.frames ?? 4, 10));
9679
+ log.info("out-of-band occupancy burst", {
9680
+ tags: { deviceId },
9681
+ meta: {
9682
+ reason: input.reason,
9683
+ frames
9684
+ }
9685
+ });
9686
+ this.enqueueOccupancyBurst(deviceId, frames);
9687
+ return { started: true };
9688
+ }
9689
+ /**
9630
9690
  * Thin delegator to the module-level {@link acquireSessionDecodeRestreamFrom}
9631
9691
  * (see its doc for the acquire behavior) — supplies this addon's `ctx.logger`.
9632
9692
  * Kept as a method so the two call sites need no change.
@@ -1,6 +1,6 @@
1
- import { $ as failureContributionCapability, Lt as errMsg, S as NativeLeaseSettingsSchema, U as deriveDetailCropRect, Wt as BaseAddon, Xt as customAction, Yt as createEvent, Zt as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, b as MOTION_CLOSE_AFTER_MS, bn as EventCategory, bt as pipelineRunnerCapability, cn as _enum, fn as lazy, hn as object, it as loadContributionCapability, ln as array, m as DEVICE_BACKEND_TO_FORMAT, mn as number, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as literal, rn as nodePin, u as DEFAULT_DETAIL_CROP_CONVENTION, un as boolean, vn as string, vt as pickNativeLeaseOverride, x as NativeLeaseAdmissionSchema } from "../dist-CswFZdi6.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-0m0RkbvB.mjs";
3
- import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-IKNS25_s.mjs";
1
+ import { $ as failureContributionCapability, Lt as errMsg, S as NativeLeaseSettingsSchema, U as deriveDetailCropRect, Wt as BaseAddon, Xt as customAction, Yt as createEvent, Zt as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, b as MOTION_CLOSE_AFTER_MS, bn as EventCategory, bt as pipelineRunnerCapability, cn as _enum, fn as lazy, hn as object, it as loadContributionCapability, ln as array, m as DEVICE_BACKEND_TO_FORMAT, mn as number, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as literal, rn as nodePin, u as DEFAULT_DETAIL_CROP_CONVENTION, un as boolean, vn as string, vt as pickNativeLeaseOverride, x as NativeLeaseAdmissionSchema } from "../dist-CoZwNgzu.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-Uh59Eo57.mjs";
3
+ import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-UXQCoRj_.mjs";
4
4
  import { t as isWorkerReply } from "../worker-protocol-C_W-P_g-.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
@@ -9619,6 +9619,66 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
9619
9619
  return [...this.attached.keys()];
9620
9620
  }
9621
9621
  /**
9622
+ * Look at one camera NOW, out of band — see the cap docblock for why the
9623
+ * periodic recheck cannot serve a question that was just asked.
9624
+ *
9625
+ * Every refusal is NAMED. The battery gate is the one that matters most: a
9626
+ * sleeping camera must not be woken by a burst (D173), and a caller told only
9627
+ * "no" cannot tell that protection from a bug.
9628
+ */
9629
+ requestOccupancyBurst(input) {
9630
+ const { deviceId } = input;
9631
+ const log = this.ctx.logger.child("occupancy-burst");
9632
+ if (!this.attached.has(deviceId)) {
9633
+ log.debug("out-of-band burst refused — camera not attached here", {
9634
+ tags: { deviceId },
9635
+ meta: { reason: input.reason }
9636
+ });
9637
+ return {
9638
+ started: false,
9639
+ refusedBecause: "not-attached"
9640
+ };
9641
+ }
9642
+ if (this.sleepingBatteryDevices.has(deviceId)) {
9643
+ log.debug("out-of-band burst refused — battery camera is sleeping", {
9644
+ tags: { deviceId },
9645
+ meta: { reason: input.reason }
9646
+ });
9647
+ return {
9648
+ started: false,
9649
+ refusedBecause: "battery-asleep"
9650
+ };
9651
+ }
9652
+ const phase = this.runner?.getPhase(deviceId);
9653
+ if (phase !== "watching") {
9654
+ log.debug("out-of-band burst refused — the camera is not watching", {
9655
+ tags: { deviceId },
9656
+ meta: {
9657
+ reason: input.reason,
9658
+ phase
9659
+ }
9660
+ });
9661
+ return {
9662
+ started: false,
9663
+ refusedBecause: "not-watching"
9664
+ };
9665
+ }
9666
+ if (this.occupancyBurstInFlight.has(deviceId) || this.occupancyQueued.has(deviceId)) return {
9667
+ started: false,
9668
+ refusedBecause: "already-bursting"
9669
+ };
9670
+ const frames = Math.max(1, Math.min(input.frames ?? 4, 10));
9671
+ log.info("out-of-band occupancy burst", {
9672
+ tags: { deviceId },
9673
+ meta: {
9674
+ reason: input.reason,
9675
+ frames
9676
+ }
9677
+ });
9678
+ this.enqueueOccupancyBurst(deviceId, frames);
9679
+ return { started: true };
9680
+ }
9681
+ /**
9622
9682
  * Thin delegator to the module-level {@link acquireSessionDecodeRestreamFrom}
9623
9683
  * (see its doc for the acquire behavior) — supplies this addon's `ctx.logger`.
9624
9684
  * Kept as a method so the two call sites need no change.
@@ -1,4 +1,4 @@
1
- import { mt as parseProcStatus } from "./dist-CswFZdi6.mjs";
1
+ import { mt as parseProcStatus } from "./dist-CoZwNgzu.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  //#region src/shared/node-topology-platform.ts
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-Zw3eICiX.js");
2
+ const require_dist = require("./dist-CWWQf3ci.js");
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_chunk.__toESM(node_fs);
5
5
  let node_child_process = require("node:child_process");
@@ -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-Zw3eICiX.js");
7
- const require_node = require("../node-BAzE1jef.js");
6
+ const require_dist = require("../dist-CWWQf3ci.js");
7
+ const require_node = require("../node-DLZWItaN.js");
8
8
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
9
9
  const require_restream_intent = require("../restream-intent-C4adO0P8.js");
10
10
  const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
@@ -1,5 +1,5 @@
1
- import { $t as hydrateSchema, C as OpsLogEntrySchema, Ct as recordingExportCapability, D as RECORDING_EXPORT_MAX_READ_BYTES, Dt as resolveLocationMode, H as deriveBatteryPresence, I as batteryCapability, Kt as DeviceFeature, Lt as errMsg, Mt as storageOccupancyCapability, O as RecordingConfigSchema, Pt as stripRetiredBandPreBufferSec, Q as evictionPolicyOfLocation, St as recordingCapability, W as deriveRecordingMode, Wt as BaseAddon, Xt as customAction, Y as evaluateSensorEdge, Z as evictionPolicyForMode, Zt as defineCustomActions, _n as record, bn as EventCategory, cn as _enum, ct as mayReadLocation, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, dt as modeMayWrite, et as gbToBytes, g as ExportRecordSchema, gn as preprocess, hn as object, i as BatteryStatusSchema, it as loadContributionCapability, jt as storageEvictableCapability, k as RecordingSignalStatusSchema, kt as resolveRecordingProfiles, ln as array, lt as mayWriteToLocation, mn as number, on as selectAssignedProfileSlots, qt as DeviceType, rn as nodePin, rt as isFirstLevelMacroClass, sn as sleep$1, un as boolean, ut as migrateLegacyDeviceSignalConfig, vn as string, wt as recordingSignalCapability } from "../dist-CswFZdi6.mjs";
2
- import { a as physicalRootOf, i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-0m0RkbvB.mjs";
1
+ import { $t as hydrateSchema, C as OpsLogEntrySchema, Ct as recordingExportCapability, D as RECORDING_EXPORT_MAX_READ_BYTES, Dt as resolveLocationMode, H as deriveBatteryPresence, I as batteryCapability, Kt as DeviceFeature, Lt as errMsg, Mt as storageOccupancyCapability, O as RecordingConfigSchema, Pt as stripRetiredBandPreBufferSec, Q as evictionPolicyOfLocation, St as recordingCapability, W as deriveRecordingMode, Wt as BaseAddon, Xt as customAction, Y as evaluateSensorEdge, Z as evictionPolicyForMode, Zt as defineCustomActions, _n as record, bn as EventCategory, cn as _enum, ct as mayReadLocation, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, dt as modeMayWrite, et as gbToBytes, g as ExportRecordSchema, gn as preprocess, hn as object, i as BatteryStatusSchema, it as loadContributionCapability, jt as storageEvictableCapability, k as RecordingSignalStatusSchema, kt as resolveRecordingProfiles, ln as array, lt as mayWriteToLocation, mn as number, on as selectAssignedProfileSlots, qt as DeviceType, rn as nodePin, rt as isFirstLevelMacroClass, sn as sleep$1, un as boolean, ut as migrateLegacyDeviceSignalConfig, vn as string, wt as recordingSignalCapability } from "../dist-CoZwNgzu.mjs";
2
+ import { a as physicalRootOf, i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-Uh59Eo57.mjs";
3
3
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
4
4
  import { c as PREBUFFER_MAX_MS, r as RECORDING_PRE_ROLL_REQUEST_MS, s as withRecordingIntent } from "../restream-intent-MeJhGCK9.mjs";
5
5
  import { n as RowMapStore, t as retireRootKeys } from "../retire-root-keys-DZvlso2l.mjs";