@camstack/addon-remote-storage 1.1.21 → 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.
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-BTuv4hPh.js");
5
+ const require_shared = require("./shared-BS3ZpipR.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-m1upfQvq.mjs";
1
+ import { c as BaseAddon, i as rearmIdleAbort, n as getOptionalBasePath, o as scheduleIdleAbort, s as storageProviderCapability, t as createSessionId } from "./shared-DQjNIB1f.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-BTuv4hPh.js");
5
+ const require_shared = require("./shared-BS3ZpipR.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-m1upfQvq.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-DQjNIB1f.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
@@ -4652,7 +4652,7 @@ function _instanceof(cls, params = {}) {
4652
4652
  return inst;
4653
4653
  }
4654
4654
  //#endregion
4655
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4655
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4656
4656
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4657
4657
  EventCategory["SystemBoot"] = "system.boot";
4658
4658
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6756,6 +6756,18 @@ function method(input, output, options) {
6756
6756
  timeoutMs: options?.timeoutMs
6757
6757
  };
6758
6758
  }
6759
+ /**
6760
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6761
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6762
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6763
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6764
+ */
6765
+ function systemMethod(input, output, options) {
6766
+ return {
6767
+ ...method(input, output, options),
6768
+ systemOnly: true
6769
+ };
6770
+ }
6759
6771
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6760
6772
  var VersionOutputSchema$1 = object({ version: string() });
6761
6773
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10494,6 +10506,7 @@ var PipelineAddonSchemaSchema = object({
10494
10506
  defaultModelId: string(),
10495
10507
  defaultModelIdByFormat: record(string(), string()).optional(),
10496
10508
  enabledByDefault: boolean().optional(),
10509
+ backfillIntoExistingOverrides: boolean().optional(),
10497
10510
  defaultConfidence: number(),
10498
10511
  group: string().optional(),
10499
10512
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10800,6 +10813,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10800
10813
  auth: "admin"
10801
10814
  }), object({ zones: array(ZoneSchema).readonly() });
10802
10815
  /**
10816
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10817
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10818
+ * so the caller supplies only the detection-res bbox divided by the detection
10819
+ * dims — no native resolution to plumb.
10820
+ */
10821
+ var NativeCropBboxSchema = object({
10822
+ x: number(),
10823
+ y: number(),
10824
+ w: number(),
10825
+ h: number()
10826
+ });
10827
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10828
+ var NativeCropResultSchema = object({
10829
+ /** Packed rgb (24-bit) pixels of the crop. */
10830
+ bytes: _instanceof(Uint8Array),
10831
+ width: number().int().positive(),
10832
+ height: number().int().positive()
10833
+ });
10834
+ /**
10803
10835
  * Per-camera tunable ranges + defaults. Single source of truth used
10804
10836
  * by both the Zod data schema (validation + default fallback) and
10805
10837
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11055,7 +11087,11 @@ var RunnerLocalMetricsSchema = object({
11055
11087
  avgInferenceTimeMs: number(),
11056
11088
  queueDepth: number()
11057
11089
  });
11058
- 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());
11090
+ 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({
11091
+ handle: FrameHandleSchema,
11092
+ bbox: NativeCropBboxSchema,
11093
+ maxWidth: number().int().positive().optional()
11094
+ }), NativeCropResultSchema.nullable());
11059
11095
  object({
11060
11096
  detected: boolean(),
11061
11097
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15093,7 +15129,17 @@ var TrackSchema = object({
15093
15129
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15094
15130
  totalDistance: number(),
15095
15131
  state: TrackStateSchema,
15096
- active: boolean()
15132
+ active: boolean(),
15133
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15134
+ * track expiry, recomputed on late label). Absent on legacy rows written
15135
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15136
+ importance: number().optional(),
15137
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15138
+ * "best" frame). Absent when the track produced no object events. */
15139
+ bestEventId: string().optional(),
15140
+ /** Tag of the importance sub-signal that dominated the score
15141
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15142
+ importanceReason: string().optional()
15097
15143
  });
15098
15144
  var BaseEventFields = {
15099
15145
  id: string(),
@@ -15158,8 +15204,18 @@ var ObjectEventSchema = object({
15158
15204
  frameHeight: number().optional(),
15159
15205
  /** MediaStore key for the crop attached to this event (if any). */
