@camstack/addon-remote-storage 1.2.101 → 1.2.103

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.
package/dist/s3.addon.js CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-SgmN8tGm.js");
5
+ const require_shared = require("./shared-DqWt_U16.js");
6
6
  let node_stream = require("node:stream");
7
7
  let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
8
8
  let _aws_sdk_lib_storage = require("@aws-sdk/lib-storage");
package/dist/s3.addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as BaseAddon, i as rearmIdleAbort, n as getOptionalBasePath, o as scheduleIdleAbort, s as storageProviderCapability, t as createSessionId } from "./shared-C0LzFm0z.mjs";
1
+ import { c as BaseAddon, i as rearmIdleAbort, n as getOptionalBasePath, o as scheduleIdleAbort, s as storageProviderCapability, t as createSessionId } from "./shared-DPTTju9B.mjs";
2
2
  import { PassThrough } from "node:stream";
3
3
  import { DeleteObjectCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
4
4
  import { Upload } from "@aws-sdk/lib-storage";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-SgmN8tGm.js");
5
+ const require_shared = require("./shared-DqWt_U16.js");
6
6
  let ssh2 = require("ssh2");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_shared.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-C0LzFm0z.mjs";
1
+ import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-DPTTju9B.mjs";
2
2
  import { Client } from "ssh2";
3
3
  import * as path from "node:path";
4
4
  //#region src/providers/sftp/sftp-config-schema.ts
@@ -5361,7 +5361,7 @@ var ZodIssueCode = {
5361
5361
  var ZodFirstPartyTypeKind;
5362
5362
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5363
5363
  //#endregion
5364
- //#region ../types/dist/sleep-DEuj7E3j.mjs
5364
+ //#region ../types/dist/sleep-BDR76Ykr.mjs
5365
5365
  /**
5366
5366
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5367
5367
  * window to float samples (D455).
@@ -17819,6 +17819,48 @@ var NcAlarmConfigSchema = object({
17819
17819
  settings: NcAlarmSettingsSchema,
17820
17820
  coverage: array(NcAlarmModeCoverageSchema)
17821
17821
  });
17822
+ /**
17823
+ * ONE rule's demand on ONE camera's clip ring.
17824
+ *
17825
+ * A rule, not a camera: the broker takes the MAX over the asks that reach a
17826
+ * camera, so the answer stays a faithful description of the rules and the
17827
+ * bounding (the byte budget, the broker's own ceiling) stays where the cost
17828
+ * lives. A camera that appears in no ask is being told **nothing** — which is
17829
+ * a different thing from never having been told, and only the envelope
17830
+ * (`rulesLoaded`) can tell those apart.
17831
+ */
17832
+ var NcClipRetentionAskSchema = object({
17833
+ /**
17834
+ * The camera this ask is about. **Absent = every camera**, which is what a
17835
+ * rule with no `conditions.devices` means: it can fire anywhere, so it is
17836
+ * asking everywhere.
17837
+ */
17838
+ deviceId: number().int().nonnegative().optional(),
17839
+ /** Seconds of history the rule needs held for it. Never zero — a rule that
17840
+ * needs nothing produces no ask at all. */
17841
+ seconds: number().min(0).max(60),
17842
+ /** The profile the rule cuts from, when it named one. Absent = the cheapest
17843
+ * assigned, which is what the cut defaults to. */
17844
+ profile: CamProfileSchema.optional(),
17845
+ /** Who is asking — so a retention the operator did not expect names a rule. */
17846
+ ruleId: string(),
17847
+ ruleName: string(),
17848
+ /** Why this many seconds: the rule's own window, or the occupancy ceiling. */
17849
+ reason: _enum(["window", "occupancy"])
17850
+ });
17851
+ /**
17852
+ * The whole answer, with the one bit that keeps absence from reading as zero.
17853
+ *
17854
+ * `rulesLoaded` is false until the rule ledger has completed a load at least
17855
+ * once. A centre that is up but has not read its rules yet answers with an
17856
+ * empty ask list that means nothing at all — applying it would drop every
17857
+ * camera's ring to zero for the first events after a restart, which is the
17858
+ * footage this mechanism exists to keep.
17859
+ */
17860
+ var NcClipRetentionPlanSchema = object({
17861
+ rulesLoaded: boolean(),
17862
+ asks: array(NcClipRetentionAskSchema).readonly()
17863
+ });
17822
17864
  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 }), {
17823
17865
  kind: "mutation",
17824
17866
  auth: "admin",
@@ -17839,7 +17881,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
17839
17881
  }), object({ success: literal(true) }), {
17840
17882
  kind: "mutation",
17841
17883
  auth: "admin"
17842
- }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
17884
+ }), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
17843
17885
  deviceId: number().int(),
17844
17886
  muted: boolean()
