@camstack/addon-export-hap 1.1.20 → 1.1.22

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.
@@ -4664,7 +4664,7 @@ function _instanceof(cls, params = {}) {
4664
4664
  return inst;
4665
4665
  }
4666
4666
  //#endregion
4667
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4667
+ //#region ../types/dist/sleep-Baang_XW.mjs
4668
4668
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4669
4669
  EventCategory["SystemBoot"] = "system.boot";
4670
4670
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6768,6 +6768,18 @@ function method(input, output, options) {
6768
6768
  timeoutMs: options?.timeoutMs
6769
6769
  };
6770
6770
  }
6771
+ /**
6772
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6773
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6774
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6775
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6776
+ */
6777
+ function systemMethod(input, output, options) {
6778
+ return {
6779
+ ...method(input, output, options),
6780
+ systemOnly: true
6781
+ };
6782
+ }
6771
6783
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6772
6784
  var VersionOutputSchema$1 = object({ version: string() });
6773
6785
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10560,6 +10572,7 @@ var PipelineAddonSchemaSchema = object({
10560
10572
  defaultModelId: string(),
10561
10573
  defaultModelIdByFormat: record(string(), string()).optional(),
10562
10574
  enabledByDefault: boolean().optional(),
10575
+ backfillIntoExistingOverrides: boolean().optional(),
10563
10576
  defaultConfidence: number(),
10564
10577
  group: string().optional(),
10565
10578
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10741,7 +10754,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10741
10754
  image: _instanceof(Uint8Array).optional(),
10742
10755
  referenceImage: string().optional(),
10743
10756
  deviceId: number().optional(),
10744
- sessionId: string().optional()
10757
+ sessionId: string().optional(),
10758
+ /**
10759
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
10760
+ * reference-image, and detail-subtree calls. 'frame' is the live
10761
+ * per-frame dispatch: ONLY root-plane steps run; crop children
10762
+ * (inputClasses ≠ null) are skipped and served per-track via
10763
+ * pipelineRunner.runDetailSubtree (two-plane design).
10764
+ */
10765
+ plane: _enum(["full", "frame"]).optional()
10745
10766
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
10746
10767
  engine: PipelineEngineChoiceSchema.optional(),
10747
10768
  steps: array(PipelineStepInputSchema).min(1),
@@ -10866,6 +10887,47 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10866
10887
  auth: "admin"
10867
10888
  }), object({ zones: array(ZoneSchema).readonly() });
10868
10889
  /**
10890
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10891
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10892
+ * so the caller supplies only the detection-res bbox divided by the detection
10893
+ * dims — no native resolution to plumb.
10894
+ */
10895
+ var NativeCropBboxSchema = object({
10896
+ x: number(),
10897
+ y: number(),
10898
+ w: number(),
10899
+ h: number()
10900
+ });
10901
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10902
+ var NativeCropResultSchema = object({
10903
+ /** Packed rgb (24-bit) pixels of the crop. */
10904
+ bytes: _instanceof(Uint8Array),
10905
+ width: number().int().positive(),
10906
+ height: number().int().positive()
10907
+ });
10908
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
10909
+ * originating detection, in FRAME-space coordinates. Reuses
10910
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
10911
+ * the coordinates are frame-space rather than getNativeCrop's
10912
+ * normalized [0,1] convention). */
10913
+ var DetailParentSchema = object({
10914
+ bbox: NativeCropBboxSchema,
10915
+ className: string()
10916
+ });
10917
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
10918
+ * or refined detection produced by running the crop-subtree on a
10919
+ * single tracked detection. */
10920
+ var DetailResultSchema = object({
10921
+ stepId: string(),
10922
+ className: string(),
10923
+ score: number(),
10924
+ /** FRAME-space bbox (already mapped back from crop space). */
10925
+ bbox: NativeCropBboxSchema.optional(),
10926
+ embedding: string().optional(),
10927
+ label: string().optional(),
10928
+ alignedCropJpeg: string().optional()
10929
+ });
10930
+ /**
10869
10931
  * Per-camera tunable ranges + defaults. Single source of truth used
10870
10932
  * by both the Zod data schema (validation + default fallback) and
10871
10933
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11121,7 +11183,17 @@ var RunnerLocalMetricsSchema = object({
11121
11183
  avgInferenceTimeMs: number(),
11122
11184
  queueDepth: number()
11123
11185
  });
11124
- 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());
11186
+ 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({
11187
+ handle: FrameHandleSchema,
11188
+ bbox: NativeCropBboxSchema,
11189
+ maxWidth: number().int().positive().optional()
11190
+ }), NativeCropResultSchema.nullable()), method(object({
11191
+ deviceId: number(),
11192
+ frameHandle: FrameHandleSchema.optional(),
11193
+ cropJpeg: string().optional(),
11194
+ parent: DetailParentSchema,
11195
+ steps: array(string()).optional()
11196
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
11125
11197
  object({
11126
11198
  detected: boolean(),
11127
11199
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15184,7 +15256,17 @@ var TrackSchema = object({
15184
15256
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15185
15257
  totalDistance: number(),
15186
15258
  state: TrackStateSchema,
15187
- active: boolean()
15259
+ active: boolean(),
15260
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15261
+ * track expiry, recomputed on late label). Absent on legacy rows written
15262
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15263
+ importance: number().optional(),
15264
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15265
+ * "best" frame). Absent when the track produced no object events. */
15266
+ bestEventId: string().optional(),
15267
+ /** Tag of the importance sub-signal that dominated the score
15268
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15269
+ importanceReason: string().optional()
15188
15270
  });
15189
15271
  var BaseEventFields = {
15190
15272
  id: string(),
@@ -15249,8 +15331,18 @@ var ObjectEventSchema = object({
15249
15331
  frameHeight: number().optional(),
15250
15332
  /** MediaStore key for the crop attached to this event (if any). */
