@camstack/addon-provider-reolink 1.1.22 → 1.1.24

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/addon.js CHANGED
@@ -4655,7 +4655,7 @@ function _instanceof(cls, params = {}) {
4655
4655
  return inst;
4656
4656
  }
4657
4657
  //#endregion
4658
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4658
+ //#region ../types/dist/sleep-Baang_XW.mjs
4659
4659
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4660
4660
  EventCategory["SystemBoot"] = "system.boot";
4661
4661
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6759,6 +6759,18 @@ function method(input, output, options) {
6759
6759
  timeoutMs: options?.timeoutMs
6760
6760
  };
6761
6761
  }
6762
+ /**
6763
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6764
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6765
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6766
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6767
+ */
6768
+ function systemMethod(input, output, options) {
6769
+ return {
6770
+ ...method(input, output, options),
6771
+ systemOnly: true
6772
+ };
6773
+ }
6762
6774
  /** Shorthand to define an event schema */
6763
6775
  function event(data) {
6764
6776
  return { data };
@@ -12000,6 +12012,7 @@ var PipelineAddonSchemaSchema = object({
12000
12012
  defaultModelId: string(),
12001
12013
  defaultModelIdByFormat: record(string(), string()).optional(),
12002
12014
  enabledByDefault: boolean().optional(),
12015
+ backfillIntoExistingOverrides: boolean().optional(),
12003
12016
  defaultConfidence: number(),
12004
12017
  group: string().optional(),
12005
12018
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -12181,7 +12194,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12181
12194
  image: _instanceof(Uint8Array).optional(),
12182
12195
  referenceImage: string().optional(),
12183
12196
  deviceId: number().optional(),
12184
- sessionId: string().optional()
12197
+ sessionId: string().optional(),
12198
+ /**
12199
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
12200
+ * reference-image, and detail-subtree calls. 'frame' is the live
12201
+ * per-frame dispatch: ONLY root-plane steps run; crop children
12202
+ * (inputClasses ≠ null) are skipped and served per-track via
12203
+ * pipelineRunner.runDetailSubtree (two-plane design).
12204
+ */
12205
+ plane: _enum(["full", "frame"]).optional()
12185
12206
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
12186
12207
  engine: PipelineEngineChoiceSchema.optional(),
12187
12208
  steps: array(PipelineStepInputSchema).min(1),
@@ -12339,6 +12360,47 @@ var zonesCapability = {
12339
12360
  runtimeState: object({ zones: array(ZoneSchema).readonly() })
12340
12361
  };
12341
12362
  /**
12363
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
12364
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
12365
+ * so the caller supplies only the detection-res bbox divided by the detection
12366
+ * dims — no native resolution to plumb.
12367
+ */
12368
+ var NativeCropBboxSchema = object({
12369
+ x: number(),
12370
+ y: number(),
12371
+ w: number(),
12372
+ h: number()
12373
+ });
12374
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
12375
+ var NativeCropResultSchema = object({
12376
+ /** Packed rgb (24-bit) pixels of the crop. */
12377
+ bytes: _instanceof(Uint8Array),
12378
+ width: number().int().positive(),
12379
+ height: number().int().positive()
12380
+ });
12381
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
12382
+ * originating detection, in FRAME-space coordinates. Reuses
12383
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
12384
+ * the coordinates are frame-space rather than getNativeCrop's
12385
+ * normalized [0,1] convention). */
12386
+ var DetailParentSchema = object({
12387
+ bbox: NativeCropBboxSchema,
12388
+ className: string()
12389
+ });
12390
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
12391
+ * or refined detection produced by running the crop-subtree on a
12392
+ * single tracked detection. */
12393
+ var DetailResultSchema = object({
12394
+ stepId: string(),
12395
+ className: string(),
12396
+ score: number(),
12397
+ /** FRAME-space bbox (already mapped back from crop space). */
12398
+ bbox: NativeCropBboxSchema.optional(),
12399
+ embedding: string().optional(),
12400
+ label: string().optional(),
12401
+ alignedCropJpeg: string().optional()
12402
+ });
12403
+ /**
12342
12404
  * Per-camera tunable ranges + defaults. Single source of truth used
12343
12405
  * by both the Zod data schema (validation + default fallback) and
12344
12406
  * the device settings UI (slider min/max/step). Touch one place and
@@ -12594,7 +12656,17 @@ var RunnerLocalMetricsSchema = object({
12594
12656
  avgInferenceTimeMs: number(),
12595
12657
  queueDepth: number()
12596
12658
  });
12597
- 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());
12659
+ 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({
12660
+ handle: FrameHandleSchema,
12661
+ bbox: NativeCropBboxSchema,
12662
+ maxWidth: number().int().positive().optional()
12663
+ }), NativeCropResultSchema.nullable()), method(object({
12664
+ deviceId: number(),
12665
+ frameHandle: FrameHandleSchema.optional(),
12666
+ cropJpeg: string().optional(),
12667
+ parent: DetailParentSchema,
12668
+ steps: array(string()).optional()
12669
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
12598
12670
  /**
12599
12671
  * Hardware / firmware motion sensor cap — binary detected state plus
12600
12672
  * a timestamp of the last observation. Distinct from
@@ -18281,7 +18353,17 @@ var TrackSchema = object({
18281
18353
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
18282
18354
  totalDistance: number(),
18283
18355
  state: TrackStateSchema,
18284
- active: boolean()
18356
+ active: boolean(),
18357
+ /** Deterministic key-event importance score in [0,1] (server-computed at
18358
+ * track expiry, recomputed on late label). Absent on legacy rows written
18359
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
18360
+ importance: number().optional(),
18361
+ /** Id of the track's highest-confidence ObjectEvent (its representative
18362
+ * "best" frame). Absent when the track produced no object events. */
18363
+ bestEventId: string().optional(),
18364
+ /** Tag of the importance sub-signal that dominated the score
18365
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
18366
+ importanceReason: string().optional()
18285
18367
  });
18286
18368
  var BaseEventFields = {
18287
18369
  id: string(),
@@ -18346,8 +18428,18 @@ var ObjectEventSchema = object({
18346
18428
  frameHeight: number().optional(),
18347
18429
  /** MediaStore key for the crop attached to this event (if any). */
18348
18430
  mediaKey: string().optional(),
18431
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
18432
+ * best-detection full frame). Resolve via the event-media data-plane
18433
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
18434
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
18435
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
18436
+ keyFrameMediaKey: string().optional(),
18349
18437
  /** Populated by B5 (recording playback URL for this event). */
18350
- mediaUrl: string().optional()
18438
+ mediaUrl: string().optional(),
18439
+ /** The parent track's key-event importance [0,1], propagated to every object
18440
+ * event of the track (so an event row can be sorted by importance without a
18441
+ * track join). Absent on legacy rows / before the track was scored. */
18442
+ importance: number().optional()
18351
18443
  });
