@camstack/addon-pipeline 1.2.197 → 1.2.199

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 (37) 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-CM-8U0Bb.js → default-detection-model-CMe44Kid.js} +1 -1
  4. package/dist/{default-detection-model-CplzzTmN.mjs → default-detection-model-O1uBusV2.mjs} +1 -1
  5. package/dist/detection-pipeline/index.js +5 -5
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-Y4BsF_EC.mjs → dist-B23u1tmN.mjs} +102 -38
  8. package/dist/{dist-CBa1j3On.js → dist-DmCrC2yx.js} +107 -37
  9. package/dist/{lazy-sharp-CS5WE9mI.js → lazy-sharp-DBHsD2lh.js} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-B5ouEQYN.mjs → node-D1MLn6oV.mjs} +1 -1
  13. package/dist/{node-C-B8VuGi.js → node-DCSTbt6C.js} +1 -1
  14. package/dist/pipeline-runner/index.js +5 -5
  15. package/dist/pipeline-runner/index.mjs +4 -4
  16. package/dist/{retire-root-keys-Csb8z2f3.js → prebuffer-DmBYRQWg.mjs} +64 -12
  17. package/dist/{retire-root-keys-DZvlso2l.mjs → prebuffer-DqdeLSsk.js} +99 -1
  18. package/dist/{process-memory-CmeKr_MZ.js → process-memory-9lvvhHym.js} +1 -1
  19. package/dist/{process-memory-DeO2OZ3-.mjs → process-memory-P24NTDb1.mjs} +1 -1
  20. package/dist/recorder/index.js +26 -18
  21. package/dist/recorder/index.mjs +22 -14
  22. package/dist/{segment-demux-js-DXPgq2cf.mjs → segment-demux-js-Bm0woPkn.mjs} +1 -1
  23. package/dist/{segment-demux-js-DiIsywGz.js → segment-demux-js-Ck_F5bsO.js} +1 -1
  24. package/dist/session-decode/decode-worker-child.js +2 -2
  25. package/dist/session-decode/decode-worker-child.mjs +1 -1
  26. package/dist/stream-broker/_stub.js +28 -31
  27. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Q-6HzWJ0.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Sq93hI-g.mjs} +3 -3
  28. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cv5McbTI.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BcjLrxhF.mjs} +1 -1
  29. package/dist/stream-broker/demux-worker-child.js +1 -1
  30. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  31. package/dist/stream-broker/{hostInit-C-2Eo_nr.mjs → hostInit-COt259tU.mjs} +3 -3
  32. package/dist/stream-broker/index.js +452 -541
  33. package/dist/stream-broker/index.mjs +448 -537
  34. package/dist/stream-broker/remoteEntry.js +1 -1
  35. package/dist/{worker-protocol-_7zrToTo.mjs → worker-protocol-BxpGZ0Dt.mjs} +1 -1
  36. package/dist/{worker-protocol-CXsdriRX.js → worker-protocol-c1r1Yddg.js} +1 -1
  37. package/package.json +1 -1
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-CBa1j3On.js");
6
- const require_process_memory = require("../process-memory-CmeKr_MZ.js");
5
+ const require_dist = require("../dist-DmCrC2yx.js");
6
+ const require_process_memory = require("../process-memory-9lvvhHym.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_dist.__toESM(node_fs);
9
9
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { Dt as errMsg, M as audioAnalyzerCapability, Pt as BaseAddon, S as PoolMemoryWatchdog, bt as resolvePoolMemoryPolicy, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, rt as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL, zt as hydrateSchema } from "../dist-Y4BsF_EC.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DeO2OZ3-.mjs";
2
+ import { Bt as hydrateSchema, Ft as BaseAddon, M as audioAnalyzerCapability, Ot as errMsg, S as PoolMemoryWatchdog, bt as resolvePoolMemoryPolicy, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, rt as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL } from "../dist-B23u1tmN.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-P24NTDb1.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-CBa1j3On.js");
1
+ const require_dist = require("./dist-DmCrC2yx.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -1,4 +1,4 @@
1
- import { N as audioKindId, Q as hfModelUrl, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-Y4BsF_EC.mjs";
1
+ import { N as audioKindId, Q as hfModelUrl, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-B23u1tmN.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-CBa1j3On.js");
6
- const require_node = require("../node-C-B8VuGi.js");
7
- const require_default_detection_model = require("../default-detection-model-CM-8U0Bb.js");
8
- const require_lazy_sharp = require("../lazy-sharp-CS5WE9mI.js");
5
+ const require_dist = require("../dist-DmCrC2yx.js");
6
+ const require_node = require("../node-DCSTbt6C.js");
7
+ const require_default_detection_model = require("../default-detection-model-CMe44Kid.js");
8
+ const require_lazy_sharp = require("../lazy-sharp-DBHsD2lh.js");
9
9
  const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
10
- const require_process_memory = require("../process-memory-CmeKr_MZ.js");
10
+ const require_process_memory = require("../process-memory-9lvvhHym.js");
11
11
  let node_os = require("node:os");
12
12
  node_os = require_dist.__toESM(node_os);
13
13
  let node_fs = require("node:fs");
@@ -1,10 +1,10 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as inferModelProvider, B as defaultDeviceFor$1, Dt as errMsg, G as detectionPipelineCapability, J as enumerateInferenceDevices, Pt as BaseAddon, Rt as createEvent, S as PoolMemoryWatchdog, St as runtimeDevices$1, Tt as supportedRuntimes$1, Ut as nodePin, Wt as parseJsonUnknown, X as evaluateZoneRules, Yt as array, an as union, bt as resolvePoolMemoryPolicy, c as DEFAULT_CLUSTER_STEP_MODELS, in as string, k as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, lt as pickClusterStepModels, m as DEVICE_BACKEND_TO_FORMAT, on as EventCategory, pt as pipelineExecutorCapability, qt as sleep, st as overlayClusterStepSettings, t as APPLE_SA_TO_MACRO, tn as object, tt as loadContributionCapability, ut as pickClusterStepSettings, vt as resolveClusterStepModelId, zt as hydrateSchema } from "../dist-Y4BsF_EC.mjs";
3
- import { a as readProcessCost } from "../node-B5ouEQYN.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-CplzzTmN.mjs";
2
+ import { $ as inferModelProvider, B as defaultDeviceFor$1, Bt as hydrateSchema, Et as supportedRuntimes$1, Ft as BaseAddon, G as detectionPipelineCapability, Gt as parseJsonUnknown, J as enumerateInferenceDevices, Jt as sleep, Ot as errMsg, S as PoolMemoryWatchdog, St as runtimeDevices$1, Wt as nodePin, X as evaluateZoneRules, Xt as array, an as string, bt as resolvePoolMemoryPolicy, c as DEFAULT_CLUSTER_STEP_MODELS, k as YAMNET_TO_MACRO, l as DEFAULT_CLUSTER_STEP_SETTINGS, lt as pickClusterStepModels, m as DEVICE_BACKEND_TO_FORMAT, nn as object, on as union, pt as pipelineExecutorCapability, sn as EventCategory, st as overlayClusterStepSettings, t as APPLE_SA_TO_MACRO, tt as loadContributionCapability, ut as pickClusterStepSettings, vt as resolveClusterStepModelId, zt as createEvent } from "../dist-B23u1tmN.mjs";
3
+ import { a as readProcessCost } from "../node-D1MLn6oV.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-O1uBusV2.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
6
  import { n as startEventLoopStallMonitor } from "../event-loop-stall-monitor-DXLNBMkY.mjs";
7
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-DeO2OZ3-.mjs";
7
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-P24NTDb1.mjs";
8
8
  import * as os from "node:os";
9
9
  import * as fs from "node:fs";
10
10
  import * as path$1 from "node:path";
@@ -9189,6 +9189,24 @@ var RecordingBandSchema = object({
9189
9189
  end: string().regex(HHMM),
9190
9190
  mode: RecordingBandModeSchema,
9191
9191
  triggers: RecordingBandTriggersSchema.optional(),
9192
+ /**
9193
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
9194
+ *
9195
+ * It was the retroactive KEEP bound — which already-written segments survive
9196
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
9197
+ * broker could serve, or the gate would delete the seconds the ring had just
9198
+ * handed the writer. That "at least as wide as" is the tell: it was a second
9199
+ * expression of the broker's retention, in different units, in a different
9200
+ * addon, with an invariant the operator had to maintain by hand. The keep
9201
+ * bound is now derived from the one prebuffer ceiling and there is nothing
9202
+ * left to configure here.
9203
+ *
9204
+ * The key survives in the SHAPE so a config written before that record still
9205
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
9206
+ * strict, so simply deleting it would strip an operator's value in silence on
9207
+ * the next save (the failure D380 came one commit from shipping). Nothing
9208
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
9209
+ */
9192
9210
  preBufferSec: number().min(0).optional(),
9193
9211
  postBufferSec: number().min(0).optional()
9194
9212
  });
@@ -9206,29 +9224,56 @@ var RecordingBandSchema = object({
9206
9224
  * `postBufferSec` must therefore exceed one segment length plus the attach
9207
9225
  * latency (ffmpeg spawn + RTSP dial), or the window closes before the first
9208
9226
  * segment is ever finalized and the camera records nothing anyway. At the 10 s
9209
- * default segment length, 30 s leaves room for two full segments. `preBufferSec`
9210
- * is retroactive only — it costs nothing at record time, it merely keeps
9211
- * already-written segments.
9212
- *
9213
- * ## Why `preBufferSec` is 15 and not one segment length
9214
- *
9215
- * It has to cover the broker's RECORDING pre-roll, which is media handed to the
9216
- * writer from BEFORE the trigger (D192/D193). If this bound were narrower, the
9217
- * keep gate would delete the very seconds the ring just supplied — two
9218
- * authorities disagreeing about the same footage, which is the failure D191 was
9219
- * written against. It is therefore set to `RECORDING_PRE_ROLL_MAX_MS` (15 s),
9220
- * the widest window the broker can be configured to serve, so an operator
9221
- * raising the cluster pre-roll can never walk past the gate silently. The
9222
- * addon-side guard is
9223
- * `packages/addon-pipeline/src/recorder/addon/__tests__/band-decision.spec.ts`.
9224
- *
9225
- * An EXPLICIT `0` is left alone: that is an operator statement, not an omission,
9226
- * and it is excluded from that invariant by name.
9227
- */
9228
- var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
9229
- preBufferSec: 15,
9230
- postBufferSec: 30
9231
- };
9227
+ * default segment length, 30 s leaves room for two full segments.
9228
+ *
9229
+ * ## There is no `preBufferSec` here any more (D381)
9230
+ *
9231
+ * There used to be, at 15 s, and its whole justification was that it had to
9232
+ * cover the widest pre-roll the broker could serve. A number whose only
9233
+ * correct value is another subsystem's ceiling is not a setting; it is that
9234
+ * ceiling, restated where it can drift. The keep bound is derived from the
9235
+ * prebuffer ceiling directly now, in `band-decision.ts`, so an operator
9236
+ * raising the prebuffer cannot walk past the gate at all rather than merely
9237
+ * being warned not to.
9238
+ */
9239
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = { postBufferSec: 30 };
9240
+ /**
9241
+ * Drop the RETIRED band `preBufferSec` from a persisted recording config.
9242
+ *
9243
+ * Explicit, and it reports what it removed, because the alternative is a
9244
+ * silent strip: `RecordingBandSchema` is a plain `z.object`, so the key
9245
+ * survives a parse and disappears on the next save with no line anywhere. An
9246
+ * operator who had typed a number would find it gone and nothing would say
9247
+ * when or why.
9248
+ *
9249
+ * Nothing is carried forward: the value it held was always required to be at
9250
+ * least the broker's widest pre-roll, and the gate is now derived from exactly
9251
+ * that ceiling. Every configuration that was legal therefore keeps a keep-gate
9252
+ * at least as wide as the one it had — including an explicit `0`, which widens.
9253
+ * That is deliberate and it is the only behaviour change: a band that kept
9254
+ * nothing before its trigger now keeps up to the prebuffer ceiling of
9255
+ * already-written footage, which is media that exists either way.
9256
+ */
9257
+ function stripRetiredBandPreBufferSec(config) {
9258
+ const strippedBands = [];
9259
+ const bands = config.bands.map((band, index) => {
9260
+ if (band.preBufferSec === void 0) return band;
9261
+ strippedBands.push(index);
9262
+ const { preBufferSec: _retired, ...rest } = band;
9263
+ return rest;
9264
+ });
9265
+ if (strippedBands.length === 0) return {
9266
+ config,
9267
+ strippedBands
9268
+ };
9269
+ return {
9270
+ config: {
9271
+ ...config,
9272
+ bands
9273
+ },
9274
+ strippedBands
9275
+ };
9276
+ }
9232
9277
  DEFAULT_EVENTS_BAND_BUFFER_SEC.postBufferSec * 1e3;
9233
9278
  /**
9234
9279
  * Per-device retention overrides. Every field is optional; an unset or `0`
@@ -12149,12 +12194,30 @@ var BackupDestinationInfoSchema = object({
12149
12194
  lastSuccessAt: number().optional(),
12150
12195
  /** Newest-archive size from `manifests.json`, or undefined. */
12151
12196
  lastSuccessSizeBytes: number().optional(),
12152
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
12197
+ /**
12198
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
12199
+ * destination, comma-joined. Absent when no enabled schedule targets it
12200
+ * — a destination nothing is scheduled to write to must not advertise a
12201
+ * cadence (D384). This is never the `backup_destination_policies.cron`
12202
+ * column: that per-location cron has scheduled nothing since 2026-07-28
12203
+ * and reading it made a destination with a DISABLED schedule claim a
12204
+ * nightly run.
12205
+ */
12153
12206
  cron: string().optional(),
12154
- /** ms-epoch of next computed firing for this destination's cron, if any. */
12207
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
12155
12208
  nextRunAt: number().optional(),
12156
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
12157
- lastRunAt: number().optional()
12209
+ /**
12210
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
12211
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
12212
+ * newest archive that actually landed) and `lastError`.
12213
+ */
12214
+ lastAttemptAt: number().optional(),
12215
+ /**
12216
+ * Why the last attempt failed, verbatim. Absent when the last attempt
12217
+ * landed the archive. A destination that has never been written to has
12218
+ * neither this nor `lastAttemptAt`.
12219
+ */
12220
+ lastError: string().optional()
12158
12221
  });
12159
12222
  /**
12160
12223
  * Per-archive entry returned by `backup.listArchives({ destinationId })`.
@@ -12317,8 +12380,16 @@ var BackupScheduleSchema = object({
12317
12380
  retentionCount: number().int().min(1).max(1e3),
12318
12381
  /** Optional subset of source locations to include; omitted = all. */
12319
12382
  dataSources: array(string()).readonly().optional(),
12320
- /** ms-epoch of last successful run. */
12321
- lastRunAt: number().optional(),
12383
+ /**
12384
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
12385
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
12386
+ * "succeeded" — a run refused by every destination stamps it too.
12387
+ */
12388
+ lastAttemptAt: number().optional(),
12389
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
12390
+ lastSuccessAt: number().optional(),
12391
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
12392
+ lastError: string().optional(),
12322
12393
  /** ms-epoch of next computed firing (read-only, filled on list). */
12323
12394
  nextRunAt: number().optional()
12324
12395
  });