15160
15206
  mediaKey: string().optional(),
15207
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15208
+ * best-detection full frame). Resolve via the event-media data-plane
15209
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15210
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15211
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15212
+ keyFrameMediaKey: string().optional(),
15161
15213
  /** Populated by B5 (recording playback URL for this event). */
15162
- mediaUrl: string().optional()
15214
+ mediaUrl: string().optional(),
15215
+ /** The parent track's key-event importance [0,1], propagated to every object
15216
+ * event of the track (so an event row can be sorted by importance without a
15217
+ * track join). Absent on legacy rows / before the track was scored. */
15218
+ importance: number().optional()
15163
15219
  });
15164
15220
  var AudioEventSchema = object({
15165
15221
  ...BaseEventFields,
@@ -15183,7 +15239,8 @@ var MediaFileKindEnum = _enum([
15183
15239
  "fullFrame",
15184
15240
  "fullFrameBoxed",
15185
15241
  "faceCrop",
15186
- "plateCrop"
15242
+ "plateCrop",
15243
+ "keyFrame"
15187
15244
  ]);
15188
15245
  var MediaFileSchema = object({
15189
15246
  key: string(),
@@ -15204,6 +15261,32 @@ var DeviceEventQueryInput = object({
15204
15261
  projection: _enum(["full", "slim"]).optional()
15205
15262
  });
15206
15263
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15264
+ var KeyEventQueryInput = object({
15265
+ deviceId: number(),
15266
+ /** Window lower bound (track firstSeen ≥ since). */
15267
+ since: number(),
15268
+ /** Window upper bound (track firstSeen ≤ until). */
15269
+ until: number(),
15270
+ limit: number().int().min(1).max(200).default(50),
15271
+ /** Drop tracks scoring below this importance. */
15272
+ minImportance: number().min(0).max(1).optional(),
15273
+ /** Restrict to a single class (e.g. 'person'). */
15274
+ classFilter: string().optional()
15275
+ });
15276
+ var KeyEventSchema = object({
15277
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15278
+ id: string(),
15279
+ trackId: string(),
15280
+ /** Track start time (firstSeen). */
15281
+ timestamp: number(),
15282
+ className: string(),
15283
+ label: string().optional(),
15284
+ importance: number(),
15285
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15286
+ bestEventId: string(),
15287
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15288
+ windowMs: number().optional()
15289
+ });
15207
15290
  var TrackedDetectionSchema = object({
15208
15291
  trackId: string(),
15209
15292
  className: string(),
@@ -15233,7 +15316,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15233
15316
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15234
15317
  kind: "mutation",
15235
15318
  auth: "admin"
15236
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15319
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15237
15320
  deviceId: number(),
15238
15321
  since: number(),
15239
15322
  until: number(),
@@ -16000,7 +16083,12 @@ DeviceType.Camera, method(object({
16000
16083
  }), SnapshotImageSchema.nullable()), method(object({ deviceId: number() }), _void(), {
16001
16084
  kind: "mutation",
16002
16085
  auth: "admin"
16003
- });
16086
+ }), systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16087
+ deviceId: number(),
16088
+ lastCapturedAt: number().nullable(),
16089
+ cacheAgeMs: number().nullable(),
16090
+ etag: string().nullable()
16091
+ })));
16004
16092
  /**
16005
16093
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
16006
16094
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16296,10 +16384,32 @@ method(_void(), array(TurnServerSchema).readonly());
16296
16384
  * b. `finishAuthentication({userId, response})` → server verifies
16297
16385
  * the assertion, bumps the credential counter, returns ok.
16298
16386
  *
16387
+ * 2b. Usernameless (discoverable-credential) authentication — the
16388
+ * passkey IS the primary factor, no password leg:
16389
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16390
+ * EMPTY `allowCredentials` (the browser offers every resident
16391
+ * passkey it holds for this RP) + `userVerification: 'required'`
16392
+ * (the passkey replaces both factors, so UV is mandatory).
16393
+ * The challenge is stored server-side, NOT bound to any user.
16394
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16395
+ * resolves the credential by the response's credential id,
16396
+ * verifies the assertion against the stored challenge + that
16397
+ * credential's public key/counter, and returns the OWNING
16398
+ * `userId` — the caller (core auth router) mints the session.
16399
+ *
16299
16400
  * 3. Management:
16300
16401
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16301
16402
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16302
16403
  *
16404
+ * 4. Second-factor preference (opt-in, default OFF):
16405
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16406
+ * demanded as a second factor after a password login ONLY when the
16407
+ * user explicitly opts in via `setSecondFactorPreference`.
16408
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16409
+ * row ⇒ `enabled: false`).
16410
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16411
+ * the providing addon beside its credentials.
16412
+ *
16303
16413
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16304
16414
  * the admin-ui composes the begin/finish round-trip and never exposes
16305
16415
  * the cap to non-admins.
@@ -16342,6 +16452,17 @@ method(object({
16342
16452
  }), object({ verified: boolean() }), {
16343
16453
  kind: "mutation",
16344
16454
  access: "view"
16455
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16456
+ kind: "mutation",
16457
+ access: "view"
16458
+ }), method(object({
16459
+ /** AuthenticationResponseJSON from the browser. */
16460
+ response: record(string(), unknown()) }), object({
16461
+ verified: boolean(),
16462
+ userId: string().nullable()
16463
+ }), {
16464
+ kind: "mutation",
16465
+ access: "view"
16345
16466
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16346
16467
  userId: string(),
16347
16468
  credentialId: string()
@@ -16349,6 +16470,13 @@ method(object({
16349
16470
  kind: "mutation",
16350
16471
  auth: "admin",
16351
16472
  access: "delete"
16473
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16474
+ userId: string(),
16475
+ enabled: boolean()
16476
+ }), object({ success: literal(true) }), {
16477
+ kind: "mutation",
16478
+ auth: "admin",
16479
+ access: "create"
16352
16480
  });
16353
16481
  /**
16354
16482
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17150,7 +17278,17 @@ var FaceInfoSchema = object({
17150
17278
  recognizedIdentityId: string().optional(),
17151
17279
  identityName: string().optional(),
17152
17280
  assigned: boolean(),
17153
- base64: string().optional()
17281
+ base64: string().optional(),
17282
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17283
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17284
+ * legacy rows written before design B. */
17285
+ faceBbox: BoundingBoxSchema.optional(),
17286
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17287
+ * Fetch the native JPEG via the event-media data-plane
17288
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17289
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17290
+ * back to the inline `base64` face crop. */
17291
+ keyFrameMediaKey: string().optional()
17154
17292
  });