18352
18444
  var AudioEventSchema = object({
18353
18445
  ...BaseEventFields,
@@ -18371,7 +18463,8 @@ var MediaFileKindEnum = _enum([
18371
18463
  "fullFrame",
18372
18464
  "fullFrameBoxed",
18373
18465
  "faceCrop",
18374
- "plateCrop"
18466
+ "plateCrop",
18467
+ "keyFrame"
18375
18468
  ]);
18376
18469
  var MediaFileSchema = object({
18377
18470
  key: string(),
@@ -18392,6 +18485,32 @@ var DeviceEventQueryInput = object({
18392
18485
  projection: _enum(["full", "slim"]).optional()
18393
18486
  });
18394
18487
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
18488
+ var KeyEventQueryInput = object({
18489
+ deviceId: number(),
18490
+ /** Window lower bound (track firstSeen ≥ since). */
18491
+ since: number(),
18492
+ /** Window upper bound (track firstSeen ≤ until). */
18493
+ until: number(),
18494
+ limit: number().int().min(1).max(200).default(50),
18495
+ /** Drop tracks scoring below this importance. */
18496
+ minImportance: number().min(0).max(1).optional(),
18497
+ /** Restrict to a single class (e.g. 'person'). */
18498
+ classFilter: string().optional()
18499
+ });
18500
+ var KeyEventSchema = object({
18501
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
18502
+ id: string(),
18503
+ trackId: string(),
18504
+ /** Track start time (firstSeen). */
18505
+ timestamp: number(),
18506
+ className: string(),
18507
+ label: string().optional(),
18508
+ importance: number(),
18509
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
18510
+ bestEventId: string(),
18511
+ /** Track lifetime in ms (lastSeen - firstSeen). */
18512
+ windowMs: number().optional()
18513
+ });
18395
18514
  var TrackedDetectionSchema = object({
18396
18515
  trackId: string(),
18397
18516
  className: string(),
@@ -18421,7 +18540,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18421
18540
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
18422
18541
  kind: "mutation",
18423
18542
  auth: "admin"
18424
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
18543
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
18425
18544
  deviceId: number(),
18426
18545
  since: number(),
18427
18546
  until: number(),
@@ -19225,7 +19344,20 @@ var snapshotCapability = {
19225
19344
  invalidateCache: method(object({ deviceId: number() }), _void(), {
19226
19345
  kind: "mutation",
19227
19346
  auth: "admin"
19228
- })
19347
+ }),
19348
+ /**
19349
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
19350
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
19351
+ * devices that never produced a frame, and gives it an ETag per device for
19352
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
19353
+ * are null for a device with no cached frame.
19354
+ */
19355
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
19356
+ deviceId: number(),
19357
+ lastCapturedAt: number().nullable(),
19358
+ cacheAgeMs: number().nullable(),
19359
+ etag: string().nullable()
19360
+ })))
19229
19361
  },