17845
17887
  }), object({ success: literal(true) }), {
@@ -18984,13 +19026,26 @@ var TrackAudioLabelSchema = object({
18984
19026
  * - `audio` — an audio event on the camera itself that was anomalous for
18985
19027
  * THAT camera, loud, and heard while nothing visual was happening (D62).
18986
19028
  *
19029
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19030
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19031
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19032
+ * detector.
19033
+ *
19034
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19035
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19036
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19037
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19038
+ * could not name.
19039
+ *
18987
19040
  * The spatial subsystems (tracker association, occupancy count, re-id /
18988
19041
  * embedding, resurrection) MUST skip every synthetic source. Test for that
18989
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
18990
- * check silently readmits every source added after it was written.
19042
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19043
+ * `!== 'sensor'` check silently readmits every source added after it was
19044
+ * written.
18991
19045
  */
18992
19046
  var TrackSourceSchema = _enum([
18993
19047
  "pipeline",
19048
+ "onboard",
18994
19049
  "sensor",
18995
19050
  "audio"
18996
19051
  ]);
@@ -20373,6 +20428,33 @@ var RunReplayFrameProcessorResultSchema = object({ tracks: array(object({
20373
20428
  * solid is this track", cheaper than re-deriving it from a trajectory. */
20374
20429
  framesMatched: number().int()
20375
20430
  })).readonly() });
20431
+ /**
20432
+ * The long-term series a camera produces. A closed union so a typo cannot
20433
+ * invent one, and the ONE declaration of it — the addon's `AnalyticsLtsSeries`
20434
+ * is an alias of this, not a second list.
20435
+ */
20436
+ var AnalyticsLtsSeriesSchema = _enum([
20437
+ "motion",
20438
+ "audio-dbfs",
20439
+ "battery",
20440
+ "occupancy"
20441
+ ]);
20442
+ /**
20443
+ * One closed 5-minute bucket of a long-term series.
20444
+ *
20445
+ * `samples` is how many readings the bucket folded — it is the ACTIVITY for a
20446
+ * series like `motion`, and the confidence for one like `occupancy`. A bucket
20447
+ * that exists at all was measured; a bucket that is absent was not, which is a
20448
+ * different claim from zero and the reason this is a sparse series.
20449
+ */
20450
+ var LtsBucketSchema = object({
20451
+ scope: string(),
20452
+ bucketStart: number().int(),
20453
+ samples: number().int().nonnegative(),
20454
+ sum: number(),
20455
+ min: number(),
20456
+ max: number()
20457
+ });
20376
20458
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
20377
20459
  deviceId: number(),
20378
20460
  trackId: string()
@@ -20419,6 +20501,14 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20419
20501
  kinds: array(string()).optional(),
20420
20502
  limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
20421
20503
  }), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(KeyEventBatchQueryInput, array(KeyEventsForDeviceSchema).readonly()), method(object({
20504
+ deviceId: number(),
20505
+ series: AnalyticsLtsSeriesSchema,
20506
+ /** Omit for EVERY scope of this series in the range. */
20507
+ scope: string().optional(),
20508
+ from: number(),
20509
+ to: number(),
20510
+ limit: number().int().positive().optional()
20511
+ }), array(LtsBucketSchema).readonly()), method(object({
20422
20512
  deviceId: number(),
20423
20513
  since: number(),
20424
20514
  until: number(),
@@ -21037,6 +21127,40 @@ var MotionSourceEnum = _enum([
21037
21127
  */
21038
21128
  var MotionSourcesSchema = array(MotionSourceEnum);
21039
21129
  /**
21130
+ * Which root detector a camera runs — EXACTLY ONE.
21131
+ *
21132
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
21133
+ * with (`DetectionSource`) rather than a second spelling of the same two
21134
+ * ideas: the value an operator picks here is the value that comes back on the
21135
+ * track, the overlay and the debug row.
21136
+ *
21137
+ * ## Why one, and why it is still an array
21138
+ *
21139
+ * Two roots on one camera is a capability nobody asked for and the operator has
21140
+ * since ruled out. It was never free: both planes feed the SAME per-device
21141
+ * stationary registry, both can promote the same parked object, and the two
21142
+ * detectors disagree about the same box by construction — which is the
21143
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
21144
+ *
21145
+ * The ARRAY shape survives because the stored settings and the attach payload
21146
+ * already speak it on every camera of every fleet, and a cap input that
21147
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
21148
+ * in the one direction that costs an operator their cameras. So the wire stays
21149
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
21150
+ * element rather than refused, and `max(1)` is what every consumer can then
21151
+ * rely on.
21152
+ *
21153
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
21154
+ * a camera an operator left with no root detector — and `planDetectionSources`
21155
+ * has always said so: inventing a root for them is how a default acts without
21156
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
21157
+ * suite caught it.
21158
+ *
21159
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
21160
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
21161
+ */
21162
+ var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
21163
+ /**
21040
21164
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
21041
21165
  * so cap-side consumers (the orchestrator forward, the runner addon's
21042
21166
  * cap implementation, tests) can reuse the type instead of redeclaring
@@ -21187,6 +21311,35 @@ var RunnerCameraConfigSchema = object({
21187
21311
  * events; the orchestrator forwards to `reportMotion`.
21188
21312
  */
21189
21313
  motionSources: MotionSourcesSchema.default(["analyzer"]),
21314
+ /**
21315
+ * WHICH root detector runs for this camera. The detection counterpart of
21316
+ * {@link motionSources}, same shape and same discipline: a per-camera list
21317
+ * of sources the system understands, vendor-agnostic, owned here.
21318
+ *
21319
+ * - `pipeline` — this runner's own root step on decoded pixels (`steps`).
21320
+ * - `onboard` — the CAMERA's own detector, admitted only when it is named
21321
+ * here. Its boxes reach post-analysis on the same
21322
+ * `PipelineInferenceResult` payload as the pipeline's, so an onboard-born
21323
+ * track gets the same tracker, the same overlay and the same detail
21324
+ * subtree (face / plate / embedding).
21325
+ *
21326
+ * `['onboard']` alone is the REPLACEMENT: this runner's root step does not
21327
+ * run, and that is where a camera with a usable onboard detector buys back
21328
+ * its share of the accelerator. It saves the root inference, not the decode
21329
+ * — the detail subtree still needs pixels to cut crops from.
21330
+ *
21331
+ * A camera whose onboard detections carry no geometry cannot serve as a root
21332
+ * step at all (there is nothing to track), and the cap that knows this says
21333
+ * so on `native-object-detection.getOptions().geometry`. On Reolink that is
21334
+ * every battery camera: the boxes ride a sub-stream a battery camera never
21335
+ * attaches, so such a camera stays on `['pipeline']` and its onboard AI is
21336
+ * worth exactly what it already is — a wake signal with a class.
21337
+ *
21338
+ * Defaults to `['pipeline']`, which is byte-for-byte today's behaviour: a
21339
+ * vendor never turns a detector on for the operator, and neither does a
21340
+ * default.
21341
+ */
21342
+ detectionSources: DetectionSourcesSchema.default(["pipeline"]),
21190
21343
  pipelineEnabled: boolean().default(true),
21191
21344
  /** Ordered tree of video steps. Absent → runner skips video detection. */
21192
21345
  steps: array(PipelineStepInputSchema).readonly().optional(),
@@ -21368,7 +21521,47 @@ var RunnerLocalMetricsSchema = object({
21368
21521
  queueDepth: number(),
21369
21522
  frameLazy: FrameLazyMetricsSchema.optional()
21370
21523
  });
21524
+ /**
21525
+ * Pipeline Runner capability — runtime detection workhorse.
21526
+ *
21527
+ * One instance per node. Receives camera assignments from
21528
+ * `addon-pipeline-orchestrator`, subscribes to the local stream-broker for
21529
+ * decoded frames, drains motion + detection queues, calls the local
21530
+ * `motion-detection` and `pipeline-executor` capabilities, and emits typed
21531
+ * `pipeline.inference-result` and `detection.motion-analysis` events on
21532
+ * the bus.
21533
+ *
21534
+ * Distinct from `pipeline-orchestrator` (the hub-side load balancer) — the
21535
+ * runner has zero knowledge of other agents, no global state, and never
21536
+ * makes assignment decisions itself.
21537
+ */
21538
+ /**
21539
+ * Why a runner declined to look at a camera out of band. Named rather than a
21540
+ * bare `false`: a camera asleep on battery (D173), one attached elsewhere, one
21541
+ * already mid-session and one already bursting are four different facts, and a
21542
+ * caller told only "no" cannot tell a protection from a bug.
21543
+ */
21544
+ var OccupancyBurstRefusalSchema = _enum([
21545
+ "not-attached",
21546
+ "battery-asleep",
21547
+ "not-watching",
21548
+ "already-bursting"
21549
+ ]);
21371
21550
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
21551
+ deviceId: number(),
21552
+ /** How many frames to collect. The caller sizes this against what its
21553
+ * own confirmation needs; the runner clamps it to the field's range. */
21554
+ frames: number().int().positive().optional(),
21555
+ /** Why, for the log. A burst nobody can attribute is a cost nobody can
21556
+ * defend — the periodic one at least has a timer to point at. */
21557
+ reason: string()
21558
+ }), object({
21559
+ started: boolean(),
21560
+ refusedBecause: OccupancyBurstRefusalSchema.optional()
21561
+ }), {
21562
+ auth: "admin",
21563
+ kind: "mutation"
21564
+ }), method(object({
21372
21565
  handle: FrameHandleSchema,
21373
21566
  bbox: NativeCropBboxSchema,
21374
21567
  maxWidth: number().int().positive().optional(),
@@ -26897,7 +27090,7 @@ var NativeDetectionSchema = object({
26897
27090
  /** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
26898
27091
  confidence: number().min(0).max(1).optional()
26899
27092
  });
26900
- object({
27093
+ var NativeObjectDetectionStatusSchema = object({
26901
27094
  /**
26902
27095
  * Last observed instance per class. Missing entries mean the class
26903
27096
  * is supported but nothing has been seen since the provider started.
@@ -26914,14 +27107,56 @@ object({
26914
27107
  supportedClasses: array(NativeObjectClassEnum).readonly(),
26915
27108
  /**
26916
27109
  * Whether forwarding of onboard AI detections is enabled for this device.
26917
- * Default FALSE (opt-in, cold-start) — onboard AI pushes are noisy/sparse and
26918
- * churn the tracker, so forwarding stays off until the operator enables it.
27110
+ *
27111
+ * Cold-start OFF on every camera. A vendor does not decide which detector a
27112
+ * camera runs — that is the operator's choice, and it is made where every
27113
+ * other detection choice is made. `geometry` on
27114
+ * {@link NativeObjectDetectionOptionsSchema} is how the form says what the
27115
+ * choice would buy this particular camera.
26919
27116
  */
26920
27117
  enabled: boolean()
26921
- }).extend({
27118
+ });
27119
+ /**
27120
+ * WHEN a camera's onboard detections carry geometry.
27121
+ *
27122
+ * - `boxed` — always. The provider holds a standing channel for the boxes, so
27123
+ * a detection is a trackable subject whenever the camera sees one.
27124
+ * - `while-streaming` — only while some stream of this camera is already open.
27125
+ * The boxes ride the video's own side-channel rather than a feed of their
27126
+ * own, so they cost nothing and they exist only when something is pulling.
27127
+ * On Reolink this is every BATTERY camera: a persistent second feed is real
27128
+ * radio drain, but a camera that is awake is awake precisely because
27129
+ * something is in front of it, and its stream is already being pulled.
27130
+ * - `flag-only` — never. The firmware ships the class and nothing else; the
27131
+ * pipeline needs geometry to make a subject, so such a push reaches the
27132
+ * tracker as motion and no further.
27133
+ *
27134
+ * Reported and not inferred, because the operator's question in front of the
27135
+ * picker is "what do I get", and these are three different answers (D14: the
27136
+ * derived form is only as honest as `getOptions`).
27137
+ */
27138
+ var NativeObjectGeometryEnum = _enum([
27139
+ "boxed",
27140
+ "while-streaming",
27141
+ "flag-only"
27142
+ ]);
27143
+ var NativeObjectDetectionOptionsSchema = object({
27144
+ /** Classes this firmware can detect — the same list the status reports. */
27145
+ supportedClasses: array(NativeObjectClassEnum).readonly(),
27146
+ /** What a detection from this camera carries. */
27147
+ geometry: NativeObjectGeometryEnum
27148
+ });
27149
+ var NativeObjectDetectionSettingsPatchSchema = object({ enabled: boolean().optional() });
27150
+ NativeObjectDetectionStatusSchema.extend({
26922
27151
  /** Required by createRuntimeStateBridge — epoch ms of last refresh. */
26923
27152
  lastFetchedAt: number() });
26924
- DeviceType.Camera, method(object({
27153
+ DeviceType.Camera, method(object({ deviceId: number() }), NativeObjectDetectionOptionsSchema), method(object({
27154
+ deviceId: number(),
27155
+ settings: NativeObjectDetectionSettingsPatchSchema
27156
+ }), _void(), {
27157
+ kind: "mutation",
27158
+ auth: "admin"
27159
+ }), method(object({
26925
27160
  deviceId: number(),
26926
27161
  enabled: boolean()
26927
27162
  }), _void(), {
@@ -30720,7 +30955,28 @@ var PerScopeBreakdownSchema = object({
30720
30955
  /** Total tracked objects in this scope (frame / zone / unzoned). */
30721
30956
  totalObjects: number().int().nonnegative(),
30722
30957
  /** Per-class count. Keys are macro class names (e.g. `person`, `car`). */
30723
- byClass: record(string(), number().int().nonnegative())
30958
+ byClass: record(string(), number().int().nonnegative()),
30959
+ /**
30960
+ * Of `totalObjects`, how many are STANDING — objects the census holds,
30961
+ * present but not going anywhere (a parked car, a bin, a statue).
30962
+ *
30963
+ * The operator's question about a scene has two halves and they answer
30964
+ * different things: "what is parked here" is stable for hours and must not
30965
+ * flap, while "who is walking through" is the thing an alert is about. One
30966
+ * number could only serve one of them, and `totalObjects` served the first
30967
+ * badly — a passer-by moved it and every occupancy rule saw a change.
30968
+ *
30969
+ * `standing + transient === totalObjects`, always. The total keeps its old
30970
+ * meaning exactly, so no rule written against it changes behaviour.
30971
+ *
30972
+ * ABSENT means UNKNOWN, never zero (D393): a snapshot from a node older than
30973
+ * this field cannot say, and a reader that folds absence in as 0 reports "no
30974
+ * parked objects here" about a camera whose lot is full.
30975
+ */
30976
+ standingObjects: number().int().nonnegative().optional(),
30977
+ /** Of `totalObjects`, how many are passing through. See `standingObjects` —
30978
+ * same absence rule. */
30979
+ transientObjects: number().int().nonnegative().optional()
30724
30980
  });
30725
30981
  var ZoneScopeBreakdownSchema = PerScopeBreakdownSchema.extend({
30726
30982
  zoneId: string(),
@@ -33659,12 +33915,24 @@ Object.freeze({
33659
33915
  addonId: null,
33660
33916
  access: "create"
33661
33917
  },
33918
+ "nativeObjectDetection.getOptions": {
33919
+ capName: "native-object-detection",
33920
+ capScope: "device",
33921
+ addonId: null,
33922
+ access: "view"
33923
+ },
33662
33924
  "nativeObjectDetection.setEnabled": {
33663
33925
  capName: "native-object-detection",
33664
33926
  capScope: "device",
33665
33927
  addonId: null,
33666
33928
  access: "create"
33667
33929
  },
33930
+ "nativeObjectDetection.setSettings": {
33931
+ capName: "native-object-detection",
33932
+ capScope: "device",
33933
+ addonId: null,
33934
+ access: "create"
33935
+ },
33668
33936
  "navigation.getFeatures": {
33669
33937
  capName: "navigation",
33670
33938
  capScope: "device",
@@ -33929,6 +34197,12 @@ Object.freeze({
33929
34197
  addonId: null,
33930
34198
  access: "view"
33931
34199
  },
34200
+ "notificationRules.getClipRetentionAsks": {
34201
+ capName: "notification-rules",
34202
+ capScope: "system",
34203
+ addonId: null,
34204
+ access: "view"
34205
+ },
33932
34206
  "notificationRules.getConditionCatalog": {
33933
34207
  capName: "notification-rules",
33934
34208
  capScope: "system",
@@ -34439,6 +34713,12 @@ Object.freeze({
34439
34713
  addonId: null,
34440
34714
  access: "create"
34441
34715
  },
34716
+ "pipelineAnalytics.readLongTermSeries": {
34717
+ capName: "pipeline-analytics",
34718
+ capScope: "device",
34719
+ addonId: null,
34720
+ access: "view"
34721
+ },
34442
34722
  "pipelineAnalytics.rebuildObjectEmbeddings": {
34443
34723
  capName: "pipeline-analytics",
34444
34724
  capScope: "device",
@@ -35111,6 +35391,12 @@ Object.freeze({
35111
35391
  addonId: null,
35112
35392
  access: "create"
35113
35393
  },
35394
+ "pipelineRunner.requestOccupancyBurst": {
35395
+ capName: "pipeline-runner",
35396
+ capScope: "system",
35397
+ addonId: null,
35398
+ access: "create"
35399
+ },
35114
35400
  "pipelineRunner.runDetailSubtree": {
35115
35401
  capName: "pipeline-runner",
35116
35402
  capScope: "system",
@@ -37891,11 +38177,21 @@ Object.freeze({
37891
38177
  form: "single",
37892
38178
  optional: false
37893
38179
  }],
38180
+ "nativeObjectDetection.getOptions": [{
38181
+ name: "deviceId",
38182
+ form: "single",
38183
+ optional: false
38184
+ }],
37894
38185
  "nativeObjectDetection.setEnabled": [{
37895
38186
  name: "deviceId",
37896
38187
  form: "single",
37897
38188
  optional: false
37898
38189
  }],
38190
+ "nativeObjectDetection.setSettings": [{
38191
+ name: "deviceId",
38192
+ form: "single",
38193
+ optional: false
38194
+ }],
37899
38195
  "navigation.getFeatures": [{
37900
38196
  name: "deviceId",
37901
38197
  form: "single",
@@ -38245,6 +38541,11 @@ Object.freeze({
38245
38541
  form: "single",
38246
38542
  optional: false
38247
38543
  }],
38544
+ "pipelineAnalytics.readLongTermSeries": [{
38545
+ name: "deviceId",
38546
+ form: "single",
38547
+ optional: false
38548
+ }],
38248
38549
  "pipelineAnalytics.rebuildObjectEmbeddings": [{
38249
38550
  name: "deviceId",
38250
38551
  form: "single",
@@ -38435,6 +38736,11 @@ Object.freeze({
38435
38736
  form: "single",
38436
38737
  optional: false
38437
38738
  }],
38739
+ "pipelineRunner.requestOccupancyBurst": [{
38740
+ name: "deviceId",
38741
+ form: "single",
38742
+ optional: false
38743
+ }],
38438
38744
  "pipelineRunner.runDetailSubtree": [{
38439
38745
  name: "deviceId",
38440
38746
  form: "single",
@@ -5384,7 +5384,7 @@ var ZodIssueCode = {
5384
5384
  var ZodFirstPartyTypeKind;
5385
5385
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5386
5386
  //#endregion
5387
- //#region ../types/dist/sleep-DEuj7E3j.mjs
5387
+ //#region ../types/dist/sleep-BDR76Ykr.mjs
5388
5388
  /**
5389
5389
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5390
5390
  * window to float samples (D455).
@@ -17842,6 +17842,48 @@ var NcAlarmConfigSchema = object({
17842
17842
  settings: NcAlarmSettingsSchema,
17843
17843
  coverage: array(NcAlarmModeCoverageSchema)
17844
17844
  });
17845
+ /**
17846
+ * ONE rule's demand on ONE camera's clip ring.
17847
+ *
17848
+ * A rule, not a camera: the broker takes the MAX over the asks that reach a
17849
+ * camera, so the answer stays a faithful description of the rules and the
17850
+ * bounding (the byte budget, the broker's own ceiling) stays where the cost
17851
+ * lives. A camera that appears in no ask is being told **nothing** — which is
17852
+ * a different thing from never having been told, and only the envelope
17853
+ * (`rulesLoaded`) can tell those apart.
17854
+ */
17855
+ var NcClipRetentionAskSchema = object({
17856
+ /**
17857
+ * The camera this ask is about. **Absent = every camera**, which is what a
17858
+ * rule with no `conditions.devices` means: it can fire anywhere, so it is
17859
+ * asking everywhere.
17860
+ */
17861
+ deviceId: number().int().nonnegative().optional(),
17862
+ /** Seconds of history the rule needs held for it. Never zero — a rule that
17863
+ * needs nothing produces no ask at all. */
17864
+ seconds: number().min(0).max(60),
17865
+ /** The profile the rule cuts from, when it named one. Absent = the cheapest
17866
+ * assigned, which is what the cut defaults to. */
17867
+ profile: CamProfileSchema.optional(),
17868
+ /** Who is asking — so a retention the operator did not expect names a rule. */
17869
+ ruleId: string(),
17870
+ ruleName: string(),
17871
+ /** Why this many seconds: the rule's own window, or the occupancy ceiling. */
17872
+ reason: _enum(["window", "occupancy"])
17873
+ });
17874
+ /**
17875
+ * The whole answer, with the one bit that keeps absence from reading as zero.
17876
+ *
17877
+ * `rulesLoaded` is false until the rule ledger has completed a load at least
17878
+ * once. A centre that is up but has not read its rules yet answers with an
17879
+ * empty ask list that means nothing at all — applying it would drop every
17880
+ * camera's ring to zero for the first events after a restart, which is the
17881
+ * footage this mechanism exists to keep.
17882
+ */
17883
+ var NcClipRetentionPlanSchema = object({
17884
+ rulesLoaded: boolean(),
17885
+ asks: array(NcClipRetentionAskSchema).readonly()
17886
+ });
17845
17887
  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 }), {
17846
17888
  kind: "mutation",
17847
17889
  auth: "admin",
@@ -17862,7 +17904,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
17862
17904
  }), object({ success: literal(true) }), {
17863
17905
  kind: "mutation",
17864
17906
  auth: "admin"
17865
- }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
17907
+ }), method(object({}), NcClipRetentionPlanSchema, { auth: "admin" }), method(object({}), object({ mutedDeviceIds: array(number().int()).readonly() }), { auth: "admin" }), method(object({
17866
17908
  deviceId: number().int(),
17867
17909
  muted: boolean()
17868
17910
  }), object({ success: literal(true) }), {
@@ -19007,13 +19049,26 @@ var TrackAudioLabelSchema = object({
19007
19049
  * - `audio` — an audio event on the camera itself that was anomalous for
19008
19050
  * THAT camera, loud, and heard while nothing visual was happening (D62).
19009
19051
  *
19052
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19053
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19054
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19055
+ * detector.
19056
+ *
19057
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19058
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19059
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19060
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19061
+ * could not name.
19062
+ *
19010
19063
  * The spatial subsystems (tracker association, occupancy count, re-id /
19011
19064
  * embedding, resurrection) MUST skip every synthetic source. Test for that
19012
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
19013
- * check silently readmits every source added after it was written.
19065
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19066
+ * `!== 'sensor'` check silently readmits every source added after it was
19067
+ * written.
19014
19068
  */
19015
19069
  var TrackSourceSchema = _enum([
19016
19070
  "pipeline",
19071
+ "onboard",
19017
19072
  "sensor",
19018
19073
  "audio"
19019
19074
  ]);
@@ -20396,6 +20451,33 @@ var RunReplayFrameProcessorResultSchema = object({ tracks: array(object({
20396
20451
  * solid is this track", cheaper than re-deriving it from a trajectory. */
20397
20452
  framesMatched: number().int()
20398
20453
  })).readonly() });
20454
+ /**
20455
+ * The long-term series a camera produces. A closed union so a typo cannot
20456
+ * invent one, and the ONE declaration of it — the addon's `AnalyticsLtsSeries`
20457
+ * is an alias of this, not a second list.
20458
+ */
20459
+ var AnalyticsLtsSeriesSchema = _enum([
20460
+ "motion",
20461
+ "audio-dbfs",
20462
+ "battery",
20463
+ "occupancy"
20464
+ ]);
20465
+ /**
20466
+ * One closed 5-minute bucket of a long-term series.
20467
+ *
20468
+ * `samples` is how many readings the bucket folded — it is the ACTIVITY for a
20469
+ * series like `motion`, and the confidence for one like `occupancy`. A bucket
20470
+ * that exists at all was measured; a bucket that is absent was not, which is a
20471
+ * different claim from zero and the reason this is a sparse series.
20472
+ */
20473
+ var LtsBucketSchema = object({
20474
+ scope: string(),
20475
+ bucketStart: number().int(),
20476
+ samples: number().int().nonnegative(),
20477
+ sum: number(),
20478
+ min: number(),
20479
+ max: number()
20480
+ });
20399
20481
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
20400
20482
  deviceId: number(),
20401
20483
  trackId: string()
@@ -20442,6 +20524,14 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20442
20524
  kinds: array(string()).optional(),
20443
20525
  limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
20444
20526
  }), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(KeyEventBatchQueryInput, array(KeyEventsForDeviceSchema).readonly()), method(object({
20527
+ deviceId: number(),
20528
+ series: AnalyticsLtsSeriesSchema,
20529
+ /** Omit for EVERY scope of this series in the range. */
20530
+ scope: string().optional(),
20531
+ from: number(),
20532
+ to: number(),
20533
+ limit: number().int().positive().optional()
20534
+ }), array(LtsBucketSchema).readonly()), method(object({
20445
20535
  deviceId: number(),
20446
20536
  since: number(),
20447
20537
  until: number(),
@@ -21060,6 +21150,40 @@ var MotionSourceEnum = _enum([
21060
21150
  */
21061
21151
  var MotionSourcesSchema = array(MotionSourceEnum);
21062
21152
  /**
21153
+ * Which root detector a camera runs — EXACTLY ONE.
21154
+ *
21155
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
21156
+ * with (`DetectionSource`) rather than a second spelling of the same two
21157
+ * ideas: the value an operator picks here is the value that comes back on the
21158
+ * track, the overlay and the debug row.
21159
+ *
21160
+ * ## Why one, and why it is still an array
21161
+ *
21162
+ * Two roots on one camera is a capability nobody asked for and the operator has
21163
+ * since ruled out. It was never free: both planes feed the SAME per-device
21164
+ * stationary registry, both can promote the same parked object, and the two
21165
+ * detectors disagree about the same box by construction — which is the
21166
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
21167
+ *
21168
+ * The ARRAY shape survives because the stored settings and the attach payload
21169
+ * already speak it on every camera of every fleet, and a cap input that
21170
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
21171
+ * in the one direction that costs an operator their cameras. So the wire stays
21172
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
21173
+ * element rather than refused, and `max(1)` is what every consumer can then
21174
+ * rely on.
21175
+ *
21176
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
21177
+ * a camera an operator left with no root detector — and `planDetectionSources`
21178
+ * has always said so: inventing a root for them is how a default acts without
21179
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
21180
+ * suite caught it.
21181
+ *
21182
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
21183
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
21184
+ */
21185
+ var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
21186
+ /**
21063
21187
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
21064
21188
  * so cap-side consumers (the orchestrator forward, the runner addon's
21065
21189
  * cap implementation, tests) can reuse the type instead of redeclaring
@@ -21210,6 +21334,35 @@ var RunnerCameraConfigSchema = object({
21210
21334
  * events; the orchestrator forwards to `reportMotion`.
21211
21335
  */
21212
21336
  motionSources: MotionSourcesSchema.default(["analyzer"]),
21337
+ /**
21338
+ * WHICH root detector runs for this camera. The detection counterpart of
21339
+ * {@link motionSources}, same shape and same discipline: a per-camera list
21340
+ * of sources the system understands, vendor-agnostic, owned here.
21341
+ *
21342
+ * - `pipeline` — this runner's own root step on decoded pixels (`steps`).
21343
+ * - `onboard` — the CAMERA's own detector, admitted only when it is named
21344
+ * here. Its boxes reach post-analysis on the same
21345
+ * `PipelineInferenceResult` payload as the pipeline's, so an onboard-born
21346
+ * track gets the same tracker, the same overlay and the same detail
21347
+ * subtree (face / plate / embedding).
21348
+ *
21349
+ * `['onboard']` alone is the REPLACEMENT: this runner's root step does not
21350
+ * run, and that is where a camera with a usable onboard detector buys back
21351
+ * its share of the accelerator. It saves the root inference, not the decode
21352
+ * — the detail subtree still needs pixels to cut crops from.
21353
+ *
21354
+ * A camera whose onboard detections carry no geometry cannot serve as a root
21355
+ * step at all (there is nothing to track), and the cap that knows this says
21356
+ * so on `native-object-detection.getOptions().geometry`. On Reolink that is
21357
+ * every battery camera: the boxes ride a sub-stream a battery camera never
21358
+ * attaches, so such a camera stays on `['pipeline']` and its onboard AI is
21359
+ * worth exactly what it already is — a wake signal with a class.
21360
+ *
21361
+ * Defaults to `['pipeline']`, which is byte-for-byte today's behaviour: a
21362
+ * vendor never turns a detector on for the operator, and neither does a
21363
+ * default.
21364
+ */
21365
+ detectionSources: DetectionSourcesSchema.default(["pipeline"]),
21213
21366
  pipelineEnabled: boolean().default(true),
21214
21367
  /** Ordered tree of video steps. Absent → runner skips video detection. */
21215
21368
  steps: array(PipelineStepInputSchema).readonly().optional(),
@@ -21391,7 +21544,47 @@ var RunnerLocalMetricsSchema = object({
21391
21544
  queueDepth: number(),
21392
21545
  frameLazy: FrameLazyMetricsSchema.optional()
21393
21546
  });
21547
+ /**
21548
+ * Pipeline Runner capability — runtime detection workhorse.
21549
+ *
21550
+ * One instance per node. Receives camera assignments from
21551
+ * `addon-pipeline-orchestrator`, subscribes to the local stream-broker for
21552
+ * decoded frames, drains motion + detection queues, calls the local
21553
+ * `motion-detection` and `pipeline-executor` capabilities, and emits typed
21554
+ * `pipeline.inference-result` and `detection.motion-analysis` events on
21555
+ * the bus.
21556
+ *
21557
+ * Distinct from `pipeline-orchestrator` (the hub-side load balancer) — the
21558
+ * runner has zero knowledge of other agents, no global state, and never
21559
+ * makes assignment decisions itself.
21560
+ */
21561
+ /**
21562
+ * Why a runner declined to look at a camera out of band. Named rather than a
21563
+ * bare `false`: a camera asleep on battery (D173), one attached elsewhere, one
21564
+ * already mid-session and one already bursting are four different facts, and a
21565
+ * caller told only "no" cannot tell a protection from a bug.
21566
+ */
21567
+ var OccupancyBurstRefusalSchema = _enum([
21568
+ "not-attached",
21569
+ "battery-asleep",
21570
+ "not-watching",
21571
+ "already-bursting"
21572
+ ]);
21394
21573
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
21574
+ deviceId: number(),
21575
+ /** How many frames to collect. The caller sizes this against what its
21576
+ * own confirmation needs; the runner clamps it to the field's range. */
21577
+ frames: number().int().positive().optional(),
21578
+ /** Why, for the log. A burst nobody can attribute is a cost nobody can
21579
+ * defend — the periodic one at least has a timer to point at. */
21580
+ reason: string()
21581
+ }), object({
21582
+ started: boolean(),
21583
+ refusedBecause: OccupancyBurstRefusalSchema.optional()
21584
+ }), {
21585
+ auth: "admin",
21586
+ kind: "mutation"
21587
+ }), method(object({
21395
21588
  handle: FrameHandleSchema,
21396
21589
  bbox: NativeCropBboxSchema,
21397
21590
  maxWidth: number().int().positive().optional(),
@@ -26920,7 +27113,7 @@ var NativeDetectionSchema = object({
26920
27113
  /** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
26921
27114
  confidence: number().min(0).max(1).optional()
26922
27115
  });
26923
- object({
27116
+ var NativeObjectDetectionStatusSchema = object({
26924
27117
  /**
26925
27118
  * Last observed instance per class. Missing entries mean the class
26926
27119
  * is supported but nothing has been seen since the provider started.
@@ -26937,14 +27130,56 @@ object({
26937
27130
  supportedClasses: array(NativeObjectClassEnum).readonly(),
26938
27131
  /**
26939
27132
  * Whether forwarding of onboard AI detections is enabled for this device.
26940
- * Default FALSE (opt-in, cold-start) — onboard AI pushes are noisy/sparse and
26941
- * churn the tracker, so forwarding stays off until the operator enables it.
27133
+ *
27134
+ * Cold-start OFF on every camera. A vendor does not decide which detector a
27135
+ * camera runs — that is the operator's choice, and it is made where every
27136
+ * other detection choice is made. `geometry` on
27137
+ * {@link NativeObjectDetectionOptionsSchema} is how the form says what the
27138
+ * choice would buy this particular camera.
26942
27139
  */
26943
27140
  enabled: boolean()
26944
- }).extend({
27141
+ });
27142
+ /**
27143
+ * WHEN a camera's onboard detections carry geometry.
27144
+ *
27145
+ * - `boxed` — always. The provider holds a standing channel for the boxes, so
27146
+ * a detection is a trackable subject whenever the camera sees one.
27147
+ * - `while-streaming` — only while some stream of this camera is already open.
27148
+ * The boxes ride the video's own side-channel rather than a feed of their
27149
+ * own, so they cost nothing and they exist only when something is pulling.
27150
+ * On Reolink this is every BATTERY camera: a persistent second feed is real
27151
+ * radio drain, but a camera that is awake is awake precisely because
27152
+ * something is in front of it, and its stream is already being pulled.
27153
+ * - `flag-only` — never. The firmware ships the class and nothing else; the
27154
+ * pipeline needs geometry to make a subject, so such a push reaches the
27155
+ * tracker as motion and no further.
27156
+ *
27157
+ * Reported and not inferred, because the operator's question in front of the
27158
+ * picker is "what do I get", and these are three different answers (D14: the
27159
+ * derived form is only as honest as `getOptions`).
27160
+ */
27161
+ var NativeObjectGeometryEnum = _enum([
27162
+ "boxed",
27163
+ "while-streaming",
27164
+ "flag-only"
27165
+ ]);
27166
+ var NativeObjectDetectionOptionsSchema = object({
27167
+ /** Classes this firmware can detect — the same list the status reports. */
27168
+ supportedClasses: array(NativeObjectClassEnum).readonly(),
27169
+ /** What a detection from this camera carries. */
27170
+ geometry: NativeObjectGeometryEnum
27171
+ });
27172
+ var NativeObjectDetectionSettingsPatchSchema = object({ enabled: boolean().optional() });
27173
+ NativeObjectDetectionStatusSchema.extend({
26945
27174
  /** Required by createRuntimeStateBridge — epoch ms of last refresh. */
26946
27175
  lastFetchedAt: number() });
26947
- DeviceType.Camera, method(object({
27176
+ DeviceType.Camera, method(object({ deviceId: number() }), NativeObjectDetectionOptionsSchema), method(object({
27177
+ deviceId: number(),
27178
+ settings: NativeObjectDetectionSettingsPatchSchema
27179
+ }), _void(), {
27180
+ kind: "mutation",
27181
+ auth: "admin"
27182
+ }), method(object({
26948
27183
  deviceId: number(),
26949
27184
  enabled: boolean()
26950
27185
  }), _void(), {
@@ -30743,7 +30978,28 @@ var PerScopeBreakdownSchema = object({
30743
30978
  /** Total tracked objects in this scope (frame / zone / unzoned). */
30744
30979
  totalObjects: number().int().nonnegative(),
30745
30980
  /** Per-class count. Keys are macro class names (e.g. `person`, `car`). */
30746
- byClass: record(string(), number().int().nonnegative())
30981
+ byClass: record(string(), number().int().nonnegative()),
30982
+ /**
30983
+ * Of `totalObjects`, how many are STANDING — objects the census holds,
30984
+ * present but not going anywhere (a parked car, a bin, a statue).
30985
+ *
30986
+ * The operator's question about a scene has two halves and they answer
30987
+ * different things: "what is parked here" is stable for hours and must not
30988
+ * flap, while "who is walking through" is the thing an alert is about. One
30989
+ * number could only serve one of them, and `totalObjects` served the first
30990
+ * badly — a passer-by moved it and every occupancy rule saw a change.
30991
+ *
30992
+ * `standing + transient === totalObjects`, always. The total keeps its old
30993
+ * meaning exactly, so no rule written against it changes behaviour.
30994
+ *
30995
+ * ABSENT means UNKNOWN, never zero (D393): a snapshot from a node older than
30996
+ * this field cannot say, and a reader that folds absence in as 0 reports "no
30997
+ * parked objects here" about a camera whose lot is full.
30998
+ */
30999
+ standingObjects: number().int().nonnegative().optional(),
31000
+ /** Of `totalObjects`, how many are passing through. See `standingObjects` —
31001
+ * same absence rule. */
31002
+ transientObjects: number().int().nonnegative().optional()
30747
31003
  });
30748
31004
  var ZoneScopeBreakdownSchema = PerScopeBreakdownSchema.extend({
30749
31005
  zoneId: string(),
@@ -33682,12 +33938,24 @@ Object.freeze({
33682
33938
  addonId: null,
33683
33939
  access: "create"
33684
33940
  },
33941
+ "nativeObjectDetection.getOptions": {
33942
+ capName: "native-object-detection",
33943
+ capScope: "device",
33944
+ addonId: null,
33945
+ access: "view"
33946
+ },
33685
33947
  "nativeObjectDetection.setEnabled": {
33686
33948
  capName: "native-object-detection",
33687
33949
  capScope: "device",
33688
33950
  addonId: null,
33689
33951
  access: "create"
33690
33952
  },
33953
+ "nativeObjectDetection.setSettings": {
33954
+ capName: "native-object-detection",
33955
+ capScope: "device",
33956
+ addonId: null,
33957
+ access: "create"
33958
+ },
33691
33959
  "navigation.getFeatures": {
33692
33960
  capName: "navigation",
33693
33961
  capScope: "device",
@@ -33952,6 +34220,12 @@ Object.freeze({
33952
34220
  addonId: null,
33953
34221
  access: "view"
33954
34222
  },
34223
+ "notificationRules.getClipRetentionAsks": {
34224
+ capName: "notification-rules",
34225
+ capScope: "system",
34226
+ addonId: null,
34227
+ access: "view"
34228
+ },
33955
34229
  "notificationRules.getConditionCatalog": {
33956
34230
  capName: "notification-rules",
33957
34231
  capScope: "system",
@@ -34462,6 +34736,12 @@ Object.freeze({
34462
34736
  addonId: null,
34463
34737
  access: "create"
34464
34738
  },
34739
+ "pipelineAnalytics.readLongTermSeries": {
34740
+ capName: "pipeline-analytics",
34741
+ capScope: "device",
34742
+ addonId: null,
34743
+ access: "view"
34744
+ },
34465
34745
  "pipelineAnalytics.rebuildObjectEmbeddings": {
34466
34746
  capName: "pipeline-analytics",
34467
34747
  capScope: "device",
@@ -35134,6 +35414,12 @@ Object.freeze({
35134
35414
  addonId: null,
35135
35415
  access: "create"
35136
35416
  },
35417
+ "pipelineRunner.requestOccupancyBurst": {
35418
+ capName: "pipeline-runner",
35419
+ capScope: "system",
35420
+ addonId: null,
35421
+ access: "create"
35422
+ },
35137
35423
  "pipelineRunner.runDetailSubtree": {
35138
35424
  capName: "pipeline-runner",
35139
35425
  capScope: "system",
@@ -37914,11 +38200,21 @@ Object.freeze({
37914
38200
  form: "single",
37915
38201
  optional: false
37916
38202
  }],
38203
+ "nativeObjectDetection.getOptions": [{
38204
+ name: "deviceId",
38205
+ form: "single",
38206
+ optional: false
38207
+ }],
37917
38208
  "nativeObjectDetection.setEnabled": [{
37918
38209
  name: "deviceId",
37919
38210
  form: "single",
37920
38211
  optional: false
37921
38212
  }],
38213
+ "nativeObjectDetection.setSettings": [{
38214
+ name: "deviceId",
38215
+ form: "single",
38216
+ optional: false
38217
+ }],
37922
38218
  "navigation.getFeatures": [{
37923
38219
  name: "deviceId",
37924
38220
  form: "single",
@@ -38268,6 +38564,11 @@ Object.freeze({
38268
38564
  form: "single",
38269
38565
  optional: false
38270
38566
  }],
38567
+ "pipelineAnalytics.readLongTermSeries": [{
38568
+ name: "deviceId",
38569
+ form: "single",
38570
+ optional: false
38571
+ }],
38271
38572
  "pipelineAnalytics.rebuildObjectEmbeddings": [{
38272
38573
  name: "deviceId",
38273
38574
  form: "single",
@@ -38458,6 +38759,11 @@ Object.freeze({
38458
38759
  form: "single",
38459
38760
  optional: false
38460
38761
  }],
38762
+ "pipelineRunner.requestOccupancyBurst": [{
38763
+ name: "deviceId",
38764
+ form: "single",
38765
+ optional: false
38766
+ }],
38461
38767
  "pipelineRunner.runDetailSubtree": [{
38462
38768
  name: "deviceId",
38463
38769
  form: "single",
package/dist/smb.addon.js CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-SgmN8tGm.js");
5
+ const require_shared = require("./shared-DqWt_U16.js");
6
6
  let node_crypto = require("node:crypto");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_shared.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, s as storageProviderCapability } from "./shared-C0LzFm0z.mjs";
1
+ import { c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, s as storageProviderCapability } from "./shared-DPTTju9B.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import * as path from "node:path";
4
4
  import * as fsp from "node:fs/promises";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-SgmN8tGm.js");
5
+ const require_shared = require("./shared-DqWt_U16.js");
6
6
  let node_stream = require("node:stream");
7
7
  let webdav = require("webdav");
8
8
  //#region src/providers/webdav/webdav-config-schema.ts
@@ -1,4 +1,4 @@
1
- import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-C0LzFm0z.mjs";
1
+ import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-DPTTju9B.mjs";
2
2
  import { PassThrough } from "node:stream";
3
3
  import { AuthType, createClient } from "webdav";
4
4
  //#region src/providers/webdav/webdav-config-schema.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-remote-storage",
3
- "version": "1.2.101",
3
+ "version": "1.2.103",
4
4
  "description": "Remote storage providers (SFTP, S3, WebDAV, SMB) — unifies remote backends behind the storage-provider cap",
5
5
  "keywords": [
6
6
  "camstack",