@camstack/addon-provider-rtsp 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.
Files changed (3) hide show
  1. package/dist/addon.js +541 -95
  2. package/dist/addon.mjs +541 -95
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -4666,7 +4666,7 @@ function preprocess(fn, schema) {
4666
4666
  });
4667
4667
  }
4668
4668
  //#endregion
4669
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4669
+ //#region ../types/dist/sleep-Baang_XW.mjs
4670
4670
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4671
4671
  EventCategory["SystemBoot"] = "system.boot";
4672
4672
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5387,10 +5387,6 @@ function hydrateField(field, values) {
5387
5387
  };
5388
5388
  }
5389
5389
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5390
- if (field.type === "password") return {
5391
- ...field,
5392
- value: ""
5393
- };
5394
5390
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5395
5391
  return {
5396
5392
  ...field,
@@ -6774,10 +6770,25 @@ function method(input, output, options) {
6774
6770
  timeoutMs: options?.timeoutMs
6775
6771
  };
6776
6772
  }
6773
+ /**
6774
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6775
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6776
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6777
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6778
+ */
6779
+ function systemMethod(input, output, options) {
6780
+ return {
6781
+ ...method(input, output, options),
6782
+ systemOnly: true
6783
+ };
6784
+ }
6777
6785
  /** Shorthand to define an event schema */
6778
6786
  function event(data) {
6779
6787
  return { data };
6780
6788
  }
6789
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6790
+ var VersionOutputSchema$1 = object({ version: string() });
6791
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6781
6792
  var StaticDirOutputSchema = object({ staticDir: string() });
6782
6793
  var VersionOutputSchema = object({ version: string() });
6783
6794
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -11697,7 +11708,7 @@ var BoundingBoxSchema = object({
11697
11708
  w: number(),
11698
11709
  h: number()
11699
11710
  });