19230
19362
  status: {
19231
19363
  schema: SnapshotStatusSchema,
@@ -19482,10 +19614,32 @@ method(_void(), array(TurnServerSchema).readonly());
19482
19614
  * b. `finishAuthentication({userId, response})` → server verifies
19483
19615
  * the assertion, bumps the credential counter, returns ok.
19484
19616
  *
19617
+ * 2b. Usernameless (discoverable-credential) authentication — the
19618
+ * passkey IS the primary factor, no password leg:
19619
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
19620
+ * EMPTY `allowCredentials` (the browser offers every resident
19621
+ * passkey it holds for this RP) + `userVerification: 'required'`
19622
+ * (the passkey replaces both factors, so UV is mandatory).
19623
+ * The challenge is stored server-side, NOT bound to any user.
19624
+ * b. `finishDiscoverableAuthentication({response})` → the provider
19625
+ * resolves the credential by the response's credential id,
19626
+ * verifies the assertion against the stored challenge + that
19627
+ * credential's public key/counter, and returns the OWNING
19628
+ * `userId` — the caller (core auth router) mints the session.
19629
+ *
19485
19630
  * 3. Management:
19486
19631
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
19487
19632
  * - `removePasskey({userId, credentialId})` — revoke one credential.
19488
19633
  *
19634
+ * 4. Second-factor preference (opt-in, default OFF):
19635
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
19636
+ * demanded as a second factor after a password login ONLY when the
19637
+ * user explicitly opts in via `setSecondFactorPreference`.
19638
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
19639
+ * row ⇒ `enabled: false`).
19640
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
19641
+ * the providing addon beside its credentials.
19642
+ *
19489
19643
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
19490
19644
  * the admin-ui composes the begin/finish round-trip and never exposes
19491
19645
  * the cap to non-admins.
@@ -19528,6 +19682,17 @@ method(object({
19528
19682
  }), object({ verified: boolean() }), {
19529
19683
  kind: "mutation",
19530
19684
  access: "view"
19685
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
19686
+ kind: "mutation",
19687
+ access: "view"
19688
+ }), method(object({
19689
+ /** AuthenticationResponseJSON from the browser. */
19690
+ response: record(string(), unknown()) }), object({
19691
+ verified: boolean(),
19692
+ userId: string().nullable()
19693
+ }), {
19694
+ kind: "mutation",
19695
+ access: "view"
19531
19696
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
19532
19697
  userId: string(),
19533
19698
  credentialId: string()
@@ -19535,6 +19700,13 @@ method(object({
19535
19700
  kind: "mutation",
19536
19701
  auth: "admin",
19537
19702
  access: "delete"
19703
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
19704
+ userId: string(),
19705
+ enabled: boolean()
19706
+ }), object({ success: literal(true) }), {
19707
+ kind: "mutation",
19708
+ auth: "admin",
19709
+ access: "create"
19538
19710
  });
19539
19711
  /**
19540
19712
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -20336,7 +20508,17 @@ var FaceInfoSchema = object({
20336
20508
  recognizedIdentityId: string().optional(),
20337
20509
  identityName: string().optional(),
20338
20510
  assigned: boolean(),
20339
- base64: string().optional()
20511
+ base64: string().optional(),
20512
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
20513
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
20514
+ * legacy rows written before design B. */
20515
+ faceBbox: BoundingBoxSchema.optional(),
20516
+ /** Design B: MediaStore key of the track's native-resolution key frame.
20517
+ * Fetch the native JPEG via the event-media data-plane
20518
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
20519
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
20520
+ * back to the inline `base64` face crop. */
20521
+ keyFrameMediaKey: string().optional()
20340
20522
  });