15251
15333
  mediaKey: string().optional(),
15334
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15335
+ * best-detection full frame). Resolve via the event-media data-plane
15336
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15337
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15338
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15339
+ keyFrameMediaKey: string().optional(),
15252
15340
  /** Populated by B5 (recording playback URL for this event). */
15253
- mediaUrl: string().optional()
15341
+ mediaUrl: string().optional(),
15342
+ /** The parent track's key-event importance [0,1], propagated to every object
15343
+ * event of the track (so an event row can be sorted by importance without a
15344
+ * track join). Absent on legacy rows / before the track was scored. */
15345
+ importance: number().optional()
15254
15346
  });
15255
15347
  var AudioEventSchema = object({
15256
15348
  ...BaseEventFields,
@@ -15274,7 +15366,8 @@ var MediaFileKindEnum = _enum([
15274
15366
  "fullFrame",
15275
15367
  "fullFrameBoxed",
15276
15368
  "faceCrop",
15277
- "plateCrop"
15369
+ "plateCrop",
15370
+ "keyFrame"
15278
15371
  ]);
15279
15372
  var MediaFileSchema = object({
15280
15373
  key: string(),
@@ -15295,6 +15388,32 @@ var DeviceEventQueryInput = object({
15295
15388
  projection: _enum(["full", "slim"]).optional()
15296
15389
  });
15297
15390
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15391
+ var KeyEventQueryInput = object({
15392
+ deviceId: number(),
15393
+ /** Window lower bound (track firstSeen ≥ since). */
15394
+ since: number(),
15395
+ /** Window upper bound (track firstSeen ≤ until). */
15396
+ until: number(),
15397
+ limit: number().int().min(1).max(200).default(50),
15398
+ /** Drop tracks scoring below this importance. */
15399
+ minImportance: number().min(0).max(1).optional(),
15400
+ /** Restrict to a single class (e.g. 'person'). */
15401
+ classFilter: string().optional()
15402
+ });
15403
+ var KeyEventSchema = object({
15404
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15405
+ id: string(),
15406
+ trackId: string(),
15407
+ /** Track start time (firstSeen). */
15408
+ timestamp: number(),
15409
+ className: string(),
15410
+ label: string().optional(),
15411
+ importance: number(),
15412
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15413
+ bestEventId: string(),
15414
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15415
+ windowMs: number().optional()
15416
+ });
15298
15417
  var TrackedDetectionSchema = object({
15299
15418
  trackId: string(),
15300
15419
  className: string(),
@@ -15324,7 +15443,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15324
15443
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15325
15444
  kind: "mutation",
15326
15445
  auth: "admin"
15327
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15446
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15328
15447
  deviceId: number(),
15329
15448
  since: number(),
15330
15449
  until: number(),
@@ -16091,7 +16210,12 @@ DeviceType.Camera, method(object({
16091
16210
  }), SnapshotImageSchema.nullable()), method(object({ deviceId: number() }), _void(), {
16092
16211
  kind: "mutation",
16093
16212
  auth: "admin"
16094
- });
16213
+ }), systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16214
+ deviceId: number(),
16215
+ lastCapturedAt: number().nullable(),
16216
+ cacheAgeMs: number().nullable(),
16217
+ etag: string().nullable()
16218
+ })));
16095
16219
  /**
16096
16220
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
16097
16221
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16342,10 +16466,32 @@ method(_void(), array(TurnServerSchema).readonly());
16342
16466
  * b. `finishAuthentication({userId, response})` → server verifies
16343
16467
  * the assertion, bumps the credential counter, returns ok.
16344
16468
  *
16469
+ * 2b. Usernameless (discoverable-credential) authentication — the
16470
+ * passkey IS the primary factor, no password leg:
16471
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16472
+ * EMPTY `allowCredentials` (the browser offers every resident
16473
+ * passkey it holds for this RP) + `userVerification: 'required'`
16474
+ * (the passkey replaces both factors, so UV is mandatory).
16475
+ * The challenge is stored server-side, NOT bound to any user.
16476
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16477
+ * resolves the credential by the response's credential id,
16478
+ * verifies the assertion against the stored challenge + that
16479
+ * credential's public key/counter, and returns the OWNING
16480
+ * `userId` — the caller (core auth router) mints the session.
16481
+ *
16345
16482
  * 3. Management:
16346
16483
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16347
16484
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16348
16485
  *
16486
+ * 4. Second-factor preference (opt-in, default OFF):
16487
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16488
+ * demanded as a second factor after a password login ONLY when the
16489
+ * user explicitly opts in via `setSecondFactorPreference`.
16490
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16491
+ * row ⇒ `enabled: false`).
16492
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16493
+ * the providing addon beside its credentials.
16494
+ *
16349
16495
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16350
16496
  * the admin-ui composes the begin/finish round-trip and never exposes
16351
16497
  * the cap to non-admins.
@@ -16388,6 +16534,17 @@ method(object({
16388
16534
  }), object({ verified: boolean() }), {
16389
16535
  kind: "mutation",
16390
16536
  access: "view"
16537
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16538
+ kind: "mutation",
16539
+ access: "view"
16540
+ }), method(object({
16541
+ /** AuthenticationResponseJSON from the browser. */
16542
+ response: record(string(), unknown()) }), object({
16543
+ verified: boolean(),
16544
+ userId: string().nullable()
16545
+ }), {
16546
+ kind: "mutation",
16547
+ access: "view"
16391
16548
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16392
16549
  userId: string(),
16393
16550
  credentialId: string()
@@ -16395,6 +16552,13 @@ method(object({
16395
16552
  kind: "mutation",
16396
16553
  auth: "admin",
16397
16554
  access: "delete"
16555
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16556
+ userId: string(),
16557
+ enabled: boolean()
16558
+ }), object({ success: literal(true) }), {
16559
+ kind: "mutation",
16560
+ auth: "admin",
16561
+ access: "create"
16398
16562
  });
16399
16563
  /**
16400
16564
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17196,7 +17360,17 @@ var FaceInfoSchema = object({
17196
17360
  recognizedIdentityId: string().optional(),
17197
17361
  identityName: string().optional(),
17198
17362
  assigned: boolean(),
17199
- base64: string().optional()
17363
+ base64: string().optional(),
17364
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17365
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17366
+ * legacy rows written before design B. */
17367
+ faceBbox: BoundingBoxSchema.optional(),
17368
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17369
+ * Fetch the native JPEG via the event-media data-plane
17370
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17371
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17372
+ * back to the inline `base64` face crop. */
17373
+ keyFrameMediaKey: string().optional()
17200
17374
  });