@@ -12367,14 +12438,7 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
12367
12438
  locationId: string(),
12368
12439
  enabled: boolean(),
12369
12440
  retentionCount: number().int().min(1).max(1e3),
12370
- label: string().optional(),
12371
- /**
12372
- * Per-destination cron expression. Empty string clears the
12373
- * schedule (manual-only). Validated server-side via croner;
12374
- * malformed expressions reject the upsert with an actionable
12375
- * message.
12376
- */
12377
- cron: string().optional()
12441
+ label: string().optional()
12378
12442
  }), _void(), {
12379
12443
  kind: "mutation",
12380
12444
  auth: "admin"
@@ -42313,4 +42377,4 @@ function enumerateInferenceDevices(hw) {
42313
42377
  return out;
42314
42378
  }
42315
42379
  //#endregion
42316
- export { inferModelProvider as $, literal as $t, addonWidgetsSourceCapability as A, buildFfmpegArgs as At, defaultDeviceFor as B, isEvent as Bt, RATE_CONTROL_RELAXED as C, storageEvictableCapability as Ct, RecordingSignalStatusSchema as D, errMsg as Dt, RecordingConfigSchema as E, webrtcSessionCapability as Et, cameraStreamsCapability as F, CAM_PROFILE_ORDER as Ft, detectionPipelineCapability as G, parseProfileBrokerId as Gt, deriveBatteryPresence as H, makeSourceBrokerId as Ht, createHwAccelCache as I, DeviceFeature as It, enumerateInferenceDevices as J, _enum as Jt, egressTranscodeSharingKey as K, selectAssignedProfileSlots as Kt, createLogChannelsProvider as L, DeviceType as Lt, audioAnalyzerCapability as M, isSoftwareDecode as Mt, audioKindId as N, BOOT_RECOVERY_BACKOFF_MS as Nt, RingBuffer as O, AUDIO_PRESETS as Ot, batteryCapability as P, BaseAddon as Pt, hfModelUrl as Q, lazy as Qt, customAction as R, createEvent as Rt, PoolMemoryWatchdog as S, runtimeDevices as St, RECORDING_EXPORT_MAX_READ_BYTES as T, supportedRuntimes as Tt, deriveDetailCropRect as U, nodePin as Ut, defineCustomActions as V, makeProfileBrokerId as Vt, deriveRecordingMode as W, parseJsonUnknown as Wt, evaluateZoneRules as X, boolean as Xt, evaluateSensorEdge as Y, array as Yt, failureContributionCapability as Z, discriminatedUnion as Zt, FailureCounters as _, recordingSignalCapability as _t, COCO_80_LABELS as a, union as an, migrateLegacyDeviceSignalConfig as at, NativeLeaseSettingsSchema as b, resolvePoolMemoryPolicy as bt, DEFAULT_CLUSTER_STEP_MODELS as c, parseProcStatus as ct, DEFAULT_EVENTS_BAND_BUFFER_SEC as d, pickDetailCropConvention as dt, number as en, isFirstLevelMacroClass as et, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as f, pickNativeLeaseOverride as ft, ExportRecordSchema as g, recordingExportCapability as gt, EncodeProfileSchema as h, recordingCapability as ht, BatteryStatusSchema as i, string as in, maskUrlCredentials as it, audioAnalysisCapability as j, invocationFromEncodeProfile as jt, YAMNET_TO_MACRO as k, Fmp4BoxSplitter as kt, DEFAULT_CLUSTER_STEP_SETTINGS as l, pickClusterStepModels as lt, DEVICE_BACKEND_TO_FORMAT as m, pipelineRunnerCapability as mt, AUDIO_BACKEND_CHOICES as n, preprocess as nn, logChannelsCapability as nt, COCO_TO_MACRO as o, EventCategory as on, motionDetectionCapability as ot, DEFAULT_NATIVE_LEASE_SETTINGS as p, pipelineExecutorCapability as pt, egressTransportFromRequest as q, sleep as qt, AUDIO_MACRO_LABELS as r, record as rn, mapAudioLabelToMacro as rt, DEFAULT_AUDIO_ANALYZER_CONFIG as s, overlayClusterStepSettings as st, APPLE_SA_TO_MACRO as t, object as tn, loadContributionCapability as tt, DEFAULT_DETAIL_CROP_CONVENTION as u, pickClusterStepSettings as ut, HF_BASE_URL as v, resolveClusterStepModelId as vt, RATE_CONTROL_TIGHT as w, streamBrokerCapability as wt, OpsLogEntrySchema as x, resolveRecordingProfiles as xt, NativeLeaseAdmissionSchema as y, resolveEgressDecodeHwAccel as yt, declareLogChannel as z, hydrateSchema as zt };
42380
+ export { inferModelProvider as $, lazy as $t, addonWidgetsSourceCapability as A, Fmp4BoxSplitter as At, defaultDeviceFor as B, hydrateSchema as Bt, RATE_CONTROL_RELAXED as C, storageEvictableCapability as Ct, RecordingSignalStatusSchema as D, webrtcSessionCapability as Dt, RecordingConfigSchema as E, supportedRuntimes as Et, cameraStreamsCapability as F, BaseAddon as Ft, detectionPipelineCapability as G, parseJsonUnknown as Gt, deriveBatteryPresence as H, makeProfileBrokerId as Ht, createHwAccelCache as I, CAM_PROFILE_ORDER as It, enumerateInferenceDevices as J, sleep as Jt, egressTranscodeSharingKey as K, parseProfileBrokerId as Kt, createLogChannelsProvider as L, DeviceFeature as Lt, audioAnalyzerCapability as M, invocationFromEncodeProfile as Mt, audioKindId as N, isSoftwareDecode as Nt, RingBuffer as O, errMsg as Ot, batteryCapability as P, BOOT_RECOVERY_BACKOFF_MS as Pt, hfModelUrl as Q, discriminatedUnion as Qt, customAction as R, DeviceType as Rt, PoolMemoryWatchdog as S, runtimeDevices as St, RECORDING_EXPORT_MAX_READ_BYTES as T, stripRetiredBandPreBufferSec as Tt, deriveDetailCropRect as U, makeSourceBrokerId as Ut, defineCustomActions as V, isEvent as Vt, deriveRecordingMode as W, nodePin as Wt, evaluateZoneRules as X, array as Xt, evaluateSensorEdge as Y, _enum as Yt, failureContributionCapability as Z, boolean as Zt, FailureCounters as _, recordingSignalCapability as _t, COCO_80_LABELS as a, string as an, migrateLegacyDeviceSignalConfig as at, NativeLeaseSettingsSchema as b, resolvePoolMemoryPolicy as bt, DEFAULT_CLUSTER_STEP_MODELS as c, parseProcStatus as ct, DEFAULT_EVENTS_BAND_BUFFER_SEC as d, pickDetailCropConvention as dt, literal as en, isFirstLevelMacroClass as et, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as f, pickNativeLeaseOverride as ft, ExportRecordSchema as g, recordingExportCapability as gt, EncodeProfileSchema as h, recordingCapability as ht, BatteryStatusSchema as i, record as in, maskUrlCredentials as it, audioAnalysisCapability as j, buildFfmpegArgs as jt, YAMNET_TO_MACRO as k, AUDIO_PRESETS as kt, DEFAULT_CLUSTER_STEP_SETTINGS as l, pickClusterStepModels as lt, DEVICE_BACKEND_TO_FORMAT as m, pipelineRunnerCapability as mt, AUDIO_BACKEND_CHOICES as n, object as nn, logChannelsCapability as nt, COCO_TO_MACRO as o, union as on, motionDetectionCapability as ot, DEFAULT_NATIVE_LEASE_SETTINGS as p, pipelineExecutorCapability as pt, egressTransportFromRequest as q, selectAssignedProfileSlots as qt, AUDIO_MACRO_LABELS as r, preprocess as rn, mapAudioLabelToMacro as rt, DEFAULT_AUDIO_ANALYZER_CONFIG as s, EventCategory as sn, overlayClusterStepSettings as st, APPLE_SA_TO_MACRO as t, number as tn, loadContributionCapability as tt, DEFAULT_DETAIL_CROP_CONVENTION as u, pickClusterStepSettings as ut, HF_BASE_URL as v, resolveClusterStepModelId as vt, RATE_CONTROL_TIGHT as w, streamBrokerCapability as wt, OpsLogEntrySchema as x, resolveRecordingProfiles as xt, NativeLeaseAdmissionSchema as y, resolveEgressDecodeHwAccel as yt, declareLogChannel as z, createEvent as zt };
@@ -9212,6 +9212,24 @@ var RecordingBandSchema = object({
9212
9212
  end: string().regex(HHMM),
9213
9213
  mode: RecordingBandModeSchema,
9214
9214
  triggers: RecordingBandTriggersSchema.optional(),
9215
+ /**
9216
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
9217
+ *
9218
+ * It was the retroactive KEEP bound — which already-written segments survive
9219
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
9220
+ * broker could serve, or the gate would delete the seconds the ring had just
9221
+ * handed the writer. That "at least as wide as" is the tell: it was a second
9222
+ * expression of the broker's retention, in different units, in a different
9223
+ * addon, with an invariant the operator had to maintain by hand. The keep
9224
+ * bound is now derived from the one prebuffer ceiling and there is nothing
9225
+ * left to configure here.
9226
+ *
9227
+ * The key survives in the SHAPE so a config written before that record still
9228
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
9229
+ * strict, so simply deleting it would strip an operator's value in silence on
9230
+ * the next save (the failure D380 came one commit from shipping). Nothing
9231
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
9232
+ */
9215
9233
  preBufferSec: number().min(0).optional(),
9216
9234
  postBufferSec: number().min(0).optional()
9217
9235
  });
@@ -9229,29 +9247,56 @@ var RecordingBandSchema = object({
9229
9247
  * `postBufferSec` must therefore exceed one segment length plus the attach
9230
9248
  * latency (ffmpeg spawn + RTSP dial), or the window closes before the first
9231
9249
  * segment is ever finalized and the camera records nothing anyway. At the 10 s
9232
- * default segment length, 30 s leaves room for two full segments. `preBufferSec`
9233
- * is retroactive only — it costs nothing at record time, it merely keeps
9234
- * already-written segments.
9235
- *
9236
- * ## Why `preBufferSec` is 15 and not one segment length
9237
- *
9238
- * It has to cover the broker's RECORDING pre-roll, which is media handed to the
9239
- * writer from BEFORE the trigger (D192/D193). If this bound were narrower, the
9240
- * keep gate would delete the very seconds the ring just supplied — two
9241
- * authorities disagreeing about the same footage, which is the failure D191 was
9242
- * written against. It is therefore set to `RECORDING_PRE_ROLL_MAX_MS` (15 s),
9243
- * the widest window the broker can be configured to serve, so an operator
9244
- * raising the cluster pre-roll can never walk past the gate silently. The
9245
- * addon-side guard is
9246
- * `packages/addon-pipeline/src/recorder/addon/__tests__/band-decision.spec.ts`.
9247
- *
9248
- * An EXPLICIT `0` is left alone: that is an operator statement, not an omission,
9249
- * and it is excluded from that invariant by name.
9250
- */
9251
- var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
9252
- preBufferSec: 15,
9253
- postBufferSec: 30
9254
- };
9250
+ * default segment length, 30 s leaves room for two full segments.
9251
+ *
9252
+ * ## There is no `preBufferSec` here any more (D381)
9253
+ *
9254
+ * There used to be, at 15 s, and its whole justification was that it had to
9255
+ * cover the widest pre-roll the broker could serve. A number whose only
9256
+ * correct value is another subsystem's ceiling is not a setting; it is that
9257
+ * ceiling, restated where it can drift. The keep bound is derived from the
9258
+ * prebuffer ceiling directly now, in `band-decision.ts`, so an operator
9259
+ * raising the prebuffer cannot walk past the gate at all rather than merely
9260
+ * being warned not to.
9261
+ */
9262
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = { postBufferSec: 30 };
9263
+ /**
9264
+ * Drop the RETIRED band `preBufferSec` from a persisted recording config.
9265
+ *
9266
+ * Explicit, and it reports what it removed, because the alternative is a
9267
+ * silent strip: `RecordingBandSchema` is a plain `z.object`, so the key
9268
+ * survives a parse and disappears on the next save with no line anywhere. An
9269
+ * operator who had typed a number would find it gone and nothing would say
9270
+ * when or why.
9271
+ *
9272
+ * Nothing is carried forward: the value it held was always required to be at
9273
+ * least the broker's widest pre-roll, and the gate is now derived from exactly
9274
+ * that ceiling. Every configuration that was legal therefore keeps a keep-gate
9275
+ * at least as wide as the one it had — including an explicit `0`, which widens.
9276
+ * That is deliberate and it is the only behaviour change: a band that kept
9277
+ * nothing before its trigger now keeps up to the prebuffer ceiling of
9278
+ * already-written footage, which is media that exists either way.
9279
+ */
9280
+ function stripRetiredBandPreBufferSec(config) {
9281
+ const strippedBands = [];
9282
+ const bands = config.bands.map((band, index) => {
9283
+ if (band.preBufferSec === void 0) return band;
9284
+ strippedBands.push(index);
9285
+ const { preBufferSec: _retired, ...rest } = band;
9286
+ return rest;
9287
+ });
9288
+ if (strippedBands.length === 0) return {
9289
+ config,
9290
+ strippedBands
9291
+ };
9292
+ return {
9293
+ config: {
9294
+ ...config,
9295
+ bands
9296
+ },
9297
+ strippedBands
9298
+ };
9299
+ }
9255
9300
  DEFAULT_EVENTS_BAND_BUFFER_SEC.postBufferSec * 1e3;
9256
9301
  /**
9257
9302
  * Per-device retention overrides. Every field is optional; an unset or `0`
@@ -12172,12 +12217,30 @@ var BackupDestinationInfoSchema = object({
12172
12217
  lastSuccessAt: number().optional(),
12173
12218
  /** Newest-archive size from `manifests.json`, or undefined. */
12174
12219
  lastSuccessSizeBytes: number().optional(),
12175
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
12220
+ /**
12221
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
12222
+ * destination, comma-joined. Absent when no enabled schedule targets it
12223
+ * — a destination nothing is scheduled to write to must not advertise a
12224
+ * cadence (D384). This is never the `backup_destination_policies.cron`
12225
+ * column: that per-location cron has scheduled nothing since 2026-07-28
12226
+ * and reading it made a destination with a DISABLED schedule claim a
12227
+ * nightly run.
12228
+ */
12176
12229
  cron: string().optional(),
12177
- /** ms-epoch of next computed firing for this destination's cron, if any. */
12230
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
12178
12231
  nextRunAt: number().optional(),
12179
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
12180
- lastRunAt: number().optional()
12232
+ /**
12233
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
12234
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
12235
+ * newest archive that actually landed) and `lastError`.
12236
+ */
12237
+ lastAttemptAt: number().optional(),
12238
+ /**
12239
+ * Why the last attempt failed, verbatim. Absent when the last attempt
12240
+ * landed the archive. A destination that has never been written to has
12241
+ * neither this nor `lastAttemptAt`.
12242
+ */
12243
+ lastError: string().optional()
12181
12244
  });
