@camstack/addon-provider-dreo 0.2.49 → 0.2.50

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 +234 -73
  2. package/dist/addon.mjs +234 -73
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8132,6 +8132,13 @@ var MediaRelocateModeSchema = _enum([
8132
8132
  ]);
8133
8133
  var RelocateMediaInputSchema = object({
8134
8134
  toLocationId: string(),
8135
+ /**
8136
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8137
+ * every row that is not already on `toLocationId` (the historical
8138
+ * behaviour). A named source is what a from→to migration needs: without it
8139
+ * "move events off disk 2" also emptied disk 1.
8140
+ */
8141
+ fromLocationId: string().optional(),
8135
8142
  throttleMbps: number().min(1).max(1e3).optional(),
8136
8143
  /** Omitted = `move`, the pre-existing behaviour. */
8137
8144
  mode: MediaRelocateModeSchema.optional()
@@ -8199,6 +8206,19 @@ var StorageMigrationDestinationsSchema = object({
8199
8206
  galleryMedia: string().min(1).optional()
8200
8207
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8201
8208
  /**
8209
+ * Optional named source per class. Omitted = the class's current default
8210
+ * (the historical behaviour). A named source that is NOT the default is a
8211
+ * drain of that disk: bytes move, the default stays, and the source is
8212
+ * disabled when the move finishes.
8213
+ */
8214
+ var StorageMigrationSourcesSchema = object({
8215
+ recordings: string().min(1).optional(),
8216
+ recordingsLow: string().min(1).optional(),
8217
+ eventMedia: string().min(1).optional(),
8218
+ backups: string().min(1).optional(),
8219
+ galleryMedia: string().min(1).optional()
8220
+ }).optional();
8221
+ /**
8202
8222
  * How a migration sequences the cutover against the byte move.
8203
8223
  *
8204
8224
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8220,6 +8240,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8220
8240
  /** Shared input for planning and starting an orchestrated storage migration. */
8221
8241
  var StorageMigrationInputSchema = object({
8222
8242
  destinations: StorageMigrationDestinationsSchema,
8243
+ /** Omitted = each class's current default. */
8244
+ sources: StorageMigrationSourcesSchema,
8223
8245
  throttleMbps: number().min(1).max(1e3).optional(),
8224
8246
  /** Omitted = `blocking`, which stays the default. */
8225
8247
  mode: StorageMigrationModeSchema.optional()
@@ -8299,6 +8321,13 @@ var StorageMigrationMoveSchema = object({
8299
8321
  storageClass: StorageMigrationClassSchema,
8300
8322
  fromLocationId: string(),
8301
8323
  toLocationId: string(),
8324
+ /**
8325
+ * True when `from` was NOT the class default at plan time. The move still
8326
+ * copies bytes, but the default is left alone and the source is disabled
8327
+ * once the copy verifies. Absent on jobs planned before this field existed
8328
+ * — those jobs always repointed, which is `false`.
8329
+ */
8330
+ freezeSource: boolean().optional(),
8302
8331
  moverJobId: string().nullable(),
8303
8332
  state: RelocateJobStateSchema.nullable(),
8304
8333
  error: string().nullable(),
@@ -8312,6 +8341,7 @@ var StorageMigrationJobSchema = object({
8312
8341
  * can tell a seconds-long cutover from a thirty-hour one. */
8313
8342
  mode: StorageMigrationModeSchema,
8314
8343
  destinations: StorageMigrationDestinationsSchema,
8344
+ sources: StorageMigrationSourcesSchema,
8315
8345
  throttleMbps: number(),
8316
8346
  moves: array(StorageMigrationMoveSchema),
8317
8347
  pauseLeaseId: string().nullable(),
@@ -8337,6 +8367,7 @@ var StorageMigrationFindingSchema = object({
8337
8367
  });
8338
8368
  var StorageMigrationPlanSchema = object({
8339
8369
  destinations: StorageMigrationDestinationsSchema,
8370
+ sources: StorageMigrationSourcesSchema,
8340
8371
  /** The mode this plan was built for. A plan is only valid for its mode: the
8341
8372
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8342
8373
  * it. */
@@ -8344,7 +8375,8 @@ var StorageMigrationPlanSchema = object({
8344
8375
  moves: array(object({
8345
8376
  storageClass: StorageMigrationClassSchema,
8346
8377
  fromLocationId: string(),
8347
- toLocationId: string()
8378
+ toLocationId: string(),
8379
+ freezeSource: boolean().optional()
8348
8380
  })),
8349
8381
  findings: array(StorageMigrationFindingSchema)
8350
8382
  });
@@ -8522,10 +8554,51 @@ var LedgerWalkReportSchema = object({
8522
8554
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8523
8555
  var RelocatableMediaCountInputSchema = object({
8524
8556
  toLocationId: string().min(1),
8557
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8558
+ fromLocationId: string().optional(),
8525
8559
  /** Omitted = `move`. */
8526
8560
  mode: MediaRelocateModeSchema.optional()
8527
8561
  });
8528
8562
  /**
8563
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8564
+ * ghost ledger entries on frozen footage locations.
8565
+ *
8566
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8567
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8568
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8569
+ * with no operator-visible status.
8570
+ */
8571
+ var StorageCleanupPhaseSchema = _enum([
8572
+ "orphans",
8573
+ "debug-media",
8574
+ "ghost-ledger",
8575
+ "done",
8576
+ "failed",
8577
+ "cancelled"
8578
+ ]);
8579
+ var StorageCleanupInputSchema = object({
8580
+ /** Also walk motion stills / track filmstrips. Off by default. */
8581
+ includeDebugMedia: boolean().optional() });
8582
+ var StorageCleanupJobSchema = object({
8583
+ jobId: string(),
8584
+ phase: StorageCleanupPhaseSchema,
8585
+ includeDebugMedia: boolean(),
8586
+ orphansReclaimed: number().int().nonnegative(),
8587
+ orphanBytesReclaimed: number().int().nonnegative(),
8588
+ debugMediaReclaimed: number().int().nonnegative(),
8589
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8590
+ ghostsForgotten: number().int().nonnegative(),
8591
+ ghostBytesForgotten: number().int().nonnegative(),
8592
+ /** Short operator-facing line: current collection, pass, or location. */
8593
+ detail: string().nullable(),
8594
+ cancelRequested: boolean(),
8595
+ startedAt: number(),
8596
+ updatedAt: number(),
8597
+ finishedAt: number().nullable(),
8598
+ error: string().nullable()
8599
+ });
8600
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8601
+ /**
8529
8602
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8530
8603
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8531
8604
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8553,11 +8626,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8553
8626
  * The default location for a type uses `id === <type>:default` by
8554
8627
  * convention (the bare type ref like `'backups'` resolves to it).
8555
8628
  *
8556
- * `isSystem: true` marks a location as orchestrator-seeded and
8557
- * undeletable. The bootstrap-installed defaults (one per type) carry
8558
- * this flag; operator-added locations don't. Editing the config of
8559
- * a system location is allowed (path migration, provider swap) but
8560
- * deleting it is rejected at the cap level.
8629
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8630
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8631
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8632
+ * / last-enabled, not on this bit.
8561
8633
  */
8562
8634
  var StorageLocationSchema = object({
8563
8635
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13100,6 +13172,12 @@ method(object({
13100
13172
  }), _void(), {
13101
13173
  kind: "mutation",
13102
13174
  auth: "admin"
13175
+ }), method(object({
13176
+ from: string(),
13177
+ to: string()
13178
+ }), object({ moved: number() }), {
13179
+ kind: "mutation",
13180
+ auth: "admin"
13103
13181
  }), method(object({
13104
13182
  deviceId: number(),
13105
13183
  disabled: boolean()
@@ -19108,46 +19186,6 @@ var RecentTracksPageSchema = object({
19108
19186
  /** Cursor for the next page, or null when this page is the last. */
19109
19187
  nextCursor: string().nullable()
19110
19188
  });
19111
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19112
- var LIST_GROUPS_MAX_LIMIT = 100;
19113
- var AnalyticsGroupRecordSchema = object({
19114
- id: string(),
19115
- deviceId: number().int(),
19116
- openedAt: number().int(),
19117
- closedAt: number().int(),
19118
- timestamp: number().int(),
19119
- memberCount: number().int(),
19120
- memberTrackIds: array(string()).readonly(),
19121
- className: string(),
19122
- classes: array(string()).readonly(),
19123
- /** Relative event-media path, or null when the group has no picture yet. */
19124
- mediaUrl: string().nullable(),
19125
- singleton: boolean()
19126
- });
19127
- var AnalyticsGroupMemberSchema = object({
19128
- trackId: string(),
19129
- deviceId: number().int(),
19130
- className: string(),
19131
- firstSeen: number().int(),
19132
- lastSeen: number().int(),
19133
- mediaUrl: string().nullable()
19134
- });
19135
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19136
- var ListGroupsQueryInput = object({
19137
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19138
- deviceIds: array(number()),
19139
- /** Window lower bound on `closedAt` (inclusive). */
19140
- since: number().optional(),
19141
- /** Window upper bound on `openedAt` (inclusive). */
19142
- until: number().optional(),
19143
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19144
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19145
- cursor: string().optional()
19146
- });
19147
- var ListGroupsPageSchema = object({
19148
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19149
- nextCursor: string().nullable()
19150
- });
19151
19189
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19152
19190
  var KEY_EVENTS_MAX_LIMIT = 200;
19153
19191
  var KeyEventQueryInput = object({
@@ -19251,9 +19289,7 @@ var TrackCascadeCountsSchema = object({
19251
19289
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19252
19290
  plates: number().int(),
19253
19291
  /** Per-track CLIP search vectors removed (best-effort). */
19254
- embeddings: number().int(),
19255
- /** Group membership + group rows removed with their last member (best-effort). */
19256
- groups: number().int()
19292
+ embeddings: number().int()
19257
19293
  });
19258
19294
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19259
19295
  var DiskReconcileCountsSchema = object({
@@ -19423,6 +19459,47 @@ var RebuildStatusSchema = object({
19423
19459
  /** Present when the pass ended by throwing. */
19424
19460
  error: string().nullable()
19425
19461
  });
19462
+ /**
19463
+ * Acknowledgement that a debug-media reclaim STARTED.
19464
+ *
19465
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19466
+ * it runs detached and this returns immediately. Awaiting it is how the
19467
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19468
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19469
+ */
19470
+ var MediaReclaimStartResultSchema = object({
19471
+ started: boolean(),
19472
+ /** True when a pass was already running; the new request is ignored. */
19473
+ alreadyRunning: boolean()
19474
+ });
19475
+ var MediaReclaimInputSchema = object({
19476
+ mode: _enum(["report", "reclaim"]).default("report"),
19477
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19478
+ deviceIds: array(number().int()).min(1).optional(),
19479
+ restart: boolean().optional(),
19480
+ pageSize: number().int().min(50).max(5e3).optional(),
19481
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19482
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19483
+ maxBytesPerRun: number().int().min(1).optional(),
19484
+ budgetMinutes: number().int().min(1).max(720).optional(),
19485
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19486
+ graceMinutes: number().int().min(1).max(10080).optional()
19487
+ });
19488
+ var MediaReclaimStatusSchema = object({
19489
+ running: boolean(),
19490
+ mode: _enum(["report", "reclaim"]).nullable(),
19491
+ totalExamined: number(),
19492
+ totalEligible: number(),
19493
+ totalReclaimed: number(),
19494
+ totalBytesReclaimed: number(),
19495
+ totalRefused: number(),
19496
+ /** Device+scope windows finished in this pass. */
19497
+ devicesDone: number(),
19498
+ complete: boolean().nullable(),
19499
+ startedAtMs: number().nullable(),
19500
+ finishedAtMs: number().nullable(),
19501
+ error: string().nullable()
19502
+ });
19426
19503
  var ReplayFrameInputSchema = object({
19427
19504
  timestamp: number(),
19428
19505
  frame: PipelineRunResultBridge
@@ -19461,10 +19538,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19461
19538
  * stationary registry). Default false: the timeline lists passages,
19462
19539
  * not parking records (operator decision, 2026-08-15). */
19463
19540
  includeStationary: boolean().optional()
19464
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19465
- deviceId: number(),
19466
- groupId: string().min(1)
19467
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19541
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19468
19542
  kind: "mutation",
19469
19543
  auth: "admin"
19470
19544
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -19564,6 +19638,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19564
19638
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19565
19639
  kind: "query",
19566
19640
  auth: "admin"
19641
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19642
+ kind: "mutation",
19643
+ auth: "admin"
19644
+ }), method(object({}), MediaReclaimStatusSchema, {
19645
+ kind: "query",
19646
+ auth: "admin"
19567
19647
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19568
19648
  kind: "query",
19569
19649
  auth: "admin"
@@ -21534,7 +21614,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21534
21614
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21535
21615
  kind: "mutation",
21536
21616
  auth: "admin"
21537
- });
21617
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21618
+ kind: "mutation",
21619
+ auth: "admin"
21620
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21621
+ kind: "mutation",
21622
+ auth: "admin"
21623
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21538
21624
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21539
21625
  providerId: string().min(1),
21540
21626
  displayName: string().min(1),
@@ -28635,6 +28721,33 @@ var RecordingRebalanceInputSchema = object({
28635
28721
  minMoveGb: number().min(0).optional()
28636
28722
  });
28637
28723
  /**
28724
+ * Operator-facing placement of one camera onto a recordings location.
28725
+ *
28726
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28727
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28728
+ * currently write — the plan, which may disagree with the pin when Auto.
28729
+ */
28730
+ var RecordingDevicePlacementSchema = object({
28731
+ deviceId: number().int(),
28732
+ profile: string(),
28733
+ locationId: string()
28734
+ });
28735
+ var RecordingDevicePinSchema = object({
28736
+ deviceId: number().int(),
28737
+ /** Recordings-class location this camera is pinned to. */
28738
+ locationId: string()
28739
+ });
28740
+ var RecordingPlacementViewSchema = object({
28741
+ assignments: array(RecordingDevicePlacementSchema),
28742
+ pins: array(RecordingDevicePinSchema),
28743
+ defaultLocations: record(string(), string())
28744
+ });
28745
+ var RecordingSetDevicePlacementInputSchema = object({
28746
+ deviceId: number().int(),
28747
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28748
+ locationId: string().nullable()
28749
+ });
28750
+ /**
28638
28751
  * Result of locating footage at a wall-clock instant for one device/profile.
28639
28752
  * `segment` carries the covering segment's window; `gap` reports the forward
28640
28753
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28860,6 +28973,12 @@ method(object({
28860
28973
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28861
28974
  kind: "mutation",
28862
28975
  auth: "admin"
28976
+ }), method(object({}), RecordingPlacementViewSchema, {
28977
+ kind: "query",
28978
+ auth: "admin"
28979
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28980
+ kind: "mutation",
28981
+ auth: "admin"
28863
28982
  });
28864
28983
  /**
28865
28984
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33929,6 +34048,12 @@ Object.freeze({
33929
34048
  addonId: null,
33930
34049
  access: "delete"
33931
34050
  },
34051
+ "deviceManager.renameLocation": {
34052
+ capName: "device-manager",
34053
+ capScope: "system",
34054
+ addonId: null,
34055
+ access: "create"
34056
+ },
33932
34057
  "deviceManager.runDeviceAction": {
33933
34058
  capName: "device-manager",
33934
34059
  capScope: "system",
@@ -35621,19 +35746,19 @@ Object.freeze({
35621
35746
  addonId: null,
35622
35747
  access: "view"
35623
35748
  },
35624
- "pipelineAnalytics.getGroup": {
35749
+ "pipelineAnalytics.getKeyEvents": {
35625
35750
  capName: "pipeline-analytics",
35626
35751
  capScope: "device",
35627
35752
  addonId: null,
35628
35753
  access: "view"
35629
35754
  },
35630
- "pipelineAnalytics.getKeyEvents": {
35755
+ "pipelineAnalytics.getKeyEventsBatch": {
35631
35756
  capName: "pipeline-analytics",
35632
35757
  capScope: "device",
35633
35758
  addonId: null,
35634
35759
  access: "view"
35635
35760
  },
35636
- "pipelineAnalytics.getKeyEventsBatch": {
35761
+ "pipelineAnalytics.getMediaReclaimStatus": {
35637
35762
  capName: "pipeline-analytics",
35638
35763
  capScope: "device",
35639
35764
  addonId: null,
@@ -35723,12 +35848,6 @@ Object.freeze({
35723
35848
  addonId: null,
35724
35849
  access: "view"
35725
35850
  },
35726
- "pipelineAnalytics.listGroups": {
35727
- capName: "pipeline-analytics",
35728
- capScope: "device",
35729
- addonId: null,
35730
- access: "view"
35731
- },
35732
35851
  "pipelineAnalytics.listOpsLog": {
35733
35852
  capName: "pipeline-analytics",
35734
35853
  capScope: "device",
@@ -35813,6 +35932,12 @@ Object.freeze({
35813
35932
  addonId: null,
35814
35933
  access: "create"
35815
35934
  },
35935
+ "pipelineAnalytics.reclaimDebugMedia": {
35936
+ capName: "pipeline-analytics",
35937
+ capScope: "device",
35938
+ addonId: null,
35939
+ access: "create"
35940
+ },
35816
35941
  "pipelineAnalytics.reconcileFromDisk": {
35817
35942
  capName: "pipeline-analytics",
35818
35943
  capScope: "device",
@@ -36737,6 +36862,12 @@ Object.freeze({
36737
36862
  addonId: null,
36738
36863
  access: "view"
36739
36864
  },
36865
+ "recording.getPlacement": {
36866
+ capName: "recording",
36867
+ capScope: "system",
36868
+ addonId: null,
36869
+ access: "view"
36870
+ },
36740
36871
  "recording.getPlaybackManifest": {
36741
36872
  capName: "recording",
36742
36873
  capScope: "system",
@@ -36863,6 +36994,12 @@ Object.freeze({
36863
36994
  addonId: null,
36864
36995
  access: "create"
36865
36996
  },
36997
+ "recording.setDevicePlacement": {
36998
+ capName: "recording",
36999
+ capScope: "system",
37000
+ addonId: null,
37001
+ access: "create"
37002
+ },
36866
37003
  "recording.startStorageMigrationMove": {
36867
37004
  capName: "recording",
36868
37005
  capScope: "system",
@@ -37307,12 +37444,36 @@ Object.freeze({
37307
37444
  addonId: null,
37308
37445
  access: "create"
37309
37446
  },
37447
+ "storageMigration.cleanupCancel": {
37448
+ capName: "storage-migration",
37449
+ capScope: "system",
37450
+ addonId: null,
37451
+ access: "create"
37452
+ },
37453
+ "storageMigration.cleanupStart": {
37454
+ capName: "storage-migration",
37455
+ capScope: "system",
37456
+ addonId: null,
37457
+ access: "create"
37458
+ },
37459
+ "storageMigration.cleanupStatus": {
37460
+ capName: "storage-migration",
37461
+ capScope: "system",
37462
+ addonId: null,
37463
+ access: "view"
37464
+ },
37310
37465
  "storageMigration.drain": {
37311
37466
  capName: "storage-migration",
37312
37467
  capScope: "system",
37313
37468
  addonId: null,
37314
37469
  access: "create"
37315
37470
  },
37471
+ "storageMigration.history": {
37472
+ capName: "storage-migration",
37473
+ capScope: "system",
37474
+ addonId: null,
37475
+ access: "view"
37476
+ },
37316
37477
  "storageMigration.movers": {
37317
37478
  capName: "storage-migration",
37318
37479
  capScope: "system",
@@ -39309,11 +39470,6 @@ Object.freeze({
39309
39470
  form: "single",
39310
39471
  optional: true
39311
39472
  }],
39312
- "pipelineAnalytics.getGroup": [{
39313
- name: "deviceId",
39314
- form: "single",
39315
- optional: false
39316
- }],
39317
39473
  "pipelineAnalytics.getKeyEvents": [{
39318
39474
  name: "deviceId",
39319
39475
  form: "single",
@@ -39379,11 +39535,6 @@ Object.freeze({
39379
39535
  form: "single",
39380
39536
  optional: false
39381
39537
  }],
39382
- "pipelineAnalytics.listGroups": [{
39383
- name: "deviceIds",
39384
- form: "array",
39385
- optional: false
39386
- }],
39387
39538
  "pipelineAnalytics.listOpsLog": [{
39388
39539
  name: "deviceId",
39389
39540
  form: "single",
@@ -39429,6 +39580,11 @@ Object.freeze({
39429
39580
  form: "single",
39430
39581
  optional: true
39431
39582
  }],
39583
+ "pipelineAnalytics.reclaimDebugMedia": [{
39584
+ name: "deviceIds",
39585
+ form: "array",
39586
+ optional: true
39587
+ }],
39432
39588
  "pipelineAnalytics.reconcileFromDisk": [{
39433
39589
  name: "deviceId",
39434
39590
  form: "single",
@@ -39794,6 +39950,11 @@ Object.freeze({
39794
39950
  form: "single",
39795
39951
  optional: false
39796
39952
  }],
39953
+ "recording.setDevicePlacement": [{
39954
+ name: "deviceId",
39955
+ form: "single",
39956
+ optional: false
39957
+ }],
39797
39958
  "recording.startStorageMigrationMove": [{
39798
39959
  name: "deviceId",
39799
39960
  form: "single",
package/dist/addon.mjs CHANGED
@@ -8133,6 +8133,13 @@ var MediaRelocateModeSchema = _enum([
8133
8133
  ]);
8134
8134
  var RelocateMediaInputSchema = object({
8135
8135
  toLocationId: string(),
8136
+ /**
8137
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8138
+ * every row that is not already on `toLocationId` (the historical
8139
+ * behaviour). A named source is what a from→to migration needs: without it
8140
+ * "move events off disk 2" also emptied disk 1.
8141
+ */
8142
+ fromLocationId: string().optional(),
8136
8143
  throttleMbps: number().min(1).max(1e3).optional(),
8137
8144
  /** Omitted = `move`, the pre-existing behaviour. */
8138
8145
  mode: MediaRelocateModeSchema.optional()
@@ -8200,6 +8207,19 @@ var StorageMigrationDestinationsSchema = object({
8200
8207
  galleryMedia: string().min(1).optional()
8201
8208
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8202
8209
  /**
8210
+ * Optional named source per class. Omitted = the class's current default
8211
+ * (the historical behaviour). A named source that is NOT the default is a
8212
+ * drain of that disk: bytes move, the default stays, and the source is
8213
+ * disabled when the move finishes.
8214
+ */
8215
+ var StorageMigrationSourcesSchema = object({
8216
+ recordings: string().min(1).optional(),
8217
+ recordingsLow: string().min(1).optional(),
8218
+ eventMedia: string().min(1).optional(),
8219
+ backups: string().min(1).optional(),
8220
+ galleryMedia: string().min(1).optional()
8221
+ }).optional();
8222
+ /**
8203
8223
  * How a migration sequences the cutover against the byte move.
8204
8224
  *
8205
8225
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8221,6 +8241,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8221
8241
  /** Shared input for planning and starting an orchestrated storage migration. */
8222
8242
  var StorageMigrationInputSchema = object({
8223
8243
  destinations: StorageMigrationDestinationsSchema,
8244
+ /** Omitted = each class's current default. */
8245
+ sources: StorageMigrationSourcesSchema,
8224
8246
  throttleMbps: number().min(1).max(1e3).optional(),
8225
8247
  /** Omitted = `blocking`, which stays the default. */
8226
8248
  mode: StorageMigrationModeSchema.optional()
@@ -8300,6 +8322,13 @@ var StorageMigrationMoveSchema = object({
8300
8322
  storageClass: StorageMigrationClassSchema,
8301
8323
  fromLocationId: string(),
8302
8324
  toLocationId: string(),
8325
+ /**
8326
+ * True when `from` was NOT the class default at plan time. The move still
8327
+ * copies bytes, but the default is left alone and the source is disabled
8328
+ * once the copy verifies. Absent on jobs planned before this field existed
8329
+ * — those jobs always repointed, which is `false`.
8330
+ */
8331
+ freezeSource: boolean().optional(),
8303
8332
  moverJobId: string().nullable(),
8304
8333
  state: RelocateJobStateSchema.nullable(),
8305
8334
  error: string().nullable(),
@@ -8313,6 +8342,7 @@ var StorageMigrationJobSchema = object({
8313
8342
  * can tell a seconds-long cutover from a thirty-hour one. */
8314
8343
  mode: StorageMigrationModeSchema,
8315
8344
  destinations: StorageMigrationDestinationsSchema,
8345
+ sources: StorageMigrationSourcesSchema,
8316
8346
  throttleMbps: number(),
8317
8347
  moves: array(StorageMigrationMoveSchema),
8318
8348
  pauseLeaseId: string().nullable(),
@@ -8338,6 +8368,7 @@ var StorageMigrationFindingSchema = object({
8338
8368
  });
8339
8369
  var StorageMigrationPlanSchema = object({
8340
8370
  destinations: StorageMigrationDestinationsSchema,
8371
+ sources: StorageMigrationSourcesSchema,
8341
8372
  /** The mode this plan was built for. A plan is only valid for its mode: the
8342
8373
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8343
8374
  * it. */
@@ -8345,7 +8376,8 @@ var StorageMigrationPlanSchema = object({
8345
8376
  moves: array(object({
8346
8377
  storageClass: StorageMigrationClassSchema,
8347
8378
  fromLocationId: string(),
8348
- toLocationId: string()
8379
+ toLocationId: string(),
8380
+ freezeSource: boolean().optional()
8349
8381
  })),
8350
8382
  findings: array(StorageMigrationFindingSchema)
8351
8383
  });
@@ -8523,10 +8555,51 @@ var LedgerWalkReportSchema = object({
8523
8555
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8524
8556
  var RelocatableMediaCountInputSchema = object({
8525
8557
  toLocationId: string().min(1),
8558
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8559
+ fromLocationId: string().optional(),
8526
8560
  /** Omitted = `move`. */
8527
8561
  mode: MediaRelocateModeSchema.optional()
8528
8562
  });
8529
8563
  /**
8564
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8565
+ * ghost ledger entries on frozen footage locations.
8566
+ *
8567
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8568
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8569
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8570
+ * with no operator-visible status.
8571
+ */
8572
+ var StorageCleanupPhaseSchema = _enum([
8573
+ "orphans",
8574
+ "debug-media",
8575
+ "ghost-ledger",
8576
+ "done",
8577
+ "failed",
8578
+ "cancelled"
8579
+ ]);
8580
+ var StorageCleanupInputSchema = object({
8581
+ /** Also walk motion stills / track filmstrips. Off by default. */
8582
+ includeDebugMedia: boolean().optional() });
8583
+ var StorageCleanupJobSchema = object({
8584
+ jobId: string(),
8585
+ phase: StorageCleanupPhaseSchema,
8586
+ includeDebugMedia: boolean(),
8587
+ orphansReclaimed: number().int().nonnegative(),
8588
+ orphanBytesReclaimed: number().int().nonnegative(),
8589
+ debugMediaReclaimed: number().int().nonnegative(),
8590
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8591
+ ghostsForgotten: number().int().nonnegative(),
8592
+ ghostBytesForgotten: number().int().nonnegative(),
8593
+ /** Short operator-facing line: current collection, pass, or location. */
8594
+ detail: string().nullable(),
8595
+ cancelRequested: boolean(),
8596
+ startedAt: number(),
8597
+ updatedAt: number(),
8598
+ finishedAt: number().nullable(),
8599
+ error: string().nullable()
8600
+ });
8601
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8602
+ /**
8530
8603
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8531
8604
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8532
8605
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8554,11 +8627,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8554
8627
  * The default location for a type uses `id === <type>:default` by
8555
8628
  * convention (the bare type ref like `'backups'` resolves to it).
8556
8629
  *
8557
- * `isSystem: true` marks a location as orchestrator-seeded and
8558
- * undeletable. The bootstrap-installed defaults (one per type) carry
8559
- * this flag; operator-added locations don't. Editing the config of
8560
- * a system location is allowed (path migration, provider swap) but
8561
- * deleting it is rejected at the cap level.
8630
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8631
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8632
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8633
+ * / last-enabled, not on this bit.
8562
8634
  */
8563
8635
  var StorageLocationSchema = object({
8564
8636
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13101,6 +13173,12 @@ method(object({
13101
13173
  }), _void(), {
13102
13174
  kind: "mutation",
13103
13175
  auth: "admin"
13176
+ }), method(object({
13177
+ from: string(),
13178
+ to: string()
13179
+ }), object({ moved: number() }), {
13180
+ kind: "mutation",
13181
+ auth: "admin"
13104
13182
  }), method(object({
13105
13183
  deviceId: number(),
13106
13184
  disabled: boolean()
@@ -19109,46 +19187,6 @@ var RecentTracksPageSchema = object({
19109
19187
  /** Cursor for the next page, or null when this page is the last. */
19110
19188
  nextCursor: string().nullable()
19111
19189
  });
19112
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19113
- var LIST_GROUPS_MAX_LIMIT = 100;
19114
- var AnalyticsGroupRecordSchema = object({
19115
- id: string(),
19116
- deviceId: number().int(),
19117
- openedAt: number().int(),
19118
- closedAt: number().int(),
19119
- timestamp: number().int(),
19120
- memberCount: number().int(),
19121
- memberTrackIds: array(string()).readonly(),
19122
- className: string(),
19123
- classes: array(string()).readonly(),
19124
- /** Relative event-media path, or null when the group has no picture yet. */
19125
- mediaUrl: string().nullable(),
19126
- singleton: boolean()
19127
- });
19128
- var AnalyticsGroupMemberSchema = object({
19129
- trackId: string(),
19130
- deviceId: number().int(),
19131
- className: string(),
19132
- firstSeen: number().int(),
19133
- lastSeen: number().int(),
19134
- mediaUrl: string().nullable()
19135
- });
19136
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19137
- var ListGroupsQueryInput = object({
19138
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19139
- deviceIds: array(number()),
19140
- /** Window lower bound on `closedAt` (inclusive). */
19141
- since: number().optional(),
19142
- /** Window upper bound on `openedAt` (inclusive). */
19143
- until: number().optional(),
19144
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19145
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19146
- cursor: string().optional()
19147
- });
19148
- var ListGroupsPageSchema = object({
19149
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19150
- nextCursor: string().nullable()
19151
- });
19152
19190
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19153
19191
  var KEY_EVENTS_MAX_LIMIT = 200;
19154
19192
  var KeyEventQueryInput = object({
@@ -19252,9 +19290,7 @@ var TrackCascadeCountsSchema = object({
19252
19290
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19253
19291
  plates: number().int(),
19254
19292
  /** Per-track CLIP search vectors removed (best-effort). */
19255
- embeddings: number().int(),
19256
- /** Group membership + group rows removed with their last member (best-effort). */
19257
- groups: number().int()
19293
+ embeddings: number().int()
19258
19294
  });
19259
19295
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19260
19296
  var DiskReconcileCountsSchema = object({
@@ -19424,6 +19460,47 @@ var RebuildStatusSchema = object({
19424
19460
  /** Present when the pass ended by throwing. */
19425
19461
  error: string().nullable()
19426
19462
  });
19463
+ /**
19464
+ * Acknowledgement that a debug-media reclaim STARTED.
19465
+ *
19466
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19467
+ * it runs detached and this returns immediately. Awaiting it is how the
19468
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19469
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19470
+ */
19471
+ var MediaReclaimStartResultSchema = object({
19472
+ started: boolean(),
19473
+ /** True when a pass was already running; the new request is ignored. */
19474
+ alreadyRunning: boolean()
19475
+ });
19476
+ var MediaReclaimInputSchema = object({
19477
+ mode: _enum(["report", "reclaim"]).default("report"),
19478
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19479
+ deviceIds: array(number().int()).min(1).optional(),
19480
+ restart: boolean().optional(),
19481
+ pageSize: number().int().min(50).max(5e3).optional(),
19482
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19483
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19484
+ maxBytesPerRun: number().int().min(1).optional(),
19485
+ budgetMinutes: number().int().min(1).max(720).optional(),
19486
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19487
+ graceMinutes: number().int().min(1).max(10080).optional()
19488
+ });
19489
+ var MediaReclaimStatusSchema = object({
19490
+ running: boolean(),
19491
+ mode: _enum(["report", "reclaim"]).nullable(),
19492
+ totalExamined: number(),
19493
+ totalEligible: number(),
19494
+ totalReclaimed: number(),
19495
+ totalBytesReclaimed: number(),
19496
+ totalRefused: number(),
19497
+ /** Device+scope windows finished in this pass. */
19498
+ devicesDone: number(),
19499
+ complete: boolean().nullable(),
19500
+ startedAtMs: number().nullable(),
19501
+ finishedAtMs: number().nullable(),
19502
+ error: string().nullable()
19503
+ });
19427
19504
  var ReplayFrameInputSchema = object({
19428
19505
  timestamp: number(),
19429
19506
  frame: PipelineRunResultBridge
@@ -19462,10 +19539,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19462
19539
  * stationary registry). Default false: the timeline lists passages,
19463
19540
  * not parking records (operator decision, 2026-08-15). */
19464
19541
  includeStationary: boolean().optional()
19465
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19466
- deviceId: number(),
19467
- groupId: string().min(1)
19468
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19542
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19469
19543
  kind: "mutation",
19470
19544
  auth: "admin"
19471
19545
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -19565,6 +19639,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19565
19639
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19566
19640
  kind: "query",
19567
19641
  auth: "admin"
19642
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19643
+ kind: "mutation",
19644
+ auth: "admin"
19645
+ }), method(object({}), MediaReclaimStatusSchema, {
19646
+ kind: "query",
19647
+ auth: "admin"
19568
19648
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19569
19649
  kind: "query",
19570
19650
  auth: "admin"
@@ -21535,7 +21615,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21535
21615
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21536
21616
  kind: "mutation",
21537
21617
  auth: "admin"
21538
- });
21618
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21619
+ kind: "mutation",
21620
+ auth: "admin"
21621
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21622
+ kind: "mutation",
21623
+ auth: "admin"
21624
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21539
21625
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21540
21626
  providerId: string().min(1),
21541
21627
  displayName: string().min(1),
@@ -28636,6 +28722,33 @@ var RecordingRebalanceInputSchema = object({
28636
28722
  minMoveGb: number().min(0).optional()
28637
28723
  });
28638
28724
  /**
28725
+ * Operator-facing placement of one camera onto a recordings location.
28726
+ *
28727
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
28728
+ * Auto (the planner may move this camera). `locationId` is where high/mid
28729
+ * currently write — the plan, which may disagree with the pin when Auto.
28730
+ */
28731
+ var RecordingDevicePlacementSchema = object({
28732
+ deviceId: number().int(),
28733
+ profile: string(),
28734
+ locationId: string()
28735
+ });
28736
+ var RecordingDevicePinSchema = object({
28737
+ deviceId: number().int(),
28738
+ /** Recordings-class location this camera is pinned to. */
28739
+ locationId: string()
28740
+ });
28741
+ var RecordingPlacementViewSchema = object({
28742
+ assignments: array(RecordingDevicePlacementSchema),
28743
+ pins: array(RecordingDevicePinSchema),
28744
+ defaultLocations: record(string(), string())
28745
+ });
28746
+ var RecordingSetDevicePlacementInputSchema = object({
28747
+ deviceId: number().int(),
28748
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
28749
+ locationId: string().nullable()
28750
+ });
28751
+ /**
28639
28752
  * Result of locating footage at a wall-clock instant for one device/profile.
28640
28753
  * `segment` carries the covering segment's window; `gap` reports the forward
28641
28754
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -28861,6 +28974,12 @@ method(object({
28861
28974
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
28862
28975
  kind: "mutation",
28863
28976
  auth: "admin"
28977
+ }), method(object({}), RecordingPlacementViewSchema, {
28978
+ kind: "query",
28979
+ auth: "admin"
28980
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
28981
+ kind: "mutation",
28982
+ auth: "admin"
28864
28983
  });
28865
28984
  /**
28866
28985
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -33930,6 +34049,12 @@ Object.freeze({
33930
34049
  addonId: null,
33931
34050
  access: "delete"
33932
34051
  },
34052
+ "deviceManager.renameLocation": {
34053
+ capName: "device-manager",
34054
+ capScope: "system",
34055
+ addonId: null,
34056
+ access: "create"
34057
+ },
33933
34058
  "deviceManager.runDeviceAction": {
33934
34059
  capName: "device-manager",
33935
34060
  capScope: "system",
@@ -35622,19 +35747,19 @@ Object.freeze({
35622
35747
  addonId: null,
35623
35748
  access: "view"
35624
35749
  },
35625
- "pipelineAnalytics.getGroup": {
35750
+ "pipelineAnalytics.getKeyEvents": {
35626
35751
  capName: "pipeline-analytics",
35627
35752
  capScope: "device",
35628
35753
  addonId: null,
35629
35754
  access: "view"
35630
35755
  },
35631
- "pipelineAnalytics.getKeyEvents": {
35756
+ "pipelineAnalytics.getKeyEventsBatch": {
35632
35757
  capName: "pipeline-analytics",
35633
35758
  capScope: "device",
35634
35759
  addonId: null,
35635
35760
  access: "view"
35636
35761
  },
35637
- "pipelineAnalytics.getKeyEventsBatch": {
35762
+ "pipelineAnalytics.getMediaReclaimStatus": {
35638
35763
  capName: "pipeline-analytics",
35639
35764
  capScope: "device",
35640
35765
  addonId: null,
@@ -35724,12 +35849,6 @@ Object.freeze({
35724
35849
  addonId: null,
35725
35850
  access: "view"
35726
35851
  },
35727
- "pipelineAnalytics.listGroups": {
35728
- capName: "pipeline-analytics",
35729
- capScope: "device",
35730
- addonId: null,
35731
- access: "view"
35732
- },
35733
35852
  "pipelineAnalytics.listOpsLog": {
35734
35853
  capName: "pipeline-analytics",
35735
35854
  capScope: "device",
@@ -35814,6 +35933,12 @@ Object.freeze({
35814
35933
  addonId: null,
35815
35934
  access: "create"
35816
35935
  },
35936
+ "pipelineAnalytics.reclaimDebugMedia": {
35937
+ capName: "pipeline-analytics",
35938
+ capScope: "device",
35939
+ addonId: null,
35940
+ access: "create"
35941
+ },
35817
35942
  "pipelineAnalytics.reconcileFromDisk": {
35818
35943
  capName: "pipeline-analytics",
35819
35944
  capScope: "device",
@@ -36738,6 +36863,12 @@ Object.freeze({
36738
36863
  addonId: null,
36739
36864
  access: "view"
36740
36865
  },
36866
+ "recording.getPlacement": {
36867
+ capName: "recording",
36868
+ capScope: "system",
36869
+ addonId: null,
36870
+ access: "view"
36871
+ },
36741
36872
  "recording.getPlaybackManifest": {
36742
36873
  capName: "recording",
36743
36874
  capScope: "system",
@@ -36864,6 +36995,12 @@ Object.freeze({
36864
36995
  addonId: null,
36865
36996
  access: "create"
36866
36997
  },
36998
+ "recording.setDevicePlacement": {
36999
+ capName: "recording",
37000
+ capScope: "system",
37001
+ addonId: null,
37002
+ access: "create"
37003
+ },
36867
37004
  "recording.startStorageMigrationMove": {
36868
37005
  capName: "recording",
36869
37006
  capScope: "system",
@@ -37308,12 +37445,36 @@ Object.freeze({
37308
37445
  addonId: null,
37309
37446
  access: "create"
37310
37447
  },
37448
+ "storageMigration.cleanupCancel": {
37449
+ capName: "storage-migration",
37450
+ capScope: "system",
37451
+ addonId: null,
37452
+ access: "create"
37453
+ },
37454
+ "storageMigration.cleanupStart": {
37455
+ capName: "storage-migration",
37456
+ capScope: "system",
37457
+ addonId: null,
37458
+ access: "create"
37459
+ },
37460
+ "storageMigration.cleanupStatus": {
37461
+ capName: "storage-migration",
37462
+ capScope: "system",
37463
+ addonId: null,
37464
+ access: "view"
37465
+ },
37311
37466
  "storageMigration.drain": {
37312
37467
  capName: "storage-migration",
37313
37468
  capScope: "system",
37314
37469
  addonId: null,
37315
37470
  access: "create"
37316
37471
  },
37472
+ "storageMigration.history": {
37473
+ capName: "storage-migration",
37474
+ capScope: "system",
37475
+ addonId: null,
37476
+ access: "view"
37477
+ },
37317
37478
  "storageMigration.movers": {
37318
37479
  capName: "storage-migration",
37319
37480
  capScope: "system",
@@ -39310,11 +39471,6 @@ Object.freeze({
39310
39471
  form: "single",
39311
39472
  optional: true
39312
39473
  }],
39313
- "pipelineAnalytics.getGroup": [{
39314
- name: "deviceId",
39315
- form: "single",
39316
- optional: false
39317
- }],
39318
39474
  "pipelineAnalytics.getKeyEvents": [{
39319
39475
  name: "deviceId",
39320
39476
  form: "single",
@@ -39380,11 +39536,6 @@ Object.freeze({
39380
39536
  form: "single",
39381
39537
  optional: false
39382
39538
  }],
39383
- "pipelineAnalytics.listGroups": [{
39384
- name: "deviceIds",
39385
- form: "array",
39386
- optional: false
39387
- }],
39388
39539
  "pipelineAnalytics.listOpsLog": [{
39389
39540
  name: "deviceId",
39390
39541
  form: "single",
@@ -39430,6 +39581,11 @@ Object.freeze({
39430
39581
  form: "single",
39431
39582
  optional: true
39432
39583
  }],
39584
+ "pipelineAnalytics.reclaimDebugMedia": [{
39585
+ name: "deviceIds",
39586
+ form: "array",
39587
+ optional: true
39588
+ }],
39433
39589
  "pipelineAnalytics.reconcileFromDisk": [{
39434
39590
  name: "deviceId",
39435
39591
  form: "single",
@@ -39795,6 +39951,11 @@ Object.freeze({
39795
39951
  form: "single",
39796
39952
  optional: false
39797
39953
  }],
39954
+ "recording.setDevicePlacement": [{
39955
+ name: "deviceId",
39956
+ form: "single",
39957
+ optional: false
39958
+ }],
39798
39959
  "recording.startStorageMigrationMove": [{
39799
39960
  name: "deviceId",
39800
39961
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",