17155
17293
  var FaceFilterEnum = _enum([
17156
17294
  "unassigned",
@@ -21269,6 +21407,12 @@ Object.freeze({
21269
21407
  addonId: null,
21270
21408
  access: "view"
21271
21409
  },
21410
+ "pipelineAnalytics.getKeyEvents": {
21411
+ capName: "pipeline-analytics",
21412
+ capScope: "device",
21413
+ addonId: null,
21414
+ access: "view"
21415
+ },
21272
21416
  "pipelineAnalytics.getMotionEvents": {
21273
21417
  capName: "pipeline-analytics",
21274
21418
  capScope: "device",
@@ -21797,6 +21941,12 @@ Object.freeze({
21797
21941
  addonId: null,
21798
21942
  access: "view"
21799
21943
  },
21944
+ "pipelineRunner.getNativeCrop": {
21945
+ capName: "pipeline-runner",
21946
+ capScope: "system",
21947
+ addonId: null,
21948
+ access: "view"
21949
+ },
21800
21950
  "pipelineRunner.reportMotion": {
21801
21951
  capName: "pipeline-runner",
21802
21952
  capScope: "system",
@@ -22163,6 +22313,12 @@ Object.freeze({
22163
22313
  addonId: null,
22164
22314
  access: "view"
22165
22315
  },
22316
+ "snapshot.getSnapshotOverview": {
22317
+ capName: "snapshot",
22318
+ capScope: "device",
22319
+ addonId: null,
22320
+ access: "view"
22321
+ },
22166
22322
  "snapshot.invalidateCache": {
22167
22323
  capName: "snapshot",
22168
22324
  capScope: "device",
@@ -22841,6 +22997,12 @@ Object.freeze({
22841
22997
  addonId: null,
22842
22998
  access: "view"
22843
22999
  },
23000
+ "userPasskeys.beginDiscoverableAuthentication": {
23001
+ capName: "user-passkeys",
23002
+ capScope: "system",
23003
+ addonId: null,
23004
+ access: "view"
23005
+ },
22844
23006
  "userPasskeys.beginRegistration": {
22845
23007
  capName: "user-passkeys",
22846
23008
  capScope: "system",
@@ -22853,12 +23015,24 @@ Object.freeze({
22853
23015
  addonId: null,
22854
23016
  access: "view"
22855
23017
  },
23018
+ "userPasskeys.finishDiscoverableAuthentication": {
23019
+ capName: "user-passkeys",
23020
+ capScope: "system",
23021
+ addonId: null,
23022
+ access: "view"
23023
+ },
22856
23024
  "userPasskeys.finishRegistration": {
22857
23025
  capName: "user-passkeys",
22858
23026
  capScope: "system",
22859
23027
  addonId: null,
22860
23028
  access: "create"
22861
23029
  },
23030
+ "userPasskeys.getSecondFactorPreference": {
23031
+ capName: "user-passkeys",
23032
+ capScope: "system",
23033
+ addonId: null,
23034
+ access: "view"
23035
+ },
22862
23036
  "userPasskeys.listPasskeys": {
22863
23037
  capName: "user-passkeys",
22864
23038
  capScope: "system",
@@ -22871,6 +23045,12 @@ Object.freeze({
22871
23045
  addonId: null,
22872
23046
  access: "delete"
22873
23047
  },
23048
+ "userPasskeys.setSecondFactorPreference": {
23049
+ capName: "user-passkeys",
23050
+ capScope: "system",
23051
+ addonId: null,
23052
+ access: "create"
23053
+ },
22874
23054
  "vacuumControl.locate": {
22875
23055
  capName: "vacuum-control",
22876
23056
  capScope: "device",
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4632
+ //#region ../types/dist/sleep-BC9Yqte7.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6733,6 +6733,18 @@ function method(input, output, options) {
6733
6733
  timeoutMs: options?.timeoutMs
6734
6734
  };
6735
6735
  }
6736
+ /**
6737
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6738
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6739
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6740
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6741
+ */
6742
+ function systemMethod(input, output, options) {
6743
+ return {
6744
+ ...method(input, output, options),
6745
+ systemOnly: true
6746
+ };
6747
+ }
6736
6748
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6737
6749
  var VersionOutputSchema$1 = object({ version: string() });
6738
6750
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10471,6 +10483,7 @@ var PipelineAddonSchemaSchema = object({
10471
10483
  defaultModelId: string(),
10472
10484
  defaultModelIdByFormat: record(string(), string()).optional(),
10473
10485
  enabledByDefault: boolean().optional(),
10486
+ backfillIntoExistingOverrides: boolean().optional(),
10474
10487
  defaultConfidence: number(),
10475
10488
  group: string().optional(),
10476
10489
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10777,6 +10790,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10777
10790
  auth: "admin"
10778
10791
  }), object({ zones: array(ZoneSchema).readonly() });
10779
10792
  /**
10793
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10794
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10795
+ * so the caller supplies only the detection-res bbox divided by the detection
10796
+ * dims — no native resolution to plumb.
10797
+ */
10798
+ var NativeCropBboxSchema = object({
10799
+ x: number(),
10800
+ y: number(),
10801
+ w: number(),
10802
+ h: number()
10803
+ });
10804
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10805
+ var NativeCropResultSchema = object({
10806
+ /** Packed rgb (24-bit) pixels of the crop. */
10807
+ bytes: _instanceof(Uint8Array),
10808
+ width: number().int().positive(),
10809
+ height: number().int().positive()
10810
+ });
10811
+ /**
10780
10812
  * Per-camera tunable ranges + defaults. Single source of truth used
10781
10813
  * by both the Zod data schema (validation + default fallback) and
10782
10814
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11032,7 +11064,11 @@ var RunnerLocalMetricsSchema = object({
11032
11064
  avgInferenceTimeMs: number(),
11033
11065
  queueDepth: number()
11034
11066
  });
11035
- 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());
11067
+ 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({
11068
+ handle: FrameHandleSchema,
11069
+ bbox: NativeCropBboxSchema,
11070
+ maxWidth: number().int().positive().optional()
11071
+ }), NativeCropResultSchema.nullable());
11036
11072
  object({
11037
11073
  detected: boolean(),
11038
11074
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15070,7 +15106,17 @@ var TrackSchema = object({
15070
15106
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15071
15107
  totalDistance: number(),
15072
15108
  state: TrackStateSchema,
15073
- active: boolean()
15109
+ active: boolean(),
15110
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15111
+ * track expiry, recomputed on late label). Absent on legacy rows written
15112
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15113
+ importance: number().optional(),
15114
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15115
+ * "best" frame). Absent when the track produced no object events. */
15116
+ bestEventId: string().optional(),
15117
+ /** Tag of the importance sub-signal that dominated the score
15118
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15119
+ importanceReason: string().optional()
15074
15120
  });
15075
15121
  var BaseEventFields = {
15076
15122
  id: string(),
@@ -15135,8 +15181,18 @@ var ObjectEventSchema = object({
15135
15181
  frameHeight: number().optional(),
15136
15182
  /** MediaStore key for the crop attached to this event (if any). */
15137
15183
  mediaKey: string().optional(),
15184
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15185
+ * best-detection full frame). Resolve via the event-media data-plane
15186
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15187
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15188
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15189
+ keyFrameMediaKey: string().optional(),
15138
15190
  /** Populated by B5 (recording playback URL for this event). */
15139
- mediaUrl: string().optional()
15191
+ mediaUrl: string().optional(),
15192
+ /** The parent track's key-event importance [0,1], propagated to every object
15193
+ * event of the track (so an event row can be sorted by importance without a
15194
+ * track join). Absent on legacy rows / before the track was scored. */
15195
+ importance: number().optional()
15140
15196
  });
15141
15197
  var AudioEventSchema = object({
15142
15198
  ...BaseEventFields,
@@ -15160,7 +15216,8 @@ var MediaFileKindEnum = _enum([
15160
15216
  "fullFrame",
15161
15217
  "fullFrameBoxed",
15162
15218
  "faceCrop",
15163
- "plateCrop"
15219
+ "plateCrop",
15220
+ "keyFrame"
15164
15221
  ]);
15165
15222
  var MediaFileSchema = object({
15166
15223
  key: string(),
@@ -15181,6 +15238,32 @@ var DeviceEventQueryInput = object({
15181
15238
  projection: _enum(["full", "slim"]).optional()
15182
15239
  });
15183
15240
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15241
+ var KeyEventQueryInput = object({
15242
+ deviceId: number(),
15243
+ /** Window lower bound (track firstSeen ≥ since). */
15244
+ since: number(),
15245
+ /** Window upper bound (track firstSeen ≤ until). */
15246
+ until: number(),
15247
+ limit: number().int().min(1).max(200).default(50),
15248
+ /** Drop tracks scoring below this importance. */
15249
+ minImportance: number().min(0).max(1).optional(),
15250
+ /** Restrict to a single class (e.g. 'person'). */
15251
+ classFilter: string().optional()
15252
+ });
15253
+ var KeyEventSchema = object({
15254
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15255
+ id: string(),
15256
+ trackId: string(),
15257
+ /** Track start time (firstSeen). */
15258
+ timestamp: number(),
15259
+ className: string(),
15260
+ label: string().optional(),
15261
+ importance: number(),
15262
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15263
+ bestEventId: string(),
15264
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15265
+ windowMs: number().optional()
15266
+ });
15184
15267
  var TrackedDetectionSchema = object({
15185
15268
  trackId: string(),
15186
15269
  className: string(),
@@ -15210,7 +15293,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15210
15293
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15211
15294
  kind: "mutation",
15212
15295
  auth: "admin"
15213
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15296
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15214
15297
  deviceId: number(),
15215
15298
  since: number(),
15216
15299
  until: number(),
@@ -15977,7 +16060,12 @@ DeviceType.Camera, method(object({
15977
16060
  }), SnapshotImageSchema.nullable()), method(object({ deviceId: number() }), _void(), {
15978
16061
  kind: "mutation",
15979
16062
  auth: "admin"
15980
- });
16063
+ }), systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16064
+ deviceId: number(),
16065
+ lastCapturedAt: number().nullable(),
16066
+ cacheAgeMs: number().nullable(),
16067
+ etag: string().nullable()
16068
+ })));
15981
16069
  /**
15982
16070
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
15983
16071
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16273,10 +16361,32 @@ method(_void(), array(TurnServerSchema).readonly());
16273
16361
  * b. `finishAuthentication({userId, response})` → server verifies
16274
16362
  * the assertion, bumps the credential counter, returns ok.
16275
16363
  *
16364
+ * 2b. Usernameless (discoverable-credential) authentication — the
16365
+ * passkey IS the primary factor, no password leg:
16366
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16367
+ * EMPTY `allowCredentials` (the browser offers every resident
16368
+ * passkey it holds for this RP) + `userVerification: 'required'`
16369
+ * (the passkey replaces both factors, so UV is mandatory).
16370
+ * The challenge is stored server-side, NOT bound to any user.
16371
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16372
+ * resolves the credential by the response's credential id,
16373
+ * verifies the assertion against the stored challenge + that
16374
+ * credential's public key/counter, and returns the OWNING
16375
+ * `userId` — the caller (core auth router) mints the session.
16376
+ *
16276
16377
  * 3. Management:
16277
16378
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16278
16379
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16279
16380
  *
16381
+ * 4. Second-factor preference (opt-in, default OFF):
16382
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16383
+ * demanded as a second factor after a password login ONLY when the
16384
+ * user explicitly opts in via `setSecondFactorPreference`.
16385
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16386
+ * row ⇒ `enabled: false`).
16387
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16388
+ * the providing addon beside its credentials.
16389
+ *
16280
16390
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16281
16391
  * the admin-ui composes the begin/finish round-trip and never exposes
16282
16392
  * the cap to non-admins.
@@ -16319,6 +16429,17 @@ method(object({
16319
16429
  }), object({ verified: boolean() }), {
16320
16430
  kind: "mutation",
16321
16431
  access: "view"
16432
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16433
+ kind: "mutation",
16434
+ access: "view"
16435
+ }), method(object({
16436
+ /** AuthenticationResponseJSON from the browser. */
16437
+ response: record(string(), unknown()) }), object({
16438
+ verified: boolean(),
16439
+ userId: string().nullable()
16440
+ }), {
16441
+ kind: "mutation",
16442
+ access: "view"
16322
16443
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16323
16444
  userId: string(),
16324
16445
  credentialId: string()
@@ -16326,6 +16447,13 @@ method(object({
16326
16447
  kind: "mutation",
16327
16448
  auth: "admin",
16328
16449
  access: "delete"
16450
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16451
+ userId: string(),
16452
+ enabled: boolean()
16453
+ }), object({ success: literal(true) }), {
16454
+ kind: "mutation",
16455
+ auth: "admin",
16456
+ access: "create"
16329
16457
  });
16330
16458
  /**
16331
16459
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17127,7 +17255,17 @@ var FaceInfoSchema = object({
17127
17255
  recognizedIdentityId: string().optional(),
17128
17256
  identityName: string().optional(),
17129
17257
  assigned: boolean(),
17130
- base64: string().optional()
17258
+ base64: string().optional(),
17259
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17260
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17261
+ * legacy rows written before design B. */
17262
+ faceBbox: BoundingBoxSchema.optional(),
17263
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17264
+ * Fetch the native JPEG via the event-media data-plane
17265
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17266
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17267
+ * back to the inline `base64` face crop. */
17268
+ keyFrameMediaKey: string().optional()
17131
17269
  });
17132
17270
  var FaceFilterEnum = _enum([
17133
17271
  "unassigned",
@@ -21246,6 +21384,12 @@ Object.freeze({
21246
21384
  addonId: null,
21247
21385
  access: "view"
21248
21386
  },
21387
+ "pipelineAnalytics.getKeyEvents": {
21388
+ capName: "pipeline-analytics",
21389
+ capScope: "device",
21390
+ addonId: null,
21391
+ access: "view"
21392
+ },
21249
21393
  "pipelineAnalytics.getMotionEvents": {
21250
21394
  capName: "pipeline-analytics",
21251
21395
  capScope: "device",
@@ -21774,6 +21918,12 @@ Object.freeze({
21774
21918
  addonId: null,
21775
21919
  access: "view"
21776
21920
  },
21921
+ "pipelineRunner.getNativeCrop": {
21922
+ capName: "pipeline-runner",
21923
+ capScope: "system",
21924
+ addonId: null,
21925
+ access: "view"
21926
+ },
21777
21927
  "pipelineRunner.reportMotion": {
21778
21928
  capName: "pipeline-runner",
21779
21929
  capScope: "system",
@@ -22140,6 +22290,12 @@ Object.freeze({
22140
22290
  addonId: null,
22141
22291
  access: "view"
22142
22292
  },
22293
+ "snapshot.getSnapshotOverview": {
22294
+ capName: "snapshot",
22295
+ capScope: "device",
22296
+ addonId: null,
22297
+ access: "view"
22298
+ },
22143
22299
  "snapshot.invalidateCache": {
22144
22300
  capName: "snapshot",
22145
22301
  capScope: "device",
@@ -22818,6 +22974,12 @@ Object.freeze({
22818
22974
  addonId: null,
22819
22975
  access: "view"
22820
22976
  },
22977
+ "userPasskeys.beginDiscoverableAuthentication": {
22978
+ capName: "user-passkeys",
22979
+ capScope: "system",
22980
+ addonId: null,
22981
+ access: "view"
22982
+ },
22821
22983
  "userPasskeys.beginRegistration": {
22822
22984
  capName: "user-passkeys",
22823
22985
  capScope: "system",
@@ -22830,12 +22992,24 @@ Object.freeze({
22830
22992
  addonId: null,
22831
22993
  access: "view"
22832
22994
  },
22995
+ "userPasskeys.finishDiscoverableAuthentication": {
22996
+ capName: "user-passkeys",
22997
+ capScope: "system",
22998
+ addonId: null,
22999
+ access: "view"
23000
+ },
22833
23001
  "userPasskeys.finishRegistration": {
22834
23002
  capName: "user-passkeys",
22835
23003
  capScope: "system",
22836
23004
  addonId: null,
22837
23005
  access: "create"
22838
23006
  },
23007
+ "userPasskeys.getSecondFactorPreference": {
23008
+ capName: "user-passkeys",
23009
+ capScope: "system",
23010
+ addonId: null,
23011
+ access: "view"
23012
+ },
22839
23013
  "userPasskeys.listPasskeys": {
22840
23014
  capName: "user-passkeys",
22841
23015
  capScope: "system",
@@ -22848,6 +23022,12 @@ Object.freeze({
22848
23022
  addonId: null,
22849
23023
  access: "delete"
22850
23024
  },
23025
+ "userPasskeys.setSecondFactorPreference": {
23026
+ capName: "user-passkeys",
23027
+ capScope: "system",
23028
+ addonId: null,
23029
+ access: "create"
23030
+ },
22851
23031
  "vacuumControl.locate": {
22852
23032
  capName: "vacuum-control",
22853
23033
  capScope: "device",
@@ -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-BTuv4hPh.js");
5
+ const require_shared = require("./shared-BS3ZpipR.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-m1upfQvq.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-DQjNIB1f.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.1.21",
3
+ "version": "1.1.22",
4
4
  "description": "Remote storage providers (SFTP, S3, WebDAV) — unifies remote backends behind the storage-provider cap",
5
5
  "keywords": [
6
6
  "camstack",