12182
12245
  /**
12183
12246
  * Per-archive entry returned by `backup.listArchives({ destinationId })`.
@@ -12340,8 +12403,16 @@ var BackupScheduleSchema = object({
12340
12403
  retentionCount: number().int().min(1).max(1e3),
12341
12404
  /** Optional subset of source locations to include; omitted = all. */
12342
12405
  dataSources: array(string()).readonly().optional(),
12343
- /** ms-epoch of last successful run. */
12344
- lastRunAt: number().optional(),
12406
+ /**
12407
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
12408
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
12409
+ * "succeeded" — a run refused by every destination stamps it too.
12410
+ */
12411
+ lastAttemptAt: number().optional(),
12412
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
12413
+ lastSuccessAt: number().optional(),
12414
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
12415
+ lastError: string().optional(),
12345
12416
  /** ms-epoch of next computed firing (read-only, filled on list). */
12346
12417
  nextRunAt: number().optional()
12347
12418
  });
@@ -12390,14 +12461,7 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
12390
12461
  locationId: string(),
12391
12462
  enabled: boolean(),
12392
12463
  retentionCount: number().int().min(1).max(1e3),
12393
- label: string().optional(),
12394
- /**
12395
- * Per-destination cron expression. Empty string clears the
12396
- * schedule (manual-only). Validated server-side via croner;
12397
- * malformed expressions reject the upsert with an actionable
12398
- * message.
12399
- */
12400
- cron: string().optional()
12464
+ label: string().optional()
12401
12465
  }), _void(), {
12402
12466
  kind: "mutation",
12403
12467
  auth: "admin"
@@ -43014,6 +43078,12 @@ Object.defineProperty(exports, "string", {
43014
43078
  return string;
43015
43079
  }
43016
43080
  });