20341
20523
  var FaceFilterEnum = _enum([
20342
20524
  "unassigned",
@@ -24784,6 +24966,12 @@ Object.freeze({
24784
24966
  addonId: null,
24785
24967
  access: "view"
24786
24968
  },
24969
+ "pipelineAnalytics.getKeyEvents": {
24970
+ capName: "pipeline-analytics",
24971
+ capScope: "device",
24972
+ addonId: null,
24973
+ access: "view"
24974
+ },
24787
24975
  "pipelineAnalytics.getMotionEvents": {
24788
24976
  capName: "pipeline-analytics",
24789
24977
  capScope: "device",
@@ -25312,12 +25500,24 @@ Object.freeze({
25312
25500
  addonId: null,
25313
25501
  access: "view"
25314
25502
  },
25503
+ "pipelineRunner.getNativeCrop": {
25504
+ capName: "pipeline-runner",
25505
+ capScope: "system",
25506
+ addonId: null,
25507
+ access: "view"
25508
+ },
25315
25509
  "pipelineRunner.reportMotion": {
25316
25510
  capName: "pipeline-runner",
25317
25511
  capScope: "system",
25318
25512
  addonId: null,
25319
25513
  access: "create"
25320
25514
  },
25515
+ "pipelineRunner.runDetailSubtree": {
25516
+ capName: "pipeline-runner",
25517
+ capScope: "system",
25518
+ addonId: null,
25519
+ access: "create"
25520
+ },
25321
25521
  "plateGallery.correctPlateText": {
25322
25522
  capName: "plate-gallery",
25323
25523
  capScope: "system",
@@ -25678,6 +25878,12 @@ Object.freeze({
25678
25878
  addonId: null,
25679
25879
  access: "view"
25680
25880
  },
25881
+ "snapshot.getSnapshotOverview": {
25882
+ capName: "snapshot",
25883
+ capScope: "device",
25884
+ addonId: null,
25885
+ access: "view"
25886
+ },
25681
25887
  "snapshot.invalidateCache": {
25682
25888
  capName: "snapshot",
25683
25889
  capScope: "device",
@@ -26356,6 +26562,12 @@ Object.freeze({
26356
26562
  addonId: null,
26357
26563
  access: "view"
26358
26564
  },
26565
+ "userPasskeys.beginDiscoverableAuthentication": {
26566
+ capName: "user-passkeys",
26567
+ capScope: "system",
26568
+ addonId: null,
26569
+ access: "view"
26570
+ },
26359
26571
  "userPasskeys.beginRegistration": {
26360
26572
  capName: "user-passkeys",
26361
26573
  capScope: "system",
@@ -26368,12 +26580,24 @@ Object.freeze({
26368
26580
  addonId: null,
26369
26581
  access: "view"
26370
26582
  },
26583
+ "userPasskeys.finishDiscoverableAuthentication": {
26584
+ capName: "user-passkeys",
26585
+ capScope: "system",
26586
+ addonId: null,
26587
+ access: "view"
26588
+ },
26371
26589
  "userPasskeys.finishRegistration": {
26372
26590
  capName: "user-passkeys",
26373
26591
  capScope: "system",
26374
26592
  addonId: null,
26375
26593
  access: "create"
26376
26594
  },
26595
+ "userPasskeys.getSecondFactorPreference": {
26596
+ capName: "user-passkeys",
26597
+ capScope: "system",
26598
+ addonId: null,
26599
+ access: "view"
26600
+ },
26377
26601
  "userPasskeys.listPasskeys": {
26378
26602
  capName: "user-passkeys",
26379
26603
  capScope: "system",
@@ -26386,6 +26610,12 @@ Object.freeze({
26386
26610
  addonId: null,
26387
26611
  access: "delete"
26388
26612
  },
26613
+ "userPasskeys.setSecondFactorPreference": {
26614
+ capName: "user-passkeys",
26615
+ capScope: "system",
26616
+ addonId: null,
26617
+ access: "create"
26618
+ },
26389
26619
  "vacuumControl.locate": {
26390
26620
  capName: "vacuum-control",
26391
26621
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4650,7 +4650,7 @@ function _instanceof(cls, params = {}) {
4650
4650
  return inst;
4651
4651
  }
4652
4652
  //#endregion
4653
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4653
+ //#region ../types/dist/sleep-Baang_XW.mjs
4654
4654
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4655
4655
  EventCategory["SystemBoot"] = "system.boot";
4656
4656
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6754,6 +6754,18 @@ function method(input, output, options) {
6754
6754
  timeoutMs: options?.timeoutMs
6755
6755
  };
6756
6756
  }
6757
+ /**
6758
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6759
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6760
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6761
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6762
+ */
6763
+ function systemMethod(input, output, options) {
6764
+ return {
6765
+ ...method(input, output, options),
6766
+ systemOnly: true
6767
+ };
6768
+ }
6757
6769
  /** Shorthand to define an event schema */
6758
6770
  function event(data) {
6759
6771
  return { data };
@@ -11995,6 +12007,7 @@ var PipelineAddonSchemaSchema = object({
11995
12007
  defaultModelId: string(),
11996
12008
  defaultModelIdByFormat: record(string(), string()).optional(),
11997
12009
  enabledByDefault: boolean().optional(),
12010
+ backfillIntoExistingOverrides: boolean().optional(),
11998
12011
  defaultConfidence: number(),
11999
12012
  group: string().optional(),
12000
12013
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -12176,7 +12189,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12176
12189
  image: _instanceof(Uint8Array).optional(),
12177
12190
  referenceImage: string().optional(),
12178
12191
  deviceId: number().optional(),
12179
- sessionId: string().optional()
12192
+ sessionId: string().optional(),
12193
+ /**
12194
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
12195
+ * reference-image, and detail-subtree calls. 'frame' is the live
12196
+ * per-frame dispatch: ONLY root-plane steps run; crop children
12197
+ * (inputClasses ≠ null) are skipped and served per-track via
12198
+ * pipelineRunner.runDetailSubtree (two-plane design).
12199
+ */
12200
+ plane: _enum(["full", "frame"]).optional()
12180
12201
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
12181
12202
  engine: PipelineEngineChoiceSchema.optional(),
12182
12203
  steps: array(PipelineStepInputSchema).min(1),
@@ -12334,6 +12355,47 @@ var zonesCapability = {
12334
12355
  runtimeState: object({ zones: array(ZoneSchema).readonly() })
12335
12356
  };
12336
12357
  /**
12358
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
12359
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
12360
+ * so the caller supplies only the detection-res bbox divided by the detection
12361
+ * dims — no native resolution to plumb.
12362
+ */
12363
+ var NativeCropBboxSchema = object({
12364
+ x: number(),
12365
+ y: number(),
12366
+ w: number(),
12367
+ h: number()
12368
+ });
12369
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
12370
+ var NativeCropResultSchema = object({
12371
+ /** Packed rgb (24-bit) pixels of the crop. */
12372
+ bytes: _instanceof(Uint8Array),
12373
+ width: number().int().positive(),
12374
+ height: number().int().positive()
12375
+ });
12376
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
12377
+ * originating detection, in FRAME-space coordinates. Reuses
12378
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
12379
+ * the coordinates are frame-space rather than getNativeCrop's
12380
+ * normalized [0,1] convention). */
12381
+ var DetailParentSchema = object({
12382
+ bbox: NativeCropBboxSchema,
12383
+ className: string()
12384
+ });
12385
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
12386
+ * or refined detection produced by running the crop-subtree on a
12387
+ * single tracked detection. */
12388
+ var DetailResultSchema = object({
12389
+ stepId: string(),
12390
+ className: string(),
12391
+ score: number(),
12392
+ /** FRAME-space bbox (already mapped back from crop space). */
12393
+ bbox: NativeCropBboxSchema.optional(),
12394
+ embedding: string().optional(),
12395
+ label: string().optional(),
12396
+ alignedCropJpeg: string().optional()
12397
+ });
12398
+ /**
12337
12399
  * Per-camera tunable ranges + defaults. Single source of truth used
12338
12400
  * by both the Zod data schema (validation + default fallback) and
12339
12401
  * the device settings UI (slider min/max/step). Touch one place and
@@ -12589,7 +12651,17 @@ var RunnerLocalMetricsSchema = object({
12589
12651
  avgInferenceTimeMs: number(),
12590
12652
  queueDepth: number()
12591
12653
  });
12592
- 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());
12654
+ 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({
12655
+ handle: FrameHandleSchema,
12656
+ bbox: NativeCropBboxSchema,
12657
+ maxWidth: number().int().positive().optional()
12658
+ }), NativeCropResultSchema.nullable()), method(object({
12659
+ deviceId: number(),
12660
+ frameHandle: FrameHandleSchema.optional(),
12661
+ cropJpeg: string().optional(),
12662
+ parent: DetailParentSchema,
12663
+ steps: array(string()).optional()
12664
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
12593
12665
  /**
12594
12666
  * Hardware / firmware motion sensor cap — binary detected state plus
12595
12667
  * a timestamp of the last observation. Distinct from
@@ -18276,7 +18348,17 @@ var TrackSchema = object({
18276
18348
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
18277
18349
  totalDistance: number(),
18278
18350
  state: TrackStateSchema,
18279
- active: boolean()
18351
+ active: boolean(),
18352
+ /** Deterministic key-event importance score in [0,1] (server-computed at
18353
+ * track expiry, recomputed on late label). Absent on legacy rows written
18354
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
18355
+ importance: number().optional(),
18356
+ /** Id of the track's highest-confidence ObjectEvent (its representative
18357
+ * "best" frame). Absent when the track produced no object events. */
18358
+ bestEventId: string().optional(),
18359
+ /** Tag of the importance sub-signal that dominated the score
18360
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
18361
+ importanceReason: string().optional()
18280
18362
  });
18281
18363
  var BaseEventFields = {
18282
18364
  id: string(),
@@ -18341,8 +18423,18 @@ var ObjectEventSchema = object({
18341
18423
  frameHeight: number().optional(),
18342
18424
  /** MediaStore key for the crop attached to this event (if any). */
18343
18425
  mediaKey: string().optional(),
18426
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
18427
+ * best-detection full frame). Resolve via the event-media data-plane
18428
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
18429
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
18430
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
18431
+ keyFrameMediaKey: string().optional(),
18344
18432
  /** Populated by B5 (recording playback URL for this event). */
18345
- mediaUrl: string().optional()
18433
+ mediaUrl: string().optional(),
18434
+ /** The parent track's key-event importance [0,1], propagated to every object
18435
+ * event of the track (so an event row can be sorted by importance without a
18436
+ * track join). Absent on legacy rows / before the track was scored. */
18437
+ importance: number().optional()
18346
18438
  });
18347
18439
  var AudioEventSchema = object({
18348
18440
  ...BaseEventFields,
@@ -18366,7 +18458,8 @@ var MediaFileKindEnum = _enum([
18366
18458
  "fullFrame",
18367
18459
  "fullFrameBoxed",
18368
18460
  "faceCrop",
18369
- "plateCrop"
18461
+ "plateCrop",
18462
+ "keyFrame"
18370
18463
  ]);
18371
18464
  var MediaFileSchema = object({
18372
18465
  key: string(),
@@ -18387,6 +18480,32 @@ var DeviceEventQueryInput = object({
18387
18480
  projection: _enum(["full", "slim"]).optional()
18388
18481
  });
18389
18482
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
18483
+ var KeyEventQueryInput = object({
18484
+ deviceId: number(),
18485
+ /** Window lower bound (track firstSeen ≥ since). */
18486
+ since: number(),
18487
+ /** Window upper bound (track firstSeen ≤ until). */
18488
+ until: number(),
18489
+ limit: number().int().min(1).max(200).default(50),
18490
+ /** Drop tracks scoring below this importance. */
18491
+ minImportance: number().min(0).max(1).optional(),
18492
+ /** Restrict to a single class (e.g. 'person'). */
18493
+ classFilter: string().optional()
18494
+ });
18495
+ var KeyEventSchema = object({
18496
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
18497
+ id: string(),
18498
+ trackId: string(),
18499
+ /** Track start time (firstSeen). */
18500
+ timestamp: number(),
18501
+ className: string(),
18502
+ label: string().optional(),
18503
+ importance: number(),
18504
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
18505
+ bestEventId: string(),
18506
+ /** Track lifetime in ms (lastSeen - firstSeen). */
18507
+ windowMs: number().optional()
18508
+ });
18390
18509
  var TrackedDetectionSchema = object({
18391
18510
  trackId: string(),
18392
18511
  className: string(),
@@ -18416,7 +18535,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18416
18535
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
18417
18536
  kind: "mutation",
18418
18537
  auth: "admin"
18419
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
18538
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
18420
18539
  deviceId: number(),
18421
18540
  since: number(),
18422
18541
  until: number(),
@@ -19220,7 +19339,20 @@ var snapshotCapability = {
19220
19339
  invalidateCache: method(object({ deviceId: number() }), _void(), {
19221
19340
  kind: "mutation",
19222
19341
  auth: "admin"
19223
- })
19342
+ }),
19343
+ /**
19344
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
19345
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
19346
+ * devices that never produced a frame, and gives it an ETag per device for
19347
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
19348
+ * are null for a device with no cached frame.
19349
+ */
19350
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
19351
+ deviceId: number(),
19352
+ lastCapturedAt: number().nullable(),
19353
+ cacheAgeMs: number().nullable(),
19354
+ etag: string().nullable()
19355
+ })))
19224
19356
  },
19225
19357
  status: {
19226
19358
  schema: SnapshotStatusSchema,
@@ -19477,10 +19609,32 @@ method(_void(), array(TurnServerSchema).readonly());
19477
19609
  * b. `finishAuthentication({userId, response})` → server verifies
19478
19610
  * the assertion, bumps the credential counter, returns ok.
19479
19611
  *
19612
+ * 2b. Usernameless (discoverable-credential) authentication — the
19613
+ * passkey IS the primary factor, no password leg:
19614
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
19615
+ * EMPTY `allowCredentials` (the browser offers every resident
19616
+ * passkey it holds for this RP) + `userVerification: 'required'`
19617
+ * (the passkey replaces both factors, so UV is mandatory).
19618
+ * The challenge is stored server-side, NOT bound to any user.
19619
+ * b. `finishDiscoverableAuthentication({response})` → the provider
19620
+ * resolves the credential by the response's credential id,
19621
+ * verifies the assertion against the stored challenge + that
19622
+ * credential's public key/counter, and returns the OWNING
19623
+ * `userId` — the caller (core auth router) mints the session.
19624
+ *
19480
19625
  * 3. Management:
19481
19626
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
19482
19627
  * - `removePasskey({userId, credentialId})` — revoke one credential.
19483
19628
  *
19629
+ * 4. Second-factor preference (opt-in, default OFF):
19630
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
19631
+ * demanded as a second factor after a password login ONLY when the
19632
+ * user explicitly opts in via `setSecondFactorPreference`.
19633
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
19634
+ * row ⇒ `enabled: false`).
19635
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
19636
+ * the providing addon beside its credentials.
19637
+ *
19484
19638
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
19485
19639
  * the admin-ui composes the begin/finish round-trip and never exposes
19486
19640
  * the cap to non-admins.
@@ -19523,6 +19677,17 @@ method(object({
19523
19677
  }), object({ verified: boolean() }), {
19524
19678
  kind: "mutation",
19525
19679
  access: "view"
19680
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
19681
+ kind: "mutation",
19682
+ access: "view"
19683
+ }), method(object({
19684
+ /** AuthenticationResponseJSON from the browser. */
19685
+ response: record(string(), unknown()) }), object({
19686
+ verified: boolean(),
19687
+ userId: string().nullable()
19688
+ }), {
19689
+ kind: "mutation",
19690
+ access: "view"
19526
19691
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
19527
19692
  userId: string(),
19528
19693
  credentialId: string()
@@ -19530,6 +19695,13 @@ method(object({
19530
19695
  kind: "mutation",
19531
19696
  auth: "admin",
19532
19697
  access: "delete"
19698
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
19699
+ userId: string(),
19700
+ enabled: boolean()
19701
+ }), object({ success: literal(true) }), {
19702
+ kind: "mutation",
19703
+ auth: "admin",
19704
+ access: "create"
19533
19705
  });
19534
19706
  /**
19535
19707
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -20331,7 +20503,17 @@ var FaceInfoSchema = object({
20331
20503
  recognizedIdentityId: string().optional(),
20332
20504
  identityName: string().optional(),
20333
20505
  assigned: boolean(),
20334
- base64: string().optional()
20506
+ base64: string().optional(),
20507
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
20508
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
20509
+ * legacy rows written before design B. */
20510
+ faceBbox: BoundingBoxSchema.optional(),
20511
+ /** Design B: MediaStore key of the track's native-resolution key frame.
20512
+ * Fetch the native JPEG via the event-media data-plane
20513
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
20514
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
20515
+ * back to the inline `base64` face crop. */
20516
+ keyFrameMediaKey: string().optional()
20335
20517
  });
20336
20518
  var FaceFilterEnum = _enum([
20337
20519
  "unassigned",
@@ -24779,6 +24961,12 @@ Object.freeze({
24779
24961
  addonId: null,
24780
24962
  access: "view"
24781
24963
  },
24964
+ "pipelineAnalytics.getKeyEvents": {
24965
+ capName: "pipeline-analytics",
24966
+ capScope: "device",
24967
+ addonId: null,
24968
+ access: "view"
24969
+ },
24782
24970
  "pipelineAnalytics.getMotionEvents": {
24783
24971
  capName: "pipeline-analytics",
24784
24972
  capScope: "device",
@@ -25307,12 +25495,24 @@ Object.freeze({
25307
25495
  addonId: null,
25308
25496
  access: "view"
25309
25497
  },
25498
+ "pipelineRunner.getNativeCrop": {
25499
+ capName: "pipeline-runner",
25500
+ capScope: "system",
25501
+ addonId: null,
25502
+ access: "view"
25503
+ },
25310
25504
  "pipelineRunner.reportMotion": {
25311
25505
  capName: "pipeline-runner",
25312
25506
  capScope: "system",
25313
25507
  addonId: null,
25314
25508
  access: "create"
25315
25509
  },
25510
+ "pipelineRunner.runDetailSubtree": {
25511
+ capName: "pipeline-runner",
25512
+ capScope: "system",
25513
+ addonId: null,
25514
+ access: "create"
25515
+ },
25316
25516
  "plateGallery.correctPlateText": {
25317
25517
  capName: "plate-gallery",
25318
25518
  capScope: "system",
@@ -25673,6 +25873,12 @@ Object.freeze({
25673
25873
  addonId: null,
25674
25874
  access: "view"
25675
25875
  },
25876
+ "snapshot.getSnapshotOverview": {
25877
+ capName: "snapshot",
25878
+ capScope: "device",
25879
+ addonId: null,
25880
+ access: "view"
25881
+ },
25676
25882
  "snapshot.invalidateCache": {
25677
25883
  capName: "snapshot",
25678
25884
  capScope: "device",
@@ -26351,6 +26557,12 @@ Object.freeze({
26351
26557
  addonId: null,
26352
26558
  access: "view"
26353
26559
  },
26560
+ "userPasskeys.beginDiscoverableAuthentication": {
26561
+ capName: "user-passkeys",
26562
+ capScope: "system",
26563
+ addonId: null,
26564
+ access: "view"
26565
+ },
26354
26566
  "userPasskeys.beginRegistration": {
26355
26567
  capName: "user-passkeys",
26356
26568
  capScope: "system",
@@ -26363,12 +26575,24 @@ Object.freeze({
26363
26575
  addonId: null,
26364
26576
  access: "view"
26365
26577
  },
26578
+ "userPasskeys.finishDiscoverableAuthentication": {
26579
+ capName: "user-passkeys",
26580
+ capScope: "system",
26581
+ addonId: null,
26582
+ access: "view"
26583
+ },
26366
26584
  "userPasskeys.finishRegistration": {
26367
26585
  capName: "user-passkeys",
26368
26586
  capScope: "system",
26369
26587
  addonId: null,
26370
26588
  access: "create"
26371
26589
  },
26590
+ "userPasskeys.getSecondFactorPreference": {
26591
+ capName: "user-passkeys",
26592
+ capScope: "system",
26593
+ addonId: null,
26594
+ access: "view"
26595
+ },
26372
26596
  "userPasskeys.listPasskeys": {
26373
26597
  capName: "user-passkeys",
26374
26598
  capScope: "system",
@@ -26381,6 +26605,12 @@ Object.freeze({
26381
26605
  addonId: null,
26382
26606
  access: "delete"
26383
26607
  },
26608
+ "userPasskeys.setSecondFactorPreference": {
26609
+ capName: "user-passkeys",
26610
+ capScope: "system",
26611
+ addonId: null,
26612
+ access: "create"
26613
+ },
26384
26614
  "vacuumControl.locate": {
26385
26615
  capName: "vacuum-control",
26386
26616
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-reolink",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "Reolink camera device provider addon for CamStack — native Baichuan protocol",
5
5
  "keywords": [
6
6
  "camstack",