17201
17375
  var FaceFilterEnum = _enum([
17202
17376
  "unassigned",
@@ -21315,6 +21489,12 @@ Object.freeze({
21315
21489
  addonId: null,
21316
21490
  access: "view"
21317
21491
  },
21492
+ "pipelineAnalytics.getKeyEvents": {
21493
+ capName: "pipeline-analytics",
21494
+ capScope: "device",
21495
+ addonId: null,
21496
+ access: "view"
21497
+ },
21318
21498
  "pipelineAnalytics.getMotionEvents": {
21319
21499
  capName: "pipeline-analytics",
21320
21500
  capScope: "device",
@@ -21843,12 +22023,24 @@ Object.freeze({
21843
22023
  addonId: null,
21844
22024
  access: "view"
21845
22025
  },
22026
+ "pipelineRunner.getNativeCrop": {
22027
+ capName: "pipeline-runner",
22028
+ capScope: "system",
22029
+ addonId: null,
22030
+ access: "view"
22031
+ },
21846
22032
  "pipelineRunner.reportMotion": {
21847
22033
  capName: "pipeline-runner",
21848
22034
  capScope: "system",
21849
22035
  addonId: null,
21850
22036
  access: "create"
21851
22037
  },
22038
+ "pipelineRunner.runDetailSubtree": {
22039
+ capName: "pipeline-runner",
22040
+ capScope: "system",
22041
+ addonId: null,
22042
+ access: "create"
22043
+ },
21852
22044
  "plateGallery.correctPlateText": {
21853
22045
  capName: "plate-gallery",
21854
22046
  capScope: "system",
@@ -22209,6 +22401,12 @@ Object.freeze({
22209
22401
  addonId: null,
22210
22402
  access: "view"
22211
22403
  },
22404
+ "snapshot.getSnapshotOverview": {
22405
+ capName: "snapshot",
22406
+ capScope: "device",
22407
+ addonId: null,
22408
+ access: "view"
22409
+ },
22212
22410
  "snapshot.invalidateCache": {
22213
22411
  capName: "snapshot",
22214
22412
  capScope: "device",
@@ -22887,6 +23085,12 @@ Object.freeze({
22887
23085
  addonId: null,
22888
23086
  access: "view"
22889
23087
  },
23088
+ "userPasskeys.beginDiscoverableAuthentication": {
23089
+ capName: "user-passkeys",
23090
+ capScope: "system",
23091
+ addonId: null,
23092
+ access: "view"
23093
+ },
22890
23094
  "userPasskeys.beginRegistration": {
22891
23095
  capName: "user-passkeys",
22892
23096
  capScope: "system",
@@ -22899,12 +23103,24 @@ Object.freeze({
22899
23103
  addonId: null,
22900
23104
  access: "view"
22901
23105
  },
23106
+ "userPasskeys.finishDiscoverableAuthentication": {
23107
+ capName: "user-passkeys",
23108
+ capScope: "system",
23109
+ addonId: null,
23110
+ access: "view"
23111
+ },
22902
23112
  "userPasskeys.finishRegistration": {
22903
23113
  capName: "user-passkeys",
22904
23114
  capScope: "system",
22905
23115
  addonId: null,
22906
23116
  access: "create"
22907
23117
  },
23118
+ "userPasskeys.getSecondFactorPreference": {
23119
+ capName: "user-passkeys",
23120
+ capScope: "system",
23121
+ addonId: null,
23122
+ access: "view"
23123
+ },
22908
23124
  "userPasskeys.listPasskeys": {
22909
23125
  capName: "user-passkeys",
22910
23126
  capScope: "system",
@@ -22917,6 +23133,12 @@ Object.freeze({
22917
23133
  addonId: null,
22918
23134
  access: "delete"
22919
23135
  },
23136
+ "userPasskeys.setSecondFactorPreference": {
23137
+ capName: "user-passkeys",
23138
+ capScope: "system",
23139
+ addonId: null,
23140
+ access: "create"
23141
+ },
22920
23142
  "vacuumControl.locate": {
22921
23143
  capName: "vacuum-control",
22922
23144
  capScope: "device",
@@ -4639,7 +4639,7 @@ function _instanceof(cls, params = {}) {
4639
4639
  return inst;
4640
4640
  }
4641
4641
  //#endregion
4642
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4642
+ //#region ../types/dist/sleep-Baang_XW.mjs
4643
4643
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4644
4644
  EventCategory["SystemBoot"] = "system.boot";
4645
4645
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6743,6 +6743,18 @@ function method(input, output, options) {
6743
6743
  timeoutMs: options?.timeoutMs
6744
6744
  };
6745
6745
  }
6746
+ /**
6747
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6748
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6749
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6750
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6751
+ */
6752
+ function systemMethod(input, output, options) {
6753
+ return {
6754
+ ...method(input, output, options),
6755
+ systemOnly: true
6756
+ };
6757
+ }
6746
6758
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6747
6759
  var VersionOutputSchema$1 = object({ version: string() });
6748
6760
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10535,6 +10547,7 @@ var PipelineAddonSchemaSchema = object({
10535
10547
  defaultModelId: string(),
10536
10548
  defaultModelIdByFormat: record(string(), string()).optional(),
10537
10549
  enabledByDefault: boolean().optional(),
10550
+ backfillIntoExistingOverrides: boolean().optional(),
10538
10551
  defaultConfidence: number(),
10539
10552
  group: string().optional(),
10540
10553
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10716,7 +10729,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10716
10729
  image: _instanceof(Uint8Array).optional(),
10717
10730
  referenceImage: string().optional(),
10718
10731
  deviceId: number().optional(),
10719
- sessionId: string().optional()
10732
+ sessionId: string().optional(),
10733
+ /**
10734
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
10735
+ * reference-image, and detail-subtree calls. 'frame' is the live
10736
+ * per-frame dispatch: ONLY root-plane steps run; crop children
10737
+ * (inputClasses ≠ null) are skipped and served per-track via
10738
+ * pipelineRunner.runDetailSubtree (two-plane design).
10739
+ */
10740
+ plane: _enum(["full", "frame"]).optional()
10720
10741
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
10721
10742
  engine: PipelineEngineChoiceSchema.optional(),
10722
10743
  steps: array(PipelineStepInputSchema).min(1),
@@ -10841,6 +10862,47 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10841
10862
  auth: "admin"
10842
10863
  }), object({ zones: array(ZoneSchema).readonly() });
10843
10864
  /**
10865
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10866
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10867
+ * so the caller supplies only the detection-res bbox divided by the detection
10868
+ * dims — no native resolution to plumb.
10869
+ */
10870
+ var NativeCropBboxSchema = object({
10871
+ x: number(),
10872
+ y: number(),
10873
+ w: number(),
10874
+ h: number()
10875
+ });
10876
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10877
+ var NativeCropResultSchema = object({
10878
+ /** Packed rgb (24-bit) pixels of the crop. */
10879
+ bytes: _instanceof(Uint8Array),
10880
+ width: number().int().positive(),
10881
+ height: number().int().positive()
10882
+ });
10883
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
10884
+ * originating detection, in FRAME-space coordinates. Reuses
10885
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
10886
+ * the coordinates are frame-space rather than getNativeCrop's
10887
+ * normalized [0,1] convention). */
10888
+ var DetailParentSchema = object({
10889
+ bbox: NativeCropBboxSchema,
10890
+ className: string()
10891
+ });
10892
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
10893
+ * or refined detection produced by running the crop-subtree on a
10894
+ * single tracked detection. */
10895
+ var DetailResultSchema = object({
10896
+ stepId: string(),
10897
+ className: string(),
10898
+ score: number(),
10899
+ /** FRAME-space bbox (already mapped back from crop space). */
10900
+ bbox: NativeCropBboxSchema.optional(),
10901
+ embedding: string().optional(),
10902
+ label: string().optional(),
10903
+ alignedCropJpeg: string().optional()
10904
+ });
10905
+ /**
10844
10906
  * Per-camera tunable ranges + defaults. Single source of truth used
10845
10907
  * by both the Zod data schema (validation + default fallback) and
10846
10908
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11096,7 +11158,17 @@ var RunnerLocalMetricsSchema = object({
11096
11158
  avgInferenceTimeMs: number(),
11097
11159
  queueDepth: number()
11098
11160
  });
11099
- 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());
11161
+ 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({
11162
+ handle: FrameHandleSchema,
11163
+ bbox: NativeCropBboxSchema,
11164
+ maxWidth: number().int().positive().optional()
11165
+ }), NativeCropResultSchema.nullable()), method(object({
11166
+ deviceId: number(),
11167
+ frameHandle: FrameHandleSchema.optional(),
11168
+ cropJpeg: string().optional(),
11169
+ parent: DetailParentSchema,
11170
+ steps: array(string()).optional()
11171
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
11100
11172
  object({
11101
11173
  detected: boolean(),
11102
11174
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15159,7 +15231,17 @@ var TrackSchema = object({
15159
15231
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15160
15232
  totalDistance: number(),
15161
15233
  state: TrackStateSchema,
15162
- active: boolean()
15234
+ active: boolean(),
15235
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15236
+ * track expiry, recomputed on late label). Absent on legacy rows written
15237
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15238
+ importance: number().optional(),
15239
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15240
+ * "best" frame). Absent when the track produced no object events. */
15241
+ bestEventId: string().optional(),
15242
+ /** Tag of the importance sub-signal that dominated the score
15243
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15244
+ importanceReason: string().optional()
15163
15245
  });
15164
15246
  var BaseEventFields = {
15165
15247
  id: string(),
@@ -15224,8 +15306,18 @@ var ObjectEventSchema = object({
15224
15306
  frameHeight: number().optional(),
15225
15307
  /** MediaStore key for the crop attached to this event (if any). */
15226
15308
  mediaKey: string().optional(),
15309
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15310
+ * best-detection full frame). Resolve via the event-media data-plane
15311
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15312
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15313
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15314
+ keyFrameMediaKey: string().optional(),
15227
15315
  /** Populated by B5 (recording playback URL for this event). */
15228
- mediaUrl: string().optional()
15316
+ mediaUrl: string().optional(),
15317
+ /** The parent track's key-event importance [0,1], propagated to every object
15318
+ * event of the track (so an event row can be sorted by importance without a
15319
+ * track join). Absent on legacy rows / before the track was scored. */
15320
+ importance: number().optional()
15229
15321
  });
15230
15322
  var AudioEventSchema = object({
15231
15323
  ...BaseEventFields,
@@ -15249,7 +15341,8 @@ var MediaFileKindEnum = _enum([
15249
15341
  "fullFrame",
15250
15342
  "fullFrameBoxed",
15251
15343
  "faceCrop",
15252
- "plateCrop"
15344
+ "plateCrop",
15345
+ "keyFrame"
15253
15346
  ]);
15254
15347
  var MediaFileSchema = object({
15255
15348
  key: string(),
@@ -15270,6 +15363,32 @@ var DeviceEventQueryInput = object({
15270
15363
  projection: _enum(["full", "slim"]).optional()
15271
15364
  });
15272
15365
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15366
+ var KeyEventQueryInput = object({
15367
+ deviceId: number(),
15368
+ /** Window lower bound (track firstSeen ≥ since). */
15369
+ since: number(),
15370
+ /** Window upper bound (track firstSeen ≤ until). */
15371
+ until: number(),
15372
+ limit: number().int().min(1).max(200).default(50),
15373
+ /** Drop tracks scoring below this importance. */
15374
+ minImportance: number().min(0).max(1).optional(),
15375
+ /** Restrict to a single class (e.g. 'person'). */
15376
+ classFilter: string().optional()
15377
+ });
15378
+ var KeyEventSchema = object({
15379
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15380
+ id: string(),
15381
+ trackId: string(),
15382
+ /** Track start time (firstSeen). */
15383
+ timestamp: number(),
15384
+ className: string(),
15385
+ label: string().optional(),
15386
+ importance: number(),
15387
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15388
+ bestEventId: string(),
15389
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15390
+ windowMs: number().optional()
15391
+ });
15273
15392
  var TrackedDetectionSchema = object({
15274
15393
  trackId: string(),
15275
15394
  className: string(),
@@ -15299,7 +15418,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15299
15418
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15300
15419
  kind: "mutation",
15301
15420
  auth: "admin"
15302
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15421
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15303
15422
  deviceId: number(),
15304
15423
  since: number(),
15305
15424
  until: number(),
@@ -16066,7 +16185,12 @@ DeviceType.Camera, method(object({
16066
16185
  }), SnapshotImageSchema.nullable()), method(object({ deviceId: number() }), _void(), {
16067
16186
  kind: "mutation",
16068
16187
  auth: "admin"
16069
- });
16188
+ }), systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16189
+ deviceId: number(),
16190
+ lastCapturedAt: number().nullable(),
16191
+ cacheAgeMs: number().nullable(),
16192
+ etag: string().nullable()
16193
+ })));
16070
16194
  /**
16071
16195
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
16072
16196
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16317,10 +16441,32 @@ method(_void(), array(TurnServerSchema).readonly());
16317
16441
  * b. `finishAuthentication({userId, response})` → server verifies
16318
16442
  * the assertion, bumps the credential counter, returns ok.
16319
16443
  *
16444
+ * 2b. Usernameless (discoverable-credential) authentication — the
16445
+ * passkey IS the primary factor, no password leg:
16446
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16447
+ * EMPTY `allowCredentials` (the browser offers every resident
16448
+ * passkey it holds for this RP) + `userVerification: 'required'`
16449
+ * (the passkey replaces both factors, so UV is mandatory).
16450
+ * The challenge is stored server-side, NOT bound to any user.
16451
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16452
+ * resolves the credential by the response's credential id,
16453
+ * verifies the assertion against the stored challenge + that
16454
+ * credential's public key/counter, and returns the OWNING
16455
+ * `userId` — the caller (core auth router) mints the session.
16456
+ *
16320
16457
  * 3. Management:
16321
16458
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16322
16459
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16323
16460
  *
16461
+ * 4. Second-factor preference (opt-in, default OFF):
16462
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16463
+ * demanded as a second factor after a password login ONLY when the
16464
+ * user explicitly opts in via `setSecondFactorPreference`.
16465
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16466
+ * row ⇒ `enabled: false`).
16467
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16468
+ * the providing addon beside its credentials.
16469
+ *
16324
16470
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16325
16471
  * the admin-ui composes the begin/finish round-trip and never exposes
16326
16472
  * the cap to non-admins.
@@ -16363,6 +16509,17 @@ method(object({
16363
16509
  }), object({ verified: boolean() }), {
16364
16510
  kind: "mutation",
16365
16511
  access: "view"
16512
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16513
+ kind: "mutation",
16514
+ access: "view"
16515
+ }), method(object({
16516
+ /** AuthenticationResponseJSON from the browser. */
16517
+ response: record(string(), unknown()) }), object({
16518
+ verified: boolean(),
16519
+ userId: string().nullable()
16520
+ }), {
16521
+ kind: "mutation",
16522
+ access: "view"
16366
16523
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16367
16524
  userId: string(),
16368
16525
  credentialId: string()
@@ -16370,6 +16527,13 @@ method(object({
16370
16527
  kind: "mutation",
16371
16528
  auth: "admin",
16372
16529
  access: "delete"
16530
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16531
+ userId: string(),
16532
+ enabled: boolean()
16533
+ }), object({ success: literal(true) }), {
16534
+ kind: "mutation",
16535
+ auth: "admin",
16536
+ access: "create"
16373
16537
  });
16374
16538
  /**
16375
16539
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17171,7 +17335,17 @@ var FaceInfoSchema = object({
17171
17335
  recognizedIdentityId: string().optional(),
17172
17336
  identityName: string().optional(),
17173
17337
  assigned: boolean(),
17174
- base64: string().optional()
17338
+ base64: string().optional(),
17339
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17340
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17341
+ * legacy rows written before design B. */
17342
+ faceBbox: BoundingBoxSchema.optional(),
17343
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17344
+ * Fetch the native JPEG via the event-media data-plane
17345
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17346
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17347
+ * back to the inline `base64` face crop. */
17348
+ keyFrameMediaKey: string().optional()
17175
17349
  });
17176
17350
  var FaceFilterEnum = _enum([
17177
17351
  "unassigned",
@@ -21290,6 +21464,12 @@ Object.freeze({
21290
21464
  addonId: null,
21291
21465
  access: "view"
21292
21466
  },
21467
+ "pipelineAnalytics.getKeyEvents": {
21468
+ capName: "pipeline-analytics",
21469
+ capScope: "device",
21470
+ addonId: null,
21471
+ access: "view"
21472
+ },
21293
21473
  "pipelineAnalytics.getMotionEvents": {
21294
21474
  capName: "pipeline-analytics",
21295
21475
  capScope: "device",
@@ -21818,12 +21998,24 @@ Object.freeze({
21818
21998
  addonId: null,
21819
21999
  access: "view"
21820
22000
  },
22001
+ "pipelineRunner.getNativeCrop": {
22002
+ capName: "pipeline-runner",
22003
+ capScope: "system",
22004
+ addonId: null,
22005
+ access: "view"
22006
+ },
21821
22007
  "pipelineRunner.reportMotion": {
21822
22008
  capName: "pipeline-runner",
21823
22009
  capScope: "system",
21824
22010
  addonId: null,
21825
22011
  access: "create"
21826
22012
  },
22013
+ "pipelineRunner.runDetailSubtree": {
22014
+ capName: "pipeline-runner",
22015
+ capScope: "system",
22016
+ addonId: null,
22017
+ access: "create"
22018
+ },
21827
22019
  "plateGallery.correctPlateText": {
21828
22020
  capName: "plate-gallery",
21829
22021
  capScope: "system",
@@ -22184,6 +22376,12 @@ Object.freeze({
22184
22376
  addonId: null,
22185
22377
  access: "view"
22186
22378
  },
22379
+ "snapshot.getSnapshotOverview": {
22380
+ capName: "snapshot",
22381
+ capScope: "device",
22382
+ addonId: null,
22383
+ access: "view"
22384
+ },
22187
22385
  "snapshot.invalidateCache": {
22188
22386
  capName: "snapshot",
22189
22387
  capScope: "device",
@@ -22862,6 +23060,12 @@ Object.freeze({
22862
23060
  addonId: null,
22863
23061
  access: "view"
22864
23062
  },
23063
+ "userPasskeys.beginDiscoverableAuthentication": {
23064
+ capName: "user-passkeys",
23065
+ capScope: "system",
23066
+ addonId: null,
23067
+ access: "view"
23068
+ },
22865
23069
  "userPasskeys.beginRegistration": {
22866
23070
  capName: "user-passkeys",
22867
23071
  capScope: "system",
@@ -22874,12 +23078,24 @@ Object.freeze({
22874
23078
  addonId: null,
22875
23079
  access: "view"
22876
23080
  },
23081
+ "userPasskeys.finishDiscoverableAuthentication": {
23082
+ capName: "user-passkeys",
23083
+ capScope: "system",
23084
+ addonId: null,
23085
+ access: "view"
23086
+ },
22877
23087
  "userPasskeys.finishRegistration": {
22878
23088
  capName: "user-passkeys",
22879
23089
  capScope: "system",
22880
23090
  addonId: null,
22881
23091
  access: "create"
22882
23092
  },
23093
+ "userPasskeys.getSecondFactorPreference": {
23094
+ capName: "user-passkeys",
23095
+ capScope: "system",
23096
+ addonId: null,
23097
+ access: "view"
23098
+ },
22883
23099
  "userPasskeys.listPasskeys": {
22884
23100
  capName: "user-passkeys",
22885
23101
  capScope: "system",
@@ -22892,6 +23108,12 @@ Object.freeze({
22892
23108
  addonId: null,
22893
23109
  access: "delete"
22894
23110
  },
23111
+ "userPasskeys.setSecondFactorPreference": {
23112
+ capName: "user-passkeys",
23113
+ capScope: "system",
23114
+ addonId: null,
23115
+ access: "create"
23116
+ },
22895
23117
  "vacuumControl.locate": {
22896
23118
  capName: "vacuum-control",
22897
23119
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.1.20",
3
+ "version": "1.1.22",
4
4
  "description": "HomeKit (HAP) bridge exporter for CamStack devices. Publishes a bridged accessory per exposed device — MotionSensor in this MVP; Camera/Doorbell/Switch/Light follow.",
5
5
  "keywords": [
6
6
  "camstack",