43081
+ Object.defineProperty(exports, "stripRetiredBandPreBufferSec", {
43082
+ enumerable: true,
43083
+ get: function() {
43084
+ return stripRetiredBandPreBufferSec;
43085
+ }
43086
+ });
43017
43087
  Object.defineProperty(exports, "supportedRuntimes", {
43018
43088
  enumerable: true,
43019
43089
  get: function() {
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-CBa1j3On.js");
1
+ const require_dist = require("./dist-DmCrC2yx.js");
2
2
  let node_path = require("node:path");
3
3
  node_path = require_dist.__toESM(node_path);
4
4
  let node_url = require("node:url");
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-CBa1j3On.js");
6
- const require_lazy_sharp = require("../lazy-sharp-CS5WE9mI.js");
5
+ const require_dist = require("../dist-DmCrC2yx.js");
6
+ const require_lazy_sharp = require("../lazy-sharp-DBHsD2lh.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
9
9
  //#region src/motion-wasm/wasm-motion-detector.ts
@@ -1,4 +1,4 @@
1
- import { Lt as DeviceType, Pt as BaseAddon, X as evaluateZoneRules, ot as motionDetectionCapability, zt as hydrateSchema } from "../dist-Y4BsF_EC.mjs";
1
+ import { Bt as hydrateSchema, Ft as BaseAddon, Rt as DeviceType, X as evaluateZoneRules, ot as motionDetectionCapability } from "../dist-B23u1tmN.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,4 +1,4 @@
1
- import { At as buildFfmpegArgs, Dt as errMsg, Mt as isSoftwareDecode, kt as Fmp4BoxSplitter } from "./dist-Y4BsF_EC.mjs";
1
+ import { At as Fmp4BoxSplitter, Nt as isSoftwareDecode, Ot as errMsg, jt as buildFfmpegArgs } from "./dist-B23u1tmN.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import "node:fs";
4
4
  import "node:path";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-CBa1j3On.js");
1
+ const require_dist = require("./dist-DmCrC2yx.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_dist.__toESM(node_fs, 1);
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-CBa1j3On.js");
6
- const require_node = require("../node-C-B8VuGi.js");
7
- const require_default_detection_model = require("../default-detection-model-CM-8U0Bb.js");
8
- const require_worker_protocol = require("../worker-protocol-CXsdriRX.js");
5
+ const require_dist = require("../dist-DmCrC2yx.js");
6
+ const require_node = require("../node-DCSTbt6C.js");
7
+ const require_default_detection_model = require("../default-detection-model-CMe44Kid.js");
8
+ const require_worker_protocol = require("../worker-protocol-c1r1Yddg.js");
9
9
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
10
- const require_lazy_sharp = require("../lazy-sharp-CS5WE9mI.js");
10
+ const require_lazy_sharp = require("../lazy-sharp-DBHsD2lh.js");
11
11
  const require_restream_intent = require("../restream-intent-Cv9x3jmu.js");
12
12
  const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
13
13
  const require_remote_restream = require("../remote-restream-CO36Sr30.js");
@@ -1,7 +1,7 @@
1
- import { $t as literal, Dt as errMsg, Jt as _enum, Pt as BaseAddon, Qt as lazy, R as customAction, Rt as createEvent, U as deriveDetailCropRect, Ut as nodePin, V as defineCustomActions, Xt as boolean, Yt as array, Z as failureContributionCapability, _ as FailureCounters, dt as pickDetailCropConvention, en as number, ft as pickNativeLeaseOverride, in as string, m as DEVICE_BACKEND_TO_FORMAT, mt as pipelineRunnerCapability, on as EventCategory, p as DEFAULT_NATIVE_LEASE_SETTINGS, tn as object, tt as loadContributionCapability, u as DEFAULT_DETAIL_CROP_CONVENTION } from "../dist-Y4BsF_EC.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-B5ouEQYN.mjs";
3
- import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-CplzzTmN.mjs";
4
- import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-_7zrToTo.mjs";
1
+ import { $t as lazy, Ft as BaseAddon, Ot as errMsg, R as customAction, U as deriveDetailCropRect, V as defineCustomActions, Wt as nodePin, Xt as array, Yt as _enum, Z as failureContributionCapability, Zt as boolean, _ as FailureCounters, an as string, dt as pickDetailCropConvention, en as literal, ft as pickNativeLeaseOverride, m as DEVICE_BACKEND_TO_FORMAT, mt as pipelineRunnerCapability, nn as object, p as DEFAULT_NATIVE_LEASE_SETTINGS, sn as EventCategory, tn as number, tt as loadContributionCapability, u as DEFAULT_DETAIL_CROP_CONVENTION, zt as createEvent } from "../dist-B23u1tmN.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-D1MLn6oV.mjs";
3
+ import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-O1uBusV2.mjs";
4
+ import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-BxpGZ0Dt.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
7
7
  import { n as withDetectionIntent } from "../restream-intent-B4BXZra7.mjs";
@@ -323,16 +323,68 @@ function isRecord(value) {
323
323
  function errText(err) {
324
324
  return err instanceof Error ? err.message : String(err);
325
325
  }
326
- //#endregion
327
- Object.defineProperty(exports, "RowMapStore", {
328
- enumerable: true,
329
- get: function() {
330
- return RowMapStore;
331
- }
332
- });
333
- Object.defineProperty(exports, "retireRootKeys", {
334
- enumerable: true,
335
- get: function() {
336
- return retireRootKeys;
326
+ /** {@link PREBUFFER_MAX_SEC} in ms — the widest window any consumer can be served. */
327
+ var PREBUFFER_MAX_MS = 15 * 1e3;
328
+ /** Clamp an enabled window's seconds into `[MIN, MAX]`; `0`/invalid means off. */
329
+ function clampSeconds(value) {
330
+ if (value === void 0) return 5;
331
+ if (!Number.isFinite(value) || value <= 0) return 0;
332
+ return Math.min(15, Math.max(1, value));
333
+ }
334
+ /** `enabled: false` is the only representation of off — never `seconds: 0` alone. */
335
+ var OFF = {
336
+ enabled: false,
337
+ seconds: 0
338
+ };
339
+ /**
340
+ * The ONE prebuffer decision.
341
+ *
342
+ * Precedence: explicit per-stream override -> battery / terminal relay (off) ->
343
+ * the profile's warm default -> off. Every layer that used to make this
344
+ * decision somewhere else — `isDefaultWarm`, `applyPreBufferConfig`,
345
+ * `getEffectivePreBufferSec`, `resolvePreRollMs`, `resolveRecordingPreRollMs` —
346
+ * is this function now, so the four of them cannot disagree about one camera.
347
+ */
348
+ function resolvePrebuffer(input) {
349
+ const override = input.overrides?.[input.camStreamId];
350
+ if (override !== void 0) {
351
+ if (!override.enabled) return OFF;
352
+ const seconds = clampSeconds(override.seconds);
353
+ return seconds > 0 ? {
354
+ enabled: true,
355
+ seconds
356
+ } : OFF;
337
357
  }
338
- });
358
+ if (input.batteryOperated === true) return OFF;
359
+ if (input.terminalRelay === true) return OFF;
360
+ if (input.defaultWarm !== true) return OFF;
361
+ const seconds = clampSeconds(input.clusterSeconds);
362
+ return seconds > 0 ? {
363
+ enabled: true,
364
+ seconds
365
+ } : OFF;
366
+ }
367
+ /** The retention, in ms — the single number the ring is trimmed to. */
368
+ function prebufferRetentionMs(config) {
369
+ return config.enabled ? config.seconds * 1e3 : 0;
370
+ }
371
+ /**
372
+ * What a consumer asking for `requestedMs` of history is actually served.
373
+ *
374
+ * The cap is the point of the record: a consumer states a WISH and the ring
375
+ * states the truth. `undefined` means "whatever you have", which is what a
376
+ * consumer that configures nothing asks for — and is why the recorder no
377
+ * longer carries a duration of its own.
378
+ *
379
+ * A nonsense request resolves to `0`, never to the whole window: an
380
+ * unparseable number arriving on a dial path must not be able to widen a burst.
381
+ */
382
+ function capPreRollRequestMs(requestedMs, retainedMs) {
383
+ const retained = Number.isFinite(retainedMs) && retainedMs > 0 ? retainedMs : 0;
384
+ if (retained === 0) return 0;
385
+ if (requestedMs === void 0) return retained;
386
+ if (!Number.isFinite(requestedMs) || requestedMs <= 0) return 0;
387
+ return Math.min(requestedMs, retained);
388
+ }
389
+ //#endregion
390
+ export { retireRootKeys as a, resolvePrebuffer as i, capPreRollRequestMs as n, RowMapStore as o, prebufferRetentionMs as r, PREBUFFER_MAX_MS as t };