11700
- var SpatialDetectionSchema = object({
11711
+ object({
11701
11712
  class: string(),
11702
11713
  originalClass: string(),
11703
11714
  score: number(),
@@ -11872,6 +11883,7 @@ var PipelineAddonSchemaSchema = object({
11872
11883
  defaultModelId: string(),
11873
11884
  defaultModelIdByFormat: record(string(), string()).optional(),
11874
11885
  enabledByDefault: boolean().optional(),
11886
+ backfillIntoExistingOverrides: boolean().optional(),
11875
11887
  defaultConfidence: number(),
11876
11888
  group: string().optional(),
11877
11889
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -11888,11 +11900,6 @@ var PipelineSchemaSchema = object({
11888
11900
  selectedEngine: PipelineEngineChoiceSchema,
11889
11901
  slots: array(PipelineSlotSchemaSchema).readonly()
11890
11902
  });
11891
- var DetectorOutputSchema = object({
11892
- detections: array(SpatialDetectionSchema).readonly(),
11893
- inferenceMs: number(),
11894
- modelId: string()
11895
- });
11896
11903
  var EngineProvisioningSchema = object({
11897
11904
  runtimeId: _enum([
11898
11905
  "onnx",
@@ -12017,7 +12024,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12017
12024
  auth: "admin"
12018
12025
  }), method(object({ nodeId: string() }), object({
12019
12026
  success: literal(true),
12020
- regeneratedModelId: string().nullable()
12027
+ clearedDevices: number()
12021
12028
  }), {
12022
12029
  kind: "mutation",
12023
12030
  auth: "admin"
@@ -12038,10 +12045,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12038
12045
  modelId: string(),
12039
12046
  format: ModelFormatSchema$1
12040
12047
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
12041
- addonId: string(),
12042
- frame: FrameInputSchema,
12043
- config: record(string(), unknown()).optional()
12044
- }), DetectorOutputSchema), method(object({
12045
12048
  engine: PipelineEngineChoiceSchema.optional(),
12046
12049
  steps: array(PipelineStepInputSchema).min(1),
12047
12050
  frame: FrameInputSchema.optional(),
@@ -12062,7 +12065,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12062
12065
  image: _instanceof(Uint8Array).optional(),
12063
12066
  referenceImage: string().optional(),
12064
12067
  deviceId: number().optional(),
12065
- sessionId: string().optional()
12068
+ sessionId: string().optional(),
12069
+ /**
12070
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
12071
+ * reference-image, and detail-subtree calls. 'frame' is the live
12072
+ * per-frame dispatch: ONLY root-plane steps run; crop children
12073
+ * (inputClasses ≠ null) are skipped and served per-track via
12074
+ * pipelineRunner.runDetailSubtree (two-plane design).
12075
+ */
12076
+ plane: _enum(["full", "frame"]).optional()
12066
12077
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
12067
12078
  engine: PipelineEngineChoiceSchema.optional(),
12068
12079
  steps: array(PipelineStepInputSchema).min(1),
@@ -12220,6 +12231,47 @@ var zonesCapability = {
12220
12231
  runtimeState: object({ zones: array(ZoneSchema).readonly() })
12221
12232
  };
12222
12233
  /**
12234
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
12235
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
12236
+ * so the caller supplies only the detection-res bbox divided by the detection
12237
+ * dims — no native resolution to plumb.
12238
+ */
12239
+ var NativeCropBboxSchema = object({
12240
+ x: number(),
12241
+ y: number(),
12242
+ w: number(),
12243
+ h: number()
12244
+ });
12245
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
12246
+ var NativeCropResultSchema = object({
12247
+ /** Packed rgb (24-bit) pixels of the crop. */
12248
+ bytes: _instanceof(Uint8Array),
12249
+ width: number().int().positive(),
12250
+ height: number().int().positive()
12251
+ });
12252
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
12253
+ * originating detection, in FRAME-space coordinates. Reuses
12254
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
12255
+ * the coordinates are frame-space rather than getNativeCrop's
12256
+ * normalized [0,1] convention). */
12257
+ var DetailParentSchema = object({
12258
+ bbox: NativeCropBboxSchema,
12259
+ className: string()
12260
+ });
12261
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
12262
+ * or refined detection produced by running the crop-subtree on a
12263
+ * single tracked detection. */
12264
+ var DetailResultSchema = object({
12265
+ stepId: string(),
12266
+ className: string(),
12267
+ score: number(),
12268
+ /** FRAME-space bbox (already mapped back from crop space). */
12269
+ bbox: NativeCropBboxSchema.optional(),
12270
+ embedding: string().optional(),
12271
+ label: string().optional(),
12272
+ alignedCropJpeg: string().optional()
12273
+ });
12274
+ /**
12223
12275
  * Per-camera tunable ranges + defaults. Single source of truth used
12224
12276
  * by both the Zod data schema (validation + default fallback) and
12225
12277
  * the device settings UI (slider min/max/step). Touch one place and
@@ -12475,7 +12527,17 @@ var RunnerLocalMetricsSchema = object({
12475
12527
  avgInferenceTimeMs: number(),
12476
12528
  queueDepth: number()
12477
12529
  });
12478
- 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());
12530
+ 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({
12531
+ handle: FrameHandleSchema,
12532
+ bbox: NativeCropBboxSchema,
12533
+ maxWidth: number().int().positive().optional()
12534
+ }), NativeCropResultSchema.nullable()), method(object({
12535
+ deviceId: number(),
12536
+ frameHandle: FrameHandleSchema.optional(),
12537
+ cropJpeg: string().optional(),
12538
+ parent: DetailParentSchema,
12539
+ steps: array(string()).optional()
12540
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
12479
12541
  /**
12480
12542
  * Hardware / firmware motion sensor cap — binary detected state plus
12481
12543
  * a timestamp of the last observation. Distinct from
@@ -15406,7 +15468,9 @@ var AddonPageDeclarationSchema$1 = object({
15406
15468
  icon: string(),
15407
15469
  path: string(),
15408
15470
  remoteName: string(),
15409
- bundle: string()
15471
+ bundle: string(),
15472
+ section: string().optional(),
15473
+ sectionLabel: string().optional()
15410
15474
  });
15411
15475
  var AddonPageInfoSchema = object({
15412
15476
  addonId: string(),
@@ -15446,7 +15510,18 @@ var AddonPageDeclarationSchema = object({
15446
15510
  * the static-file route can compute an mtime-based cache-buster URL
15447
15511
  * without a separate filesystem stat.
15448
15512
  */
15449
- bundle: string()
15513
+ bundle: string(),
15514
+ /**
15515
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
15516
+ * `'cluster'`, `'administration'` — the page renders inside that group.
15517
+ * Any OTHER string creates (or joins) a custom section rendered after
15518
+ * the built-in groups; its label comes from `sectionLabel` (first
15519
+ * declaration wins), falling back to the id. Absent → the legacy
15520
+ * "Addon Pages" group.
15521
+ */
15522
+ section: string().optional(),
15523
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
15524
+ sectionLabel: string().optional()
15450
15525
  });
15451
15526
  method(_void(), array(AddonPageDeclarationSchema).readonly());
15452
15527
  var AddonHttpRouteSchema = object({
@@ -15662,6 +15737,17 @@ var WidgetMetadataSchema = object({
15662
15737
  deviceContext: boolean().default(false),
15663
15738
  integrationContext: boolean().default(false)
15664
15739
  }),
15740
+ /**
15741
+ * Loadable BEFORE authentication. The normal widget registry listing
15742
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
15743
+ * (the login page) cannot discover a widget through it. A widget that
15744
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
15745
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
15746
+ * login-method contribution channel (see `login-method.cap.ts`) rather
15747
+ * than the authenticated registry, and its bundle is served by the
15748
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
15749
+ */
15750
+ preAuth: boolean().optional().default(false),
15665
15751
  /** Dashboard placement HINTS (operator can override per instance). */
15666
15752
  defaultSize: WidgetSizeEnum.default("md"),
15667
15753
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -15963,6 +16049,66 @@ method(object({
15963
16049
  password: string()
15964
16050
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
15965
16051
  /**
16052
+ * `login-method` — collection cap through which auth addons contribute
16053
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
16054
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
16055
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
16056
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
16057
+ * procedure aggregates them for the unauthenticated login page.
16058
+ *
16059
+ * A contribution is a discriminated union on `kind`:
16060
+ *
16061
+ * - `redirect` — a declarative button. The login page renders a generic
16062
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
16063
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
16064
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
16065
+ * login page needs NO change.
16066
+ *
16067
+ * - `widget` — a Module-Federation widget the login page mounts (via
16068
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
16069
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
16070
+ * addon bundle. The referenced widget also declares `preAuth: true` in
16071
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
16072
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
16073
+ *
16074
+ * Every contribution carries a `stage`:
16075
+ * - `primary` — shown on the first credentials screen (OIDC /
16076
+ * magic-link buttons; a future usernameless passkey).
16077
+ * - `second-factor` — shown AFTER the password leg, gated on the
16078
+ * returned `factors` (passkey-as-2FA today).
16079
+ *
16080
+ * `mount: skip` — the cap is read server-side by the core auth router
16081
+ * (`registry.getCollection('login-method')`), never mounted as its own
16082
+ * tRPC router.
16083
+ */
16084
+ /** When a login method renders in the two-phase login flow. */
16085
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
16086
+ /** One login-method contribution — redirect button OR pre-auth widget. */
16087
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
16088
+ kind: literal("redirect"),
16089
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
16090
+ id: string(),
16091
+ /** Operator-facing button label. */
16092
+ label: string(),
16093
+ /** lucide-react icon name. */
16094
+ icon: string().optional(),
16095
+ /** Addon-owned HTTP route the button navigates to (GET). */
16096
+ startUrl: string(),
16097
+ stage: LoginStageEnum
16098
+ }), object({
16099
+ kind: literal("widget"),
16100
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
16101
+ id: string(),
16102
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
16103
+ addonId: string(),
16104
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
16105
+ bundle: string(),
16106
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
16107
+ remote: WidgetRemoteSchema,
16108
+ stage: LoginStageEnum
16109
+ })]);
16110
+ method(_void(), array(LoginMethodContributionSchema).readonly());
16111
+ /**
15966
16112
  * Orchestrator-side destination metadata. The orchestrator computes
15967
16113
  * `id = <addonId>:<subId>` from its provider lookup so consumers
15968
16114
  * (admin UI, restore flow) see one canonical key.
@@ -18066,7 +18212,17 @@ var TrackSchema = object({
18066
18212
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
18067
18213
  totalDistance: number(),
18068
18214
  state: TrackStateSchema,
18069
- active: boolean()
18215
+ active: boolean(),
18216
+ /** Deterministic key-event importance score in [0,1] (server-computed at
18217
+ * track expiry, recomputed on late label). Absent on legacy rows written
18218
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
18219
+ importance: number().optional(),
18220
+ /** Id of the track's highest-confidence ObjectEvent (its representative
18221
+ * "best" frame). Absent when the track produced no object events. */
18222
+ bestEventId: string().optional(),
18223
+ /** Tag of the importance sub-signal that dominated the score
18224
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
18225
+ importanceReason: string().optional()
18070
18226
  });
18071
18227
  var BaseEventFields = {
18072
18228
  id: string(),
@@ -18131,8 +18287,18 @@ var ObjectEventSchema = object({
18131
18287
  frameHeight: number().optional(),
18132
18288
  /** MediaStore key for the crop attached to this event (if any). */
18133
18289
  mediaKey: string().optional(),
18290
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
18291
+ * best-detection full frame). Resolve via the event-media data-plane
18292
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
18293
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
18294
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
18295
+ keyFrameMediaKey: string().optional(),
18134
18296
  /** Populated by B5 (recording playback URL for this event). */
18135
- mediaUrl: string().optional()
18297
+ mediaUrl: string().optional(),
18298
+ /** The parent track's key-event importance [0,1], propagated to every object
18299
+ * event of the track (so an event row can be sorted by importance without a
18300
+ * track join). Absent on legacy rows / before the track was scored. */
18301
+ importance: number().optional()
18136
18302
  });
18137
18303
  var AudioEventSchema = object({
18138
18304
  ...BaseEventFields,
@@ -18156,7 +18322,8 @@ var MediaFileKindEnum = _enum([
18156
18322
  "fullFrame",
18157
18323
  "fullFrameBoxed",
18158
18324
  "faceCrop",
18159
- "plateCrop"
18325
+ "plateCrop",
18326
+ "keyFrame"
18160
18327
  ]);
18161
18328
  var MediaFileSchema = object({
18162
18329
  key: string(),
@@ -18177,6 +18344,32 @@ var DeviceEventQueryInput = object({
18177
18344
  projection: _enum(["full", "slim"]).optional()
18178
18345
  });
18179
18346
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
18347
+ var KeyEventQueryInput = object({
18348
+ deviceId: number(),
18349
+ /** Window lower bound (track firstSeen ≥ since). */
18350
+ since: number(),
18351
+ /** Window upper bound (track firstSeen ≤ until). */
18352
+ until: number(),
18353
+ limit: number().int().min(1).max(200).default(50),
18354
+ /** Drop tracks scoring below this importance. */
18355
+ minImportance: number().min(0).max(1).optional(),
18356
+ /** Restrict to a single class (e.g. 'person'). */
18357
+ classFilter: string().optional()
18358
+ });
18359
+ var KeyEventSchema = object({
18360
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
18361
+ id: string(),
18362
+ trackId: string(),
18363
+ /** Track start time (firstSeen). */
18364
+ timestamp: number(),
18365
+ className: string(),
18366
+ label: string().optional(),
18367
+ importance: number(),
18368
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
18369
+ bestEventId: string(),
18370
+ /** Track lifetime in ms (lastSeen - firstSeen). */
18371
+ windowMs: number().optional()
18372
+ });
18180
18373
  var TrackedDetectionSchema = object({
18181
18374
  trackId: string(),
18182
18375
  className: string(),
@@ -18206,7 +18399,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18206
18399
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
18207
18400
  kind: "mutation",
18208
18401
  auth: "admin"
18209
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
18402
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
18210
18403
  deviceId: number(),
18211
18404
  since: number(),
18212
18405
  until: number(),
@@ -18280,7 +18473,12 @@ var AgentPipelineSettingsSchema = object({
18280
18473
  detectWeight: number().positive().optional(),
18281
18474
  /** Node is eligible to run the detection pipeline (decode + inference). */
18282
18475
  detect: boolean().optional(),
18283
- /** Node is eligible to host decoder sessions. */
18476
+ /**
18477
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
18478
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
18479
+ * the schema ONLY so persisted stores written before the removal still
18480
+ * parse — no code reads it and no write path emits it.
18481
+ */
18284
18482
  decode: boolean().optional(),
18285
18483
  /** Node is eligible to run audio-analyzer sessions. */
18286
18484
  audio: boolean().optional(),
@@ -18341,25 +18539,6 @@ var PipelineAssignmentSchema = object({
18341
18539
  assignedAt: number()
18342
18540
  });
18343
18541
  /**
18344
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
18345
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
18346
- * → co-located with pipeline → capacity).
18347
- */
18348
- var DecoderAssignmentSchema = object({
18349
- deviceId: number(),
18350
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
18351
- decoderNodeId: string(),
18352
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
18353
- pinned: boolean(),
18354
- /** Why this assignment was made — useful for debugging the decoder balancer. */
18355
- reason: _enum([
18356
- "manual",
18357
- "co-located",
18358
- "capacity",
18359
- "hardware-affinity"
18360
- ])
18361
- });
18362
- /**
18363
18542
  * Per-agent load summary surfaced to the load balancer + dashboards.
18364
18543
  * Aggregated from each runner's `getLocalLoad` cap call.
18365
18544
  */
@@ -18565,15 +18744,6 @@ method(object({
18565
18744
  }), method(_void(), IngestOwnerSchema), method(object({
18566
18745
  deviceId: number(),
18567
18746
  nodeId: string()
18568
- }), _void(), {
18569
- kind: "mutation",
18570
- auth: "admin"
18571
- }), method(object({ deviceId: number() }), _void(), {
18572
- kind: "mutation",
18573
- auth: "admin"
18574
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
18575
- deviceId: number(),
18576
- nodeId: string()
18577
18747
  }), object({ success: literal(true) }), {
18578
18748
  kind: "mutation",
18579
18749
  auth: "admin"
@@ -18592,10 +18762,7 @@ method(object({
18592
18762
  nodeId: string(),
18593
18763
  pinned: boolean(),
18594
18764
  assignedAt: number()
18595
- }))), method(object({
18596
- deviceId: number(),
18597
- pipelineNodeId: string().optional()
18598
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18765
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18599
18766
  nodeId: string(),
18600
18767
  settings: AgentPipelineSettingsSchema
18601
18768
  })).readonly()), method(object({
@@ -18625,7 +18792,6 @@ method(object({
18625
18792
  }), method(object({
18626
18793
  agentNodeId: string(),
18627
18794
  detect: boolean().nullable().optional(),
18628
- decode: boolean().nullable().optional(),
18629
18795
  audio: boolean().nullable().optional(),
18630
18796
  ingest: boolean().nullable().optional()
18631
18797
  }), object({ success: literal(true) }), {
@@ -18637,6 +18803,15 @@ method(object({
18637
18803
  }), object({ success: literal(true) }), {
18638
18804
  kind: "mutation",
18639
18805
  auth: "admin"
18806
+ }), method(object({ agentNodeId: string() }), object({
18807
+ success: literal(true),
18808
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
18809
+ effectiveModelId: string().nullable(),
18810
+ /** Number of cameras whose node-scoped overrides were cleared. */
18811
+ clearedCameraOverrides: number()
18812
+ }), {
18813
+ kind: "mutation",
18814
+ auth: "admin"
18640
18815
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18641
18816
  deviceId: number(),
18642
18817
  addonId: string(),
@@ -18682,6 +18857,131 @@ method(object({
18682
18857
  auth: "admin"
18683
18858
  });
18684
18859
  /**
18860
+ * server-management — per-NODE singleton capability for a node's ROOT
18861
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
18862
+ * agents).
18863
+ *
18864
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
18865
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
18866
+ * version describes the node. Updates install into
18867
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
18868
+ * starter (probation boot + auto-rollback to N-1).
18869
+ *
18870
+ * Providers:
18871
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
18872
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
18873
+ * unpinned calls.
18874
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
18875
+ * the synthetic `agent-runtime` addonId and declared in the agent's
18876
+ * `$hub.registerNode` manifest.
18877
+ *
18878
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
18879
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
18880
+ * SDK) routes the call to that node's provider via the standard remote
18881
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
18882
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
18883
+ *
18884
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
18885
+ */
18886
+ /**
18887
+ * Where the running hub's code was loaded from:
18888
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
18889
+ * plain resolution and runtime updates are refused.
18890
+ * - `baked` — the immutable image seed closure (no data-dir root active).
18891
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
18892
+ */
18893
+ var ServerBootModeSchema = _enum([
18894
+ "workspace",
18895
+ "baked",
18896
+ "data-root"
18897
+ ]);
18898
+ /**
18899
+ * Update lifecycle state:
18900
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
18901
+ * - `pending-restart` — a version is staged and the node has NOT yet
18902
+ * restarted onto it (still running the OLD version).
18903
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
18904
+ * (it is the active probation boot) and is waiting to confirm boot-health.
18905
+ * Apply/rollback are refused in this state and the node must NOT be
18906
+ * manually restarted, or the probation boot auto-rolls-back.
18907
+ */
18908
+ var ServerUpdateStateSchema = _enum([
18909
+ "idle",
18910
+ "checking",
18911
+ "staging",
18912
+ "pending-restart",
18913
+ "awaiting-confirmation"
18914
+ ]);
18915
+ var ServerRollbackInfoSchema = object({
18916
+ /** The version that failed (or was manually rolled back). */
18917
+ fromVersion: string(),
18918
+ /** The version rolled back to; null = the baked seed. */
18919
+ toVersion: string().nullable(),
18920
+ atMs: number(),
18921
+ reason: string()
18922
+ });
18923
+ var ServerPackageStatusSchema = object({
18924
+ /** Root package name (`@camstack/server` on the hub). */
18925
+ packageName: string(),
18926
+ /** Version of the code the running process ACTUALLY loaded. */
18927
+ runningVersion: string().nullable(),
18928
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
18929
+ nodeRuntimeVersion: string().nullable(),
18930
+ /** Active data-dir root version; null when booted from seed/workspace. */
18931
+ activeVersion: string().nullable(),
18932
+ /** N-1 version kept for rollback; null when no previous version exists. */
18933
+ previousVersion: string().nullable(),
18934
+ /** Version of the immutable baked seed closure (image fallback). */
18935
+ seedVersion: string().nullable(),
18936
+ /** Latest registry version from the most recent check (null = never checked). */
18937
+ latestVersion: string().nullable(),
18938
+ updateAvailable: boolean(),
18939
+ bootMode: ServerBootModeSchema,
18940
+ updateState: ServerUpdateStateSchema,
18941
+ /** Version staged + awaiting its probation boot, when one is pending. */
18942
+ pendingVersion: string().nullable(),
18943
+ /** Set when the last freshly-activated version failed its boot health-check. */
18944
+ rolledBack: ServerRollbackInfoSchema.nullable(),
18945
+ /**
18946
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
18947
+ * hub is running from the baked seed (or workspace) while installed data-dir
18948
+ * versions are being IGNORED. Surfaced as a warning in the UI.
18949
+ */
18950
+ stateFileCorrupt: boolean(),
18951
+ lastCheckedAtMs: number().nullable()
18952
+ });
18953
+ var ServerUpdateCheckResultSchema = object({
18954
+ packageName: string(),
18955
+ runningVersion: string().nullable(),
18956
+ latestVersion: string().nullable(),
18957
+ updateAvailable: boolean(),
18958
+ checkedAtMs: number(),
18959
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
18960
+ error: string().nullable()
18961
+ });
18962
+ var ServerUpdateActionResultSchema = object({
18963
+ accepted: boolean(),
18964
+ targetVersion: string().nullable(),
18965
+ /** True when a graceful restart was scheduled to apply the change. */
18966
+ restarting: boolean(),
18967
+ message: string()
18968
+ });
18969
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
18970
+ kind: "mutation",
18971
+ auth: "admin"
18972
+ }), method(object({
18973
+ /** Explicit target version; omitted = latest from the registry. */
18974
+ version: string().optional() }), ServerUpdateActionResultSchema, {
18975
+ kind: "mutation",
18976
+ auth: "admin"
18977
+ }), method(_void(), ServerUpdateActionResultSchema, {
18978
+ kind: "mutation",
18979
+ auth: "admin"
18980
+ }), method(_void(), ServerUpdateActionResultSchema, {
18981
+ kind: "mutation",
18982
+ auth: "admin"
18983
+ });
18984
+ /**
18685
18985
  * Query filter for settings-store collections.
18686
18986
  */
18687
18987
  var QueryFilterSchema = object({
@@ -18903,7 +19203,20 @@ var snapshotCapability = {
18903
19203
  invalidateCache: method(object({ deviceId: number() }), _void(), {
18904
19204
  kind: "mutation",
18905
19205
  auth: "admin"
18906
- })
19206
+ }),
19207
+ /**
19208
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
19209
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
19210
+ * devices that never produced a frame, and gives it an ETag per device for
19211
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
19212
+ * are null for a device with no cached frame.
19213
+ */
19214
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
19215
+ deviceId: number(),
19216
+ lastCapturedAt: number().nullable(),
19217
+ cacheAgeMs: number().nullable(),
19218
+ etag: string().nullable()
19219
+ })))
18907
19220
  },
18908
19221
  status: {
18909
19222
  schema: SnapshotStatusSchema,
@@ -19160,10 +19473,32 @@ method(_void(), array(TurnServerSchema).readonly());
19160
19473
  * b. `finishAuthentication({userId, response})` → server verifies
19161
19474
  * the assertion, bumps the credential counter, returns ok.
19162
19475
  *
19476
+ * 2b. Usernameless (discoverable-credential) authentication — the
19477
+ * passkey IS the primary factor, no password leg:
19478
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
19479
+ * EMPTY `allowCredentials` (the browser offers every resident
19480
+ * passkey it holds for this RP) + `userVerification: 'required'`
19481
+ * (the passkey replaces both factors, so UV is mandatory).
19482
+ * The challenge is stored server-side, NOT bound to any user.
19483
+ * b. `finishDiscoverableAuthentication({response})` → the provider
19484
+ * resolves the credential by the response's credential id,
19485
+ * verifies the assertion against the stored challenge + that
19486
+ * credential's public key/counter, and returns the OWNING
19487
+ * `userId` — the caller (core auth router) mints the session.
19488
+ *
19163
19489
  * 3. Management:
19164
19490
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
19165
19491
  * - `removePasskey({userId, credentialId})` — revoke one credential.
19166
19492
  *
19493
+ * 4. Second-factor preference (opt-in, default OFF):
19494
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
19495
+ * demanded as a second factor after a password login ONLY when the
19496
+ * user explicitly opts in via `setSecondFactorPreference`.
19497
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
19498
+ * row ⇒ `enabled: false`).
19499
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
19500
+ * the providing addon beside its credentials.
19501
+ *
19167
19502
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
19168
19503
  * the admin-ui composes the begin/finish round-trip and never exposes
19169
19504
  * the cap to non-admins.
@@ -19206,6 +19541,17 @@ method(object({
19206
19541
  }), object({ verified: boolean() }), {
19207
19542
  kind: "mutation",
19208
19543
  access: "view"
19544
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
19545
+ kind: "mutation",
19546
+ access: "view"
19547
+ }), method(object({
19548
+ /** AuthenticationResponseJSON from the browser. */
19549
+ response: record(string(), unknown()) }), object({
19550
+ verified: boolean(),
19551
+ userId: string().nullable()
19552
+ }), {
19553
+ kind: "mutation",
19554
+ access: "view"
19209
19555
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
19210
19556
  userId: string(),
19211
19557
  credentialId: string()
@@ -19213,6 +19559,13 @@ method(object({
19213
19559
  kind: "mutation",
19214
19560
  auth: "admin",
19215
19561
  access: "delete"
19562
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
19563
+ userId: string(),
19564
+ enabled: boolean()
19565
+ }), object({ success: literal(true) }), {
19566
+ kind: "mutation",
19567
+ auth: "admin",
19568
+ access: "create"
19216
19569
  });
19217
19570
  /**
19218
19571
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -20014,7 +20367,17 @@ var FaceInfoSchema = object({
20014
20367
  recognizedIdentityId: string().optional(),
20015
20368
  identityName: string().optional(),
20016
20369
  assigned: boolean(),
20017
- base64: string().optional()
20370
+ base64: string().optional(),
20371
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
20372
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
20373
+ * legacy rows written before design B. */
20374
+ faceBbox: BoundingBoxSchema.optional(),
20375
+ /** Design B: MediaStore key of the track's native-resolution key frame.
20376
+ * Fetch the native JPEG via the event-media data-plane
20377
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
20378
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
20379
+ * back to the inline `base64` face crop. */
20380
+ keyFrameMediaKey: string().optional()
20018
20381
  });
20019
20382
  var FaceFilterEnum = _enum([
20020
20383
  "unassigned",
@@ -20711,6 +21074,16 @@ var TopologyCategorySchema = object({
20711
21074
  healthy: number(),
20712
21075
  addons: array(TopologyCategoryAddonSchema).readonly()
20713
21076
  });
21077
+ /**
21078
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
21079
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
21080
+ * version visibility for the Server management surface. Nullable: offline
21081
+ * rows and pre-phase-2 nodes report none.
21082
+ */
21083
+ var TopologyRootPackageSchema = object({
21084
+ name: string(),
21085
+ version: string()
21086
+ });
20714
21087
  var TopologyNodeSchema = object({
20715
21088
  id: string(),
20716
21089
  name: string(),
@@ -20734,7 +21107,8 @@ var TopologyNodeSchema = object({
20734
21107
  status: string()
20735
21108
  })).readonly(),
20736
21109
  processes: array(TopologyProcessSchema).readonly(),
20737
- categories: array(TopologyCategorySchema).readonly()
21110
+ categories: array(TopologyCategorySchema).readonly(),
21111
+ rootPackage: TopologyRootPackageSchema.nullable()
20738
21112
  });
20739
21113
  var CapUsageEdgeSchema = object({
20740
21114
  callerAddonId: string(),
@@ -23547,6 +23921,12 @@ Object.freeze({
23547
23921
  addonId: null,
23548
23922
  access: "create"
23549
23923
  },
23924
+ "loginMethod.getLoginMethods": {
23925
+ capName: "login-method",
23926
+ capScope: "system",
23927
+ addonId: null,
23928
+ access: "view"
23929
+ },
23550
23930
  "mediaPlayer.next": {
23551
23931
  capName: "media-player",
23552
23932
  capScope: "device",
@@ -24129,6 +24509,12 @@ Object.freeze({
24129
24509
  addonId: null,
24130
24510
  access: "view"
24131
24511
  },
24512
+ "pipelineAnalytics.getKeyEvents": {
24513
+ capName: "pipeline-analytics",
24514
+ capScope: "device",
24515
+ addonId: null,
24516
+ access: "view"
24517
+ },
24132
24518
  "pipelineAnalytics.getMotionEvents": {
24133
24519
  capName: "pipeline-analytics",
24134
24520
  capScope: "device",
@@ -24177,23 +24563,23 @@ Object.freeze({
24177
24563
  addonId: null,
24178
24564
  access: "create"
24179
24565
  },
24180
- "pipelineExecutor.deleteModel": {
24566
+ "pipelineExecutor.clearDeviceOverrides": {
24181
24567
  capName: "pipeline-executor",
24182
24568
  capScope: "system",
24183
24569
  addonId: null,
24184
24570
  access: "delete"
24185
24571
  },
24186
- "pipelineExecutor.deleteTemplate": {
24572
+ "pipelineExecutor.deleteModel": {
24187
24573
  capName: "pipeline-executor",
24188
24574
  capScope: "system",
24189
24575
  addonId: null,
24190
24576
  access: "delete"
24191
24577
  },
24192
- "pipelineExecutor.detect": {
24578
+ "pipelineExecutor.deleteTemplate": {
24193
24579
  capName: "pipeline-executor",
24194
24580
  capScope: "system",
24195
24581
  addonId: null,
24196
- access: "view"
24582
+ access: "delete"
24197
24583
  },
24198
24584
  "pipelineExecutor.downloadModel": {
24199
24585
  capName: "pipeline-executor",
@@ -24339,12 +24725,6 @@ Object.freeze({
24339
24725
  addonId: null,
24340
24726
  access: "create"
24341
24727
  },
24342
- "pipelineExecutor.resetToDefault": {
24343
- capName: "pipeline-executor",
24344
- capScope: "system",
24345
- addonId: null,
24346
- access: "delete"
24347
- },
24348
24728
  "pipelineExecutor.runAudioTest": {
24349
24729
  capName: "pipeline-executor",
24350
24730
  capScope: "system",
@@ -24405,12 +24785,6 @@ Object.freeze({
24405
24785
  addonId: null,
24406
24786
  access: "create"
24407
24787
  },
24408
- "pipelineOrchestrator.assignDecoder": {
24409
- capName: "pipeline-orchestrator",
24410
- capScope: "system",
24411
- addonId: null,
24412
- access: "create"
24413
- },
24414
24788
  "pipelineOrchestrator.assignPipeline": {
24415
24789
  capName: "pipeline-orchestrator",
24416
24790
  capScope: "system",
@@ -24489,18 +24863,6 @@ Object.freeze({
24489
24863
  addonId: null,
24490
24864
  access: "view"
24491
24865
  },
24492
- "pipelineOrchestrator.getDecoderAssignment": {
24493
- capName: "pipeline-orchestrator",
24494
- capScope: "system",
24495
- addonId: null,
24496
- access: "view"
24497
- },
24498
- "pipelineOrchestrator.getDecoderAssignments": {
24499
- capName: "pipeline-orchestrator",
24500
- capScope: "system",
24501
- addonId: null,
24502
- access: "view"
24503
- },
24504
24866
  "pipelineOrchestrator.getGlobalMetrics": {
24505
24867
  capName: "pipeline-orchestrator",
24506
24868
  capScope: "system",
@@ -24549,6 +24911,12 @@ Object.freeze({
24549
24911
  addonId: null,
24550
24912
  access: "delete"
24551
24913
  },
24914
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
24915
+ capName: "pipeline-orchestrator",
24916
+ capScope: "system",
24917
+ addonId: null,
24918
+ access: "delete"
24919
+ },
24552
24920
  "pipelineOrchestrator.resolvePipeline": {
24553
24921
  capName: "pipeline-orchestrator",
24554
24922
  capScope: "system",
@@ -24621,12 +24989,6 @@ Object.freeze({
24621
24989
  addonId: null,
24622
24990
  access: "create"
24623
24991
  },
24624
- "pipelineOrchestrator.unassignDecoder": {
24625
- capName: "pipeline-orchestrator",
24626
- capScope: "system",
24627
- addonId: null,
24628
- access: "create"
24629
- },
24630
24992
  "pipelineOrchestrator.unassignPipeline": {
24631
24993
  capName: "pipeline-orchestrator",
24632
24994
  capScope: "system",
@@ -24681,12 +25043,24 @@ Object.freeze({
24681
25043
  addonId: null,
24682
25044
  access: "view"
24683
25045
  },
25046
+ "pipelineRunner.getNativeCrop": {
25047
+ capName: "pipeline-runner",
25048
+ capScope: "system",
25049
+ addonId: null,
25050
+ access: "view"
25051
+ },
24684
25052
  "pipelineRunner.reportMotion": {
24685
25053
  capName: "pipeline-runner",
24686
25054
  capScope: "system",
24687
25055
  addonId: null,
24688
25056
  access: "create"
24689
25057
  },
25058
+ "pipelineRunner.runDetailSubtree": {
25059
+ capName: "pipeline-runner",
25060
+ capScope: "system",
25061
+ addonId: null,
25062
+ access: "create"
25063
+ },
24690
25064
  "plateGallery.correctPlateText": {
24691
25065
  capName: "plate-gallery",
24692
25066
  capScope: "system",
@@ -24933,6 +25307,36 @@ Object.freeze({
24933
25307
  addonId: null,
24934
25308
  access: "create"
24935
25309
  },
25310
+ "serverManagement.applyServerUpdate": {
25311
+ capName: "server-management",
25312
+ capScope: "system",
25313
+ addonId: null,
25314
+ access: "create"
25315
+ },
25316
+ "serverManagement.checkServerUpdate": {
25317
+ capName: "server-management",
25318
+ capScope: "system",
25319
+ addonId: null,
25320
+ access: "create"
25321
+ },
25322
+ "serverManagement.getServerPackageStatus": {
25323
+ capName: "server-management",
25324
+ capScope: "system",
25325
+ addonId: null,
25326
+ access: "view"
25327
+ },
25328
+ "serverManagement.restartServer": {
25329
+ capName: "server-management",
25330
+ capScope: "system",
25331
+ addonId: null,
25332
+ access: "create"
25333
+ },
25334
+ "serverManagement.rollbackServerUpdate": {
25335
+ capName: "server-management",
25336
+ capScope: "system",
25337
+ addonId: null,
25338
+ access: "create"
25339
+ },
24936
25340
  "settingsStore.count": {
24937
25341
  capName: "settings-store",
24938
25342
  capScope: "system",
@@ -25017,6 +25421,12 @@ Object.freeze({
25017
25421
  addonId: null,
25018
25422
  access: "view"
25019
25423
  },
25424
+ "snapshot.getSnapshotOverview": {
25425
+ capName: "snapshot",
25426
+ capScope: "device",
25427
+ addonId: null,
25428
+ access: "view"
25429
+ },
25020
25430
  "snapshot.invalidateCache": {
25021
25431
  capName: "snapshot",
25022
25432
  capScope: "device",
@@ -25695,6 +26105,12 @@ Object.freeze({
25695
26105
  addonId: null,
25696
26106
  access: "view"
25697
26107
  },
26108
+ "userPasskeys.beginDiscoverableAuthentication": {
26109
+ capName: "user-passkeys",
26110
+ capScope: "system",
26111
+ addonId: null,
26112
+ access: "view"
26113
+ },
25698
26114
  "userPasskeys.beginRegistration": {
25699
26115
  capName: "user-passkeys",
25700
26116
  capScope: "system",
@@ -25707,12 +26123,24 @@ Object.freeze({
25707
26123
  addonId: null,
25708
26124
  access: "view"
25709
26125
  },
26126
+ "userPasskeys.finishDiscoverableAuthentication": {
26127
+ capName: "user-passkeys",
26128
+ capScope: "system",
26129
+ addonId: null,
26130
+ access: "view"
26131
+ },
25710
26132
  "userPasskeys.finishRegistration": {
25711
26133
  capName: "user-passkeys",
25712
26134
  capScope: "system",
25713
26135
  addonId: null,
25714
26136
  access: "create"
25715
26137
  },
26138
+ "userPasskeys.getSecondFactorPreference": {
26139
+ capName: "user-passkeys",
26140
+ capScope: "system",
26141
+ addonId: null,
26142
+ access: "view"
26143
+ },
25716
26144
  "userPasskeys.listPasskeys": {
25717
26145
  capName: "user-passkeys",
25718
26146
  capScope: "system",
@@ -25725,6 +26153,12 @@ Object.freeze({
25725
26153
  addonId: null,
25726
26154
  access: "delete"
25727
26155
  },
26156
+ "userPasskeys.setSecondFactorPreference": {
26157
+ capName: "user-passkeys",
26158
+ capScope: "system",
26159
+ addonId: null,
26160
+ access: "create"
26161
+ },
25728
26162
  "vacuumControl.locate": {
25729
26163
  capName: "vacuum-control",
25730
26164
  capScope: "device",
@@ -25797,6 +26231,18 @@ Object.freeze({
25797
26231
  addonId: null,
25798
26232
  access: "view"
25799
26233
  },
26234
+ "viewerUi.getStaticDir": {
26235
+ capName: "viewer-ui",
26236
+ capScope: "system",
26237
+ addonId: null,
26238
+ access: "view"
26239
+ },
26240
+ "viewerUi.getVersion": {
26241
+ capName: "viewer-ui",
26242
+ capScope: "system",
26243
+ addonId: null,
26244
+ access: "view"
26245
+ },
25800
26246
  "waterHeater.setAway": {
25801
26247
  capName: "water-heater",
25802
26248
  capScope: "device",