@camstack/addon-provider-petkit 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
@@ -9198,6 +9198,13 @@ var MediaRelocateModeSchema = _enum([
9198
9198
  ]);
9199
9199
  var RelocateMediaInputSchema = object({
9200
9200
  toLocationId: string(),
9201
+ /**
9202
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
9203
+ * every row that is not already on `toLocationId` (the historical
9204
+ * behaviour). A named source is what a from→to migration needs: without it
9205
+ * "move events off disk 2" also emptied disk 1.
9206
+ */
9207
+ fromLocationId: string().optional(),
9201
9208
  throttleMbps: number().min(1).max(1e3).optional(),
9202
9209
  /** Omitted = `move`, the pre-existing behaviour. */
9203
9210
  mode: MediaRelocateModeSchema.optional()
@@ -9265,6 +9272,19 @@ var StorageMigrationDestinationsSchema = object({
9265
9272
  galleryMedia: string().min(1).optional()
9266
9273
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
9267
9274
  /**
9275
+ * Optional named source per class. Omitted = the class's current default
9276
+ * (the historical behaviour). A named source that is NOT the default is a
9277
+ * drain of that disk: bytes move, the default stays, and the source is
9278
+ * disabled when the move finishes.
9279
+ */
9280
+ var StorageMigrationSourcesSchema = object({
9281
+ recordings: string().min(1).optional(),
9282
+ recordingsLow: string().min(1).optional(),
9283
+ eventMedia: string().min(1).optional(),
9284
+ backups: string().min(1).optional(),
9285
+ galleryMedia: string().min(1).optional()
9286
+ }).optional();
9287
+ /**
9268
9288
  * How a migration sequences the cutover against the byte move.
9269
9289
  *
9270
9290
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -9286,6 +9306,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
9286
9306
  /** Shared input for planning and starting an orchestrated storage migration. */
9287
9307
  var StorageMigrationInputSchema = object({
9288
9308
  destinations: StorageMigrationDestinationsSchema,
9309
+ /** Omitted = each class's current default. */
9310
+ sources: StorageMigrationSourcesSchema,
9289
9311
  throttleMbps: number().min(1).max(1e3).optional(),
9290
9312
  /** Omitted = `blocking`, which stays the default. */
9291
9313
  mode: StorageMigrationModeSchema.optional()
@@ -9365,6 +9387,13 @@ var StorageMigrationMoveSchema = object({
9365
9387
  storageClass: StorageMigrationClassSchema,
9366
9388
  fromLocationId: string(),
9367
9389
  toLocationId: string(),
9390
+ /**
9391
+ * True when `from` was NOT the class default at plan time. The move still
9392
+ * copies bytes, but the default is left alone and the source is disabled
9393
+ * once the copy verifies. Absent on jobs planned before this field existed
9394
+ * — those jobs always repointed, which is `false`.
9395
+ */
9396
+ freezeSource: boolean().optional(),
9368
9397
  moverJobId: string().nullable(),
9369
9398
  state: RelocateJobStateSchema.nullable(),
9370
9399
  error: string().nullable(),
@@ -9378,6 +9407,7 @@ var StorageMigrationJobSchema = object({
9378
9407
  * can tell a seconds-long cutover from a thirty-hour one. */
9379
9408
  mode: StorageMigrationModeSchema,
9380
9409
  destinations: StorageMigrationDestinationsSchema,
9410
+ sources: StorageMigrationSourcesSchema,
9381
9411
  throttleMbps: number(),
9382
9412
  moves: array(StorageMigrationMoveSchema),
9383
9413
  pauseLeaseId: string().nullable(),
@@ -9403,6 +9433,7 @@ var StorageMigrationFindingSchema = object({
9403
9433
  });
9404
9434
  var StorageMigrationPlanSchema = object({
9405
9435
  destinations: StorageMigrationDestinationsSchema,
9436
+ sources: StorageMigrationSourcesSchema,
9406
9437
  /** The mode this plan was built for. A plan is only valid for its mode: the
9407
9438
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
9408
9439
  * it. */
@@ -9410,7 +9441,8 @@ var StorageMigrationPlanSchema = object({
9410
9441
  moves: array(object({
9411
9442
  storageClass: StorageMigrationClassSchema,
9412
9443
  fromLocationId: string(),
9413
- toLocationId: string()
9444
+ toLocationId: string(),
9445
+ freezeSource: boolean().optional()
9414
9446
  })),
9415
9447
  findings: array(StorageMigrationFindingSchema)
9416
9448
  });
@@ -9588,10 +9620,51 @@ var LedgerWalkReportSchema = object({
9588
9620
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
9589
9621
  var RelocatableMediaCountInputSchema = object({
9590
9622
  toLocationId: string().min(1),
9623
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
9624
+ fromLocationId: string().optional(),
9591
9625
  /** Omitted = `move`. */
9592
9626
  mode: MediaRelocateModeSchema.optional()
9593
9627
  });
9594
9628
  /**
9629
+ * Operator cleanup of leftover analytics rows, optional debug media, and
9630
+ * ghost ledger entries on frozen footage locations.
9631
+ *
9632
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
9633
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
9634
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
9635
+ * with no operator-visible status.
9636
+ */
9637
+ var StorageCleanupPhaseSchema = _enum([
9638
+ "orphans",
9639
+ "debug-media",
9640
+ "ghost-ledger",
9641
+ "done",
9642
+ "failed",
9643
+ "cancelled"
9644
+ ]);
9645
+ var StorageCleanupInputSchema = object({
9646
+ /** Also walk motion stills / track filmstrips. Off by default. */
9647
+ includeDebugMedia: boolean().optional() });
9648
+ var StorageCleanupJobSchema = object({
9649
+ jobId: string(),
9650
+ phase: StorageCleanupPhaseSchema,
9651
+ includeDebugMedia: boolean(),
9652
+ orphansReclaimed: number().int().nonnegative(),
9653
+ orphanBytesReclaimed: number().int().nonnegative(),
9654
+ debugMediaReclaimed: number().int().nonnegative(),
9655
+ debugMediaBytesReclaimed: number().int().nonnegative(),
9656
+ ghostsForgotten: number().int().nonnegative(),
9657
+ ghostBytesForgotten: number().int().nonnegative(),
9658
+ /** Short operator-facing line: current collection, pass, or location. */
9659
+ detail: string().nullable(),
9660
+ cancelRequested: boolean(),
9661
+ startedAt: number(),
9662
+ updatedAt: number(),
9663
+ finishedAt: number().nullable(),
9664
+ error: string().nullable()
9665
+ });
9666
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
9667
+ /**
9595
9668
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
9596
9669
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
9597
9670
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -9619,11 +9692,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
9619
9692
  * The default location for a type uses `id === <type>:default` by
9620
9693
  * convention (the bare type ref like `'backups'` resolves to it).
9621
9694
  *
9622
- * `isSystem: true` marks a location as orchestrator-seeded and
9623
- * undeletable. The bootstrap-installed defaults (one per type) carry
9624
- * this flag; operator-added locations don't. Editing the config of
9625
- * a system location is allowed (path migration, provider swap) but
9626
- * deleting it is rejected at the cap level.
9695
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
9696
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
9697
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
9698
+ * / last-enabled, not on this bit.
9627
9699
  */
9628
9700
  var StorageLocationSchema = object({
9629
9701
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -14166,6 +14238,12 @@ method(object({
14166
14238
  }), _void(), {
14167
14239
  kind: "mutation",
14168
14240
  auth: "admin"
14241
+ }), method(object({
14242
+ from: string(),
14243
+ to: string()
14244
+ }), object({ moved: number() }), {
14245
+ kind: "mutation",
14246
+ auth: "admin"
14169
14247
  }), method(object({
14170
14248
  deviceId: number(),
14171
14249
  disabled: boolean()
@@ -20174,46 +20252,6 @@ var RecentTracksPageSchema = object({
20174
20252
  /** Cursor for the next page, or null when this page is the last. */
20175
20253
  nextCursor: string().nullable()
20176
20254
  });
20177
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
20178
- var LIST_GROUPS_MAX_LIMIT = 100;
20179
- var AnalyticsGroupRecordSchema = object({
20180
- id: string(),
20181
- deviceId: number().int(),
20182
- openedAt: number().int(),
20183
- closedAt: number().int(),
20184
- timestamp: number().int(),
20185
- memberCount: number().int(),
20186
- memberTrackIds: array(string()).readonly(),
20187
- className: string(),
20188
- classes: array(string()).readonly(),
20189
- /** Relative event-media path, or null when the group has no picture yet. */
20190
- mediaUrl: string().nullable(),
20191
- singleton: boolean()
20192
- });
20193
- var AnalyticsGroupMemberSchema = object({
20194
- trackId: string(),
20195
- deviceId: number().int(),
20196
- className: string(),
20197
- firstSeen: number().int(),
20198
- lastSeen: number().int(),
20199
- mediaUrl: string().nullable()
20200
- });
20201
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
20202
- var ListGroupsQueryInput = object({
20203
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
20204
- deviceIds: array(number()),
20205
- /** Window lower bound on `closedAt` (inclusive). */
20206
- since: number().optional(),
20207
- /** Window upper bound on `openedAt` (inclusive). */
20208
- until: number().optional(),
20209
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
20210
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
20211
- cursor: string().optional()
20212
- });
20213
- var ListGroupsPageSchema = object({
20214
- groups: array(AnalyticsGroupRecordSchema).readonly(),
20215
- nextCursor: string().nullable()
20216
- });
20217
20255
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
20218
20256
  var KEY_EVENTS_MAX_LIMIT = 200;
20219
20257
  var KeyEventQueryInput = object({
@@ -20317,9 +20355,7 @@ var TrackCascadeCountsSchema = object({
20317
20355
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
20318
20356
  plates: number().int(),
20319
20357
  /** Per-track CLIP search vectors removed (best-effort). */
20320
- embeddings: number().int(),
20321
- /** Group membership + group rows removed with their last member (best-effort). */
20322
- groups: number().int()
20358
+ embeddings: number().int()
20323
20359
  });
20324
20360
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
20325
20361
  var DiskReconcileCountsSchema = object({
@@ -20489,6 +20525,47 @@ var RebuildStatusSchema = object({
20489
20525
  /** Present when the pass ended by throwing. */
20490
20526
  error: string().nullable()
20491
20527
  });
20528
+ /**
20529
+ * Acknowledgement that a debug-media reclaim STARTED.
20530
+ *
20531
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
20532
+ * it runs detached and this returns immediately. Awaiting it is how the
20533
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
20534
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
20535
+ */
20536
+ var MediaReclaimStartResultSchema = object({
20537
+ started: boolean(),
20538
+ /** True when a pass was already running; the new request is ignored. */
20539
+ alreadyRunning: boolean()
20540
+ });
20541
+ var MediaReclaimInputSchema = object({
20542
+ mode: _enum(["report", "reclaim"]).default("report"),
20543
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
20544
+ deviceIds: array(number().int()).min(1).optional(),
20545
+ restart: boolean().optional(),
20546
+ pageSize: number().int().min(50).max(5e3).optional(),
20547
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
20548
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
20549
+ maxBytesPerRun: number().int().min(1).optional(),
20550
+ budgetMinutes: number().int().min(1).max(720).optional(),
20551
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
20552
+ graceMinutes: number().int().min(1).max(10080).optional()
20553
+ });
20554
+ var MediaReclaimStatusSchema = object({
20555
+ running: boolean(),
20556
+ mode: _enum(["report", "reclaim"]).nullable(),
20557
+ totalExamined: number(),
20558
+ totalEligible: number(),
20559
+ totalReclaimed: number(),
20560
+ totalBytesReclaimed: number(),
20561
+ totalRefused: number(),
20562
+ /** Device+scope windows finished in this pass. */
20563
+ devicesDone: number(),
20564
+ complete: boolean().nullable(),
20565
+ startedAtMs: number().nullable(),
20566
+ finishedAtMs: number().nullable(),
20567
+ error: string().nullable()
20568
+ });
20492
20569
  var ReplayFrameInputSchema = object({
20493
20570
  timestamp: number(),
20494
20571
  frame: PipelineRunResultBridge
@@ -20527,10 +20604,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20527
20604
  * stationary registry). Default false: the timeline lists passages,
20528
20605
  * not parking records (operator decision, 2026-08-15). */
20529
20606
  includeStationary: boolean().optional()
20530
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
20531
- deviceId: number(),
20532
- groupId: string().min(1)
20533
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20607
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20534
20608
  kind: "mutation",
20535
20609
  auth: "admin"
20536
20610
  }), 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({
@@ -20630,6 +20704,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20630
20704
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20631
20705
  kind: "query",
20632
20706
  auth: "admin"
20707
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
20708
+ kind: "mutation",
20709
+ auth: "admin"
20710
+ }), method(object({}), MediaReclaimStatusSchema, {
20711
+ kind: "query",
20712
+ auth: "admin"
20633
20713
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
20634
20714
  kind: "query",
20635
20715
  auth: "admin"
@@ -22600,7 +22680,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
22600
22680
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
22601
22681
  kind: "mutation",
22602
22682
  auth: "admin"
22603
- });
22683
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
22684
+ kind: "mutation",
22685
+ auth: "admin"
22686
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
22687
+ kind: "mutation",
22688
+ auth: "admin"
22689
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
22604
22690
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
22605
22691
  providerId: string().min(1),
22606
22692
  displayName: string().min(1),
@@ -29701,6 +29787,33 @@ var RecordingRebalanceInputSchema = object({
29701
29787
  minMoveGb: number().min(0).optional()
29702
29788
  });
29703
29789
  /**
29790
+ * Operator-facing placement of one camera onto a recordings location.
29791
+ *
29792
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29793
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29794
+ * currently write — the plan, which may disagree with the pin when Auto.
29795
+ */
29796
+ var RecordingDevicePlacementSchema = object({
29797
+ deviceId: number().int(),
29798
+ profile: string(),
29799
+ locationId: string()
29800
+ });
29801
+ var RecordingDevicePinSchema = object({
29802
+ deviceId: number().int(),
29803
+ /** Recordings-class location this camera is pinned to. */
29804
+ locationId: string()
29805
+ });
29806
+ var RecordingPlacementViewSchema = object({
29807
+ assignments: array(RecordingDevicePlacementSchema),
29808
+ pins: array(RecordingDevicePinSchema),
29809
+ defaultLocations: record(string(), string())
29810
+ });
29811
+ var RecordingSetDevicePlacementInputSchema = object({
29812
+ deviceId: number().int(),
29813
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29814
+ locationId: string().nullable()
29815
+ });
29816
+ /**
29704
29817
  * Result of locating footage at a wall-clock instant for one device/profile.
29705
29818
  * `segment` carries the covering segment's window; `gap` reports the forward
29706
29819
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29926,6 +30039,12 @@ method(object({
29926
30039
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29927
30040
  kind: "mutation",
29928
30041
  auth: "admin"
30042
+ }), method(object({}), RecordingPlacementViewSchema, {
30043
+ kind: "query",
30044
+ auth: "admin"
30045
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
30046
+ kind: "mutation",
30047
+ auth: "admin"
29929
30048
  });
29930
30049
  /**
29931
30050
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34995,6 +35114,12 @@ Object.freeze({
34995
35114
  addonId: null,
34996
35115
  access: "delete"
34997
35116
  },
35117
+ "deviceManager.renameLocation": {
35118
+ capName: "device-manager",
35119
+ capScope: "system",
35120
+ addonId: null,
35121
+ access: "create"
35122
+ },
34998
35123
  "deviceManager.runDeviceAction": {
34999
35124
  capName: "device-manager",
35000
35125
  capScope: "system",
@@ -36687,19 +36812,19 @@ Object.freeze({
36687
36812
  addonId: null,
36688
36813
  access: "view"
36689
36814
  },
36690
- "pipelineAnalytics.getGroup": {
36815
+ "pipelineAnalytics.getKeyEvents": {
36691
36816
  capName: "pipeline-analytics",
36692
36817
  capScope: "device",
36693
36818
  addonId: null,
36694
36819
  access: "view"
36695
36820
  },
36696
- "pipelineAnalytics.getKeyEvents": {
36821
+ "pipelineAnalytics.getKeyEventsBatch": {
36697
36822
  capName: "pipeline-analytics",
36698
36823
  capScope: "device",
36699
36824
  addonId: null,
36700
36825
  access: "view"
36701
36826
  },
36702
- "pipelineAnalytics.getKeyEventsBatch": {
36827
+ "pipelineAnalytics.getMediaReclaimStatus": {
36703
36828
  capName: "pipeline-analytics",
36704
36829
  capScope: "device",
36705
36830
  addonId: null,
@@ -36789,12 +36914,6 @@ Object.freeze({
36789
36914
  addonId: null,
36790
36915
  access: "view"
36791
36916
  },
36792
- "pipelineAnalytics.listGroups": {
36793
- capName: "pipeline-analytics",
36794
- capScope: "device",
36795
- addonId: null,
36796
- access: "view"
36797
- },
36798
36917
  "pipelineAnalytics.listOpsLog": {
36799
36918
  capName: "pipeline-analytics",
36800
36919
  capScope: "device",
@@ -36879,6 +36998,12 @@ Object.freeze({
36879
36998
  addonId: null,
36880
36999
  access: "create"
36881
37000
  },
37001
+ "pipelineAnalytics.reclaimDebugMedia": {
37002
+ capName: "pipeline-analytics",
37003
+ capScope: "device",
37004
+ addonId: null,
37005
+ access: "create"
37006
+ },
36882
37007
  "pipelineAnalytics.reconcileFromDisk": {
36883
37008
  capName: "pipeline-analytics",
36884
37009
  capScope: "device",
@@ -37803,6 +37928,12 @@ Object.freeze({
37803
37928
  addonId: null,
37804
37929
  access: "view"
37805
37930
  },
37931
+ "recording.getPlacement": {
37932
+ capName: "recording",
37933
+ capScope: "system",
37934
+ addonId: null,
37935
+ access: "view"
37936
+ },
37806
37937
  "recording.getPlaybackManifest": {
37807
37938
  capName: "recording",
37808
37939
  capScope: "system",
@@ -37929,6 +38060,12 @@ Object.freeze({
37929
38060
  addonId: null,
37930
38061
  access: "create"
37931
38062
  },
38063
+ "recording.setDevicePlacement": {
38064
+ capName: "recording",
38065
+ capScope: "system",
38066
+ addonId: null,
38067
+ access: "create"
38068
+ },
37932
38069
  "recording.startStorageMigrationMove": {
37933
38070
  capName: "recording",
37934
38071
  capScope: "system",
@@ -38373,12 +38510,36 @@ Object.freeze({
38373
38510
  addonId: null,
38374
38511
  access: "create"
38375
38512
  },
38513
+ "storageMigration.cleanupCancel": {
38514
+ capName: "storage-migration",
38515
+ capScope: "system",
38516
+ addonId: null,
38517
+ access: "create"
38518
+ },
38519
+ "storageMigration.cleanupStart": {
38520
+ capName: "storage-migration",
38521
+ capScope: "system",
38522
+ addonId: null,
38523
+ access: "create"
38524
+ },
38525
+ "storageMigration.cleanupStatus": {
38526
+ capName: "storage-migration",
38527
+ capScope: "system",
38528
+ addonId: null,
38529
+ access: "view"
38530
+ },
38376
38531
  "storageMigration.drain": {
38377
38532
  capName: "storage-migration",
38378
38533
  capScope: "system",
38379
38534
  addonId: null,
38380
38535
  access: "create"
38381
38536
  },
38537
+ "storageMigration.history": {
38538
+ capName: "storage-migration",
38539
+ capScope: "system",
38540
+ addonId: null,
38541
+ access: "view"
38542
+ },
38382
38543
  "storageMigration.movers": {
38383
38544
  capName: "storage-migration",
38384
38545
  capScope: "system",
@@ -40375,11 +40536,6 @@ Object.freeze({
40375
40536
  form: "single",
40376
40537
  optional: true
40377
40538
  }],
40378
- "pipelineAnalytics.getGroup": [{
40379
- name: "deviceId",
40380
- form: "single",
40381
- optional: false
40382
- }],
40383
40539
  "pipelineAnalytics.getKeyEvents": [{
40384
40540
  name: "deviceId",
40385
40541
  form: "single",
@@ -40445,11 +40601,6 @@ Object.freeze({
40445
40601
  form: "single",
40446
40602
  optional: false
40447
40603
  }],
40448
- "pipelineAnalytics.listGroups": [{
40449
- name: "deviceIds",
40450
- form: "array",
40451
- optional: false
40452
- }],
40453
40604
  "pipelineAnalytics.listOpsLog": [{
40454
40605
  name: "deviceId",
40455
40606
  form: "single",
@@ -40495,6 +40646,11 @@ Object.freeze({
40495
40646
  form: "single",
40496
40647
  optional: true
40497
40648
  }],
40649
+ "pipelineAnalytics.reclaimDebugMedia": [{
40650
+ name: "deviceIds",
40651
+ form: "array",
40652
+ optional: true
40653
+ }],
40498
40654
  "pipelineAnalytics.reconcileFromDisk": [{
40499
40655
  name: "deviceId",
40500
40656
  form: "single",
@@ -40860,6 +41016,11 @@ Object.freeze({
40860
41016
  form: "single",
40861
41017
  optional: false
40862
41018
  }],
41019
+ "recording.setDevicePlacement": [{
41020
+ name: "deviceId",
41021
+ form: "single",
41022
+ optional: false
41023
+ }],
40863
41024
  "recording.startStorageMigrationMove": [{
40864
41025
  name: "deviceId",
40865
41026
  form: "single",
package/dist/addon.mjs CHANGED
@@ -9197,6 +9197,13 @@ var MediaRelocateModeSchema = _enum([
9197
9197
  ]);
9198
9198
  var RelocateMediaInputSchema = object({
9199
9199
  toLocationId: string(),
9200
+ /**
9201
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
9202
+ * every row that is not already on `toLocationId` (the historical
9203
+ * behaviour). A named source is what a from→to migration needs: without it
9204
+ * "move events off disk 2" also emptied disk 1.
9205
+ */
9206
+ fromLocationId: string().optional(),
9200
9207
  throttleMbps: number().min(1).max(1e3).optional(),
9201
9208
  /** Omitted = `move`, the pre-existing behaviour. */
9202
9209
  mode: MediaRelocateModeSchema.optional()
@@ -9264,6 +9271,19 @@ var StorageMigrationDestinationsSchema = object({
9264
9271
  galleryMedia: string().min(1).optional()
9265
9272
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
9266
9273
  /**
9274
+ * Optional named source per class. Omitted = the class's current default
9275
+ * (the historical behaviour). A named source that is NOT the default is a
9276
+ * drain of that disk: bytes move, the default stays, and the source is
9277
+ * disabled when the move finishes.
9278
+ */
9279
+ var StorageMigrationSourcesSchema = object({
9280
+ recordings: string().min(1).optional(),
9281
+ recordingsLow: string().min(1).optional(),
9282
+ eventMedia: string().min(1).optional(),
9283
+ backups: string().min(1).optional(),
9284
+ galleryMedia: string().min(1).optional()
9285
+ }).optional();
9286
+ /**
9267
9287
  * How a migration sequences the cutover against the byte move.
9268
9288
  *
9269
9289
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -9285,6 +9305,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
9285
9305
  /** Shared input for planning and starting an orchestrated storage migration. */
9286
9306
  var StorageMigrationInputSchema = object({
9287
9307
  destinations: StorageMigrationDestinationsSchema,
9308
+ /** Omitted = each class's current default. */
9309
+ sources: StorageMigrationSourcesSchema,
9288
9310
  throttleMbps: number().min(1).max(1e3).optional(),
9289
9311
  /** Omitted = `blocking`, which stays the default. */
9290
9312
  mode: StorageMigrationModeSchema.optional()
@@ -9364,6 +9386,13 @@ var StorageMigrationMoveSchema = object({
9364
9386
  storageClass: StorageMigrationClassSchema,
9365
9387
  fromLocationId: string(),
9366
9388
  toLocationId: string(),
9389
+ /**
9390
+ * True when `from` was NOT the class default at plan time. The move still
9391
+ * copies bytes, but the default is left alone and the source is disabled
9392
+ * once the copy verifies. Absent on jobs planned before this field existed
9393
+ * — those jobs always repointed, which is `false`.
9394
+ */
9395
+ freezeSource: boolean().optional(),
9367
9396
  moverJobId: string().nullable(),
9368
9397
  state: RelocateJobStateSchema.nullable(),
9369
9398
  error: string().nullable(),
@@ -9377,6 +9406,7 @@ var StorageMigrationJobSchema = object({
9377
9406
  * can tell a seconds-long cutover from a thirty-hour one. */
9378
9407
  mode: StorageMigrationModeSchema,
9379
9408
  destinations: StorageMigrationDestinationsSchema,
9409
+ sources: StorageMigrationSourcesSchema,
9380
9410
  throttleMbps: number(),
9381
9411
  moves: array(StorageMigrationMoveSchema),
9382
9412
  pauseLeaseId: string().nullable(),
@@ -9402,6 +9432,7 @@ var StorageMigrationFindingSchema = object({
9402
9432
  });
9403
9433
  var StorageMigrationPlanSchema = object({
9404
9434
  destinations: StorageMigrationDestinationsSchema,
9435
+ sources: StorageMigrationSourcesSchema,
9405
9436
  /** The mode this plan was built for. A plan is only valid for its mode: the
9406
9437
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
9407
9438
  * it. */
@@ -9409,7 +9440,8 @@ var StorageMigrationPlanSchema = object({
9409
9440
  moves: array(object({
9410
9441
  storageClass: StorageMigrationClassSchema,
9411
9442
  fromLocationId: string(),
9412
- toLocationId: string()
9443
+ toLocationId: string(),
9444
+ freezeSource: boolean().optional()
9413
9445
  })),
9414
9446
  findings: array(StorageMigrationFindingSchema)
9415
9447
  });
@@ -9587,10 +9619,51 @@ var LedgerWalkReportSchema = object({
9587
9619
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
9588
9620
  var RelocatableMediaCountInputSchema = object({
9589
9621
  toLocationId: string().min(1),
9622
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
9623
+ fromLocationId: string().optional(),
9590
9624
  /** Omitted = `move`. */
9591
9625
  mode: MediaRelocateModeSchema.optional()
9592
9626
  });
9593
9627
  /**
9628
+ * Operator cleanup of leftover analytics rows, optional debug media, and
9629
+ * ghost ledger entries on frozen footage locations.
9630
+ *
9631
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
9632
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
9633
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
9634
+ * with no operator-visible status.
9635
+ */
9636
+ var StorageCleanupPhaseSchema = _enum([
9637
+ "orphans",
9638
+ "debug-media",
9639
+ "ghost-ledger",
9640
+ "done",
9641
+ "failed",
9642
+ "cancelled"
9643
+ ]);
9644
+ var StorageCleanupInputSchema = object({
9645
+ /** Also walk motion stills / track filmstrips. Off by default. */
9646
+ includeDebugMedia: boolean().optional() });
9647
+ var StorageCleanupJobSchema = object({
9648
+ jobId: string(),
9649
+ phase: StorageCleanupPhaseSchema,
9650
+ includeDebugMedia: boolean(),
9651
+ orphansReclaimed: number().int().nonnegative(),
9652
+ orphanBytesReclaimed: number().int().nonnegative(),
9653
+ debugMediaReclaimed: number().int().nonnegative(),
9654
+ debugMediaBytesReclaimed: number().int().nonnegative(),
9655
+ ghostsForgotten: number().int().nonnegative(),
9656
+ ghostBytesForgotten: number().int().nonnegative(),
9657
+ /** Short operator-facing line: current collection, pass, or location. */
9658
+ detail: string().nullable(),
9659
+ cancelRequested: boolean(),
9660
+ startedAt: number(),
9661
+ updatedAt: number(),
9662
+ finishedAt: number().nullable(),
9663
+ error: string().nullable()
9664
+ });
9665
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
9666
+ /**
9594
9667
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
9595
9668
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
9596
9669
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -9618,11 +9691,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
9618
9691
  * The default location for a type uses `id === <type>:default` by
9619
9692
  * convention (the bare type ref like `'backups'` resolves to it).
9620
9693
  *
9621
- * `isSystem: true` marks a location as orchestrator-seeded and
9622
- * undeletable. The bootstrap-installed defaults (one per type) carry
9623
- * this flag; operator-added locations don't. Editing the config of
9624
- * a system location is allowed (path migration, provider swap) but
9625
- * deleting it is rejected at the cap level.
9694
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
9695
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
9696
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
9697
+ * / last-enabled, not on this bit.
9626
9698
  */
9627
9699
  var StorageLocationSchema = object({
9628
9700
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -14165,6 +14237,12 @@ method(object({
14165
14237
  }), _void(), {
14166
14238
  kind: "mutation",
14167
14239
  auth: "admin"
14240
+ }), method(object({
14241
+ from: string(),
14242
+ to: string()
14243
+ }), object({ moved: number() }), {
14244
+ kind: "mutation",
14245
+ auth: "admin"
14168
14246
  }), method(object({
14169
14247
  deviceId: number(),
14170
14248
  disabled: boolean()
@@ -20173,46 +20251,6 @@ var RecentTracksPageSchema = object({
20173
20251
  /** Cursor for the next page, or null when this page is the last. */
20174
20252
  nextCursor: string().nullable()
20175
20253
  });
20176
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
20177
- var LIST_GROUPS_MAX_LIMIT = 100;
20178
- var AnalyticsGroupRecordSchema = object({
20179
- id: string(),
20180
- deviceId: number().int(),
20181
- openedAt: number().int(),
20182
- closedAt: number().int(),
20183
- timestamp: number().int(),
20184
- memberCount: number().int(),
20185
- memberTrackIds: array(string()).readonly(),
20186
- className: string(),
20187
- classes: array(string()).readonly(),
20188
- /** Relative event-media path, or null when the group has no picture yet. */
20189
- mediaUrl: string().nullable(),
20190
- singleton: boolean()
20191
- });
20192
- var AnalyticsGroupMemberSchema = object({
20193
- trackId: string(),
20194
- deviceId: number().int(),
20195
- className: string(),
20196
- firstSeen: number().int(),
20197
- lastSeen: number().int(),
20198
- mediaUrl: string().nullable()
20199
- });
20200
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
20201
- var ListGroupsQueryInput = object({
20202
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
20203
- deviceIds: array(number()),
20204
- /** Window lower bound on `closedAt` (inclusive). */
20205
- since: number().optional(),
20206
- /** Window upper bound on `openedAt` (inclusive). */
20207
- until: number().optional(),
20208
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
20209
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
20210
- cursor: string().optional()
20211
- });
20212
- var ListGroupsPageSchema = object({
20213
- groups: array(AnalyticsGroupRecordSchema).readonly(),
20214
- nextCursor: string().nullable()
20215
- });
20216
20254
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
20217
20255
  var KEY_EVENTS_MAX_LIMIT = 200;
20218
20256
  var KeyEventQueryInput = object({
@@ -20316,9 +20354,7 @@ var TrackCascadeCountsSchema = object({
20316
20354
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
20317
20355
  plates: number().int(),
20318
20356
  /** Per-track CLIP search vectors removed (best-effort). */
20319
- embeddings: number().int(),
20320
- /** Group membership + group rows removed with their last member (best-effort). */
20321
- groups: number().int()
20357
+ embeddings: number().int()
20322
20358
  });
20323
20359
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
20324
20360
  var DiskReconcileCountsSchema = object({
@@ -20488,6 +20524,47 @@ var RebuildStatusSchema = object({
20488
20524
  /** Present when the pass ended by throwing. */
20489
20525
  error: string().nullable()
20490
20526
  });
20527
+ /**
20528
+ * Acknowledgement that a debug-media reclaim STARTED.
20529
+ *
20530
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
20531
+ * it runs detached and this returns immediately. Awaiting it is how the
20532
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
20533
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
20534
+ */
20535
+ var MediaReclaimStartResultSchema = object({
20536
+ started: boolean(),
20537
+ /** True when a pass was already running; the new request is ignored. */
20538
+ alreadyRunning: boolean()
20539
+ });
20540
+ var MediaReclaimInputSchema = object({
20541
+ mode: _enum(["report", "reclaim"]).default("report"),
20542
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
20543
+ deviceIds: array(number().int()).min(1).optional(),
20544
+ restart: boolean().optional(),
20545
+ pageSize: number().int().min(50).max(5e3).optional(),
20546
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
20547
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
20548
+ maxBytesPerRun: number().int().min(1).optional(),
20549
+ budgetMinutes: number().int().min(1).max(720).optional(),
20550
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
20551
+ graceMinutes: number().int().min(1).max(10080).optional()
20552
+ });
20553
+ var MediaReclaimStatusSchema = object({
20554
+ running: boolean(),
20555
+ mode: _enum(["report", "reclaim"]).nullable(),
20556
+ totalExamined: number(),
20557
+ totalEligible: number(),
20558
+ totalReclaimed: number(),
20559
+ totalBytesReclaimed: number(),
20560
+ totalRefused: number(),
20561
+ /** Device+scope windows finished in this pass. */
20562
+ devicesDone: number(),
20563
+ complete: boolean().nullable(),
20564
+ startedAtMs: number().nullable(),
20565
+ finishedAtMs: number().nullable(),
20566
+ error: string().nullable()
20567
+ });
20491
20568
  var ReplayFrameInputSchema = object({
20492
20569
  timestamp: number(),
20493
20570
  frame: PipelineRunResultBridge
@@ -20526,10 +20603,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20526
20603
  * stationary registry). Default false: the timeline lists passages,
20527
20604
  * not parking records (operator decision, 2026-08-15). */
20528
20605
  includeStationary: boolean().optional()
20529
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
20530
- deviceId: number(),
20531
- groupId: string().min(1)
20532
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20606
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20533
20607
  kind: "mutation",
20534
20608
  auth: "admin"
20535
20609
  }), 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({
@@ -20629,6 +20703,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20629
20703
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20630
20704
  kind: "query",
20631
20705
  auth: "admin"
20706
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
20707
+ kind: "mutation",
20708
+ auth: "admin"
20709
+ }), method(object({}), MediaReclaimStatusSchema, {
20710
+ kind: "query",
20711
+ auth: "admin"
20632
20712
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
20633
20713
  kind: "query",
20634
20714
  auth: "admin"
@@ -22599,7 +22679,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
22599
22679
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
22600
22680
  kind: "mutation",
22601
22681
  auth: "admin"
22602
- });
22682
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
22683
+ kind: "mutation",
22684
+ auth: "admin"
22685
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
22686
+ kind: "mutation",
22687
+ auth: "admin"
22688
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
22603
22689
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
22604
22690
  providerId: string().min(1),
22605
22691
  displayName: string().min(1),
@@ -29700,6 +29786,33 @@ var RecordingRebalanceInputSchema = object({
29700
29786
  minMoveGb: number().min(0).optional()
29701
29787
  });
29702
29788
  /**
29789
+ * Operator-facing placement of one camera onto a recordings location.
29790
+ *
29791
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29792
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29793
+ * currently write — the plan, which may disagree with the pin when Auto.
29794
+ */
29795
+ var RecordingDevicePlacementSchema = object({
29796
+ deviceId: number().int(),
29797
+ profile: string(),
29798
+ locationId: string()
29799
+ });
29800
+ var RecordingDevicePinSchema = object({
29801
+ deviceId: number().int(),
29802
+ /** Recordings-class location this camera is pinned to. */
29803
+ locationId: string()
29804
+ });
29805
+ var RecordingPlacementViewSchema = object({
29806
+ assignments: array(RecordingDevicePlacementSchema),
29807
+ pins: array(RecordingDevicePinSchema),
29808
+ defaultLocations: record(string(), string())
29809
+ });
29810
+ var RecordingSetDevicePlacementInputSchema = object({
29811
+ deviceId: number().int(),
29812
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29813
+ locationId: string().nullable()
29814
+ });
29815
+ /**
29703
29816
  * Result of locating footage at a wall-clock instant for one device/profile.
29704
29817
  * `segment` carries the covering segment's window; `gap` reports the forward
29705
29818
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29925,6 +30038,12 @@ method(object({
29925
30038
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29926
30039
  kind: "mutation",
29927
30040
  auth: "admin"
30041
+ }), method(object({}), RecordingPlacementViewSchema, {
30042
+ kind: "query",
30043
+ auth: "admin"
30044
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
30045
+ kind: "mutation",
30046
+ auth: "admin"
29928
30047
  });
29929
30048
  /**
29930
30049
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34994,6 +35113,12 @@ Object.freeze({
34994
35113
  addonId: null,
34995
35114
  access: "delete"
34996
35115
  },
35116
+ "deviceManager.renameLocation": {
35117
+ capName: "device-manager",
35118
+ capScope: "system",
35119
+ addonId: null,
35120
+ access: "create"
35121
+ },
34997
35122
  "deviceManager.runDeviceAction": {
34998
35123
  capName: "device-manager",
34999
35124
  capScope: "system",
@@ -36686,19 +36811,19 @@ Object.freeze({
36686
36811
  addonId: null,
36687
36812
  access: "view"
36688
36813
  },
36689
- "pipelineAnalytics.getGroup": {
36814
+ "pipelineAnalytics.getKeyEvents": {
36690
36815
  capName: "pipeline-analytics",
36691
36816
  capScope: "device",
36692
36817
  addonId: null,
36693
36818
  access: "view"
36694
36819
  },
36695
- "pipelineAnalytics.getKeyEvents": {
36820
+ "pipelineAnalytics.getKeyEventsBatch": {
36696
36821
  capName: "pipeline-analytics",
36697
36822
  capScope: "device",
36698
36823
  addonId: null,
36699
36824
  access: "view"
36700
36825
  },
36701
- "pipelineAnalytics.getKeyEventsBatch": {
36826
+ "pipelineAnalytics.getMediaReclaimStatus": {
36702
36827
  capName: "pipeline-analytics",
36703
36828
  capScope: "device",
36704
36829
  addonId: null,
@@ -36788,12 +36913,6 @@ Object.freeze({
36788
36913
  addonId: null,
36789
36914
  access: "view"
36790
36915
  },
36791
- "pipelineAnalytics.listGroups": {
36792
- capName: "pipeline-analytics",
36793
- capScope: "device",
36794
- addonId: null,
36795
- access: "view"
36796
- },
36797
36916
  "pipelineAnalytics.listOpsLog": {
36798
36917
  capName: "pipeline-analytics",
36799
36918
  capScope: "device",
@@ -36878,6 +36997,12 @@ Object.freeze({
36878
36997
  addonId: null,
36879
36998
  access: "create"
36880
36999
  },
37000
+ "pipelineAnalytics.reclaimDebugMedia": {
37001
+ capName: "pipeline-analytics",
37002
+ capScope: "device",
37003
+ addonId: null,
37004
+ access: "create"
37005
+ },
36881
37006
  "pipelineAnalytics.reconcileFromDisk": {
36882
37007
  capName: "pipeline-analytics",
36883
37008
  capScope: "device",
@@ -37802,6 +37927,12 @@ Object.freeze({
37802
37927
  addonId: null,
37803
37928
  access: "view"
37804
37929
  },
37930
+ "recording.getPlacement": {
37931
+ capName: "recording",
37932
+ capScope: "system",
37933
+ addonId: null,
37934
+ access: "view"
37935
+ },
37805
37936
  "recording.getPlaybackManifest": {
37806
37937
  capName: "recording",
37807
37938
  capScope: "system",
@@ -37928,6 +38059,12 @@ Object.freeze({
37928
38059
  addonId: null,
37929
38060
  access: "create"
37930
38061
  },
38062
+ "recording.setDevicePlacement": {
38063
+ capName: "recording",
38064
+ capScope: "system",
38065
+ addonId: null,
38066
+ access: "create"
38067
+ },
37931
38068
  "recording.startStorageMigrationMove": {
37932
38069
  capName: "recording",
37933
38070
  capScope: "system",
@@ -38372,12 +38509,36 @@ Object.freeze({
38372
38509
  addonId: null,
38373
38510
  access: "create"
38374
38511
  },
38512
+ "storageMigration.cleanupCancel": {
38513
+ capName: "storage-migration",
38514
+ capScope: "system",
38515
+ addonId: null,
38516
+ access: "create"
38517
+ },
38518
+ "storageMigration.cleanupStart": {
38519
+ capName: "storage-migration",
38520
+ capScope: "system",
38521
+ addonId: null,
38522
+ access: "create"
38523
+ },
38524
+ "storageMigration.cleanupStatus": {
38525
+ capName: "storage-migration",
38526
+ capScope: "system",
38527
+ addonId: null,
38528
+ access: "view"
38529
+ },
38375
38530
  "storageMigration.drain": {
38376
38531
  capName: "storage-migration",
38377
38532
  capScope: "system",
38378
38533
  addonId: null,
38379
38534
  access: "create"
38380
38535
  },
38536
+ "storageMigration.history": {
38537
+ capName: "storage-migration",
38538
+ capScope: "system",
38539
+ addonId: null,
38540
+ access: "view"
38541
+ },
38381
38542
  "storageMigration.movers": {
38382
38543
  capName: "storage-migration",
38383
38544
  capScope: "system",
@@ -40374,11 +40535,6 @@ Object.freeze({
40374
40535
  form: "single",
40375
40536
  optional: true
40376
40537
  }],
40377
- "pipelineAnalytics.getGroup": [{
40378
- name: "deviceId",
40379
- form: "single",
40380
- optional: false
40381
- }],
40382
40538
  "pipelineAnalytics.getKeyEvents": [{
40383
40539
  name: "deviceId",
40384
40540
  form: "single",
@@ -40444,11 +40600,6 @@ Object.freeze({
40444
40600
  form: "single",
40445
40601
  optional: false
40446
40602
  }],
40447
- "pipelineAnalytics.listGroups": [{
40448
- name: "deviceIds",
40449
- form: "array",
40450
- optional: false
40451
- }],
40452
40603
  "pipelineAnalytics.listOpsLog": [{
40453
40604
  name: "deviceId",
40454
40605
  form: "single",
@@ -40494,6 +40645,11 @@ Object.freeze({
40494
40645
  form: "single",
40495
40646
  optional: true
40496
40647
  }],
40648
+ "pipelineAnalytics.reclaimDebugMedia": [{
40649
+ name: "deviceIds",
40650
+ form: "array",
40651
+ optional: true
40652
+ }],
40497
40653
  "pipelineAnalytics.reconcileFromDisk": [{
40498
40654
  name: "deviceId",
40499
40655
  form: "single",
@@ -40859,6 +41015,11 @@ Object.freeze({
40859
41015
  form: "single",
40860
41016
  optional: false
40861
41017
  }],
41018
+ "recording.setDevicePlacement": [{
41019
+ name: "deviceId",
41020
+ form: "single",
41021
+ optional: false
41022
+ }],
40862
41023
  "recording.startStorageMigrationMove": [{
40863
41024
  name: "deviceId",
40864
41025
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-petkit",
3
- "version": "0.2.49",
3
+ "version": "0.2.50",
4
4
  "description": "PetKit smart-feeder device-provider addon for CamStack — wraps the @apocaliss92/nodepetkit PetKit cloud client",
5
5
  "keywords": [
6
6
  "camstack",