@camstack/addon-provider-petkit 0.2.49 → 0.2.51

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 +236 -73
  2. package/dist/addon.mjs +236 -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()
@@ -16916,6 +16994,8 @@ var NcSystemEventKindSchema = _enum([
16916
16994
  "device-offline",
16917
16995
  "device-disabled",
16918
16996
  "device-enabled",
16997
+ "device-battery-low",
16998
+ "device-battery-normal",
16919
16999
  "stream-online",
16920
17000
  "stream-offline",
16921
17001
  "node-online",
@@ -20174,46 +20254,6 @@ var RecentTracksPageSchema = object({
20174
20254
  /** Cursor for the next page, or null when this page is the last. */
20175
20255
  nextCursor: string().nullable()
20176
20256
  });
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
20257
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
20218
20258
  var KEY_EVENTS_MAX_LIMIT = 200;
20219
20259
  var KeyEventQueryInput = object({
@@ -20317,9 +20357,7 @@ var TrackCascadeCountsSchema = object({
20317
20357
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
20318
20358
  plates: number().int(),
20319
20359
  /** 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()
20360
+ embeddings: number().int()
20323
20361
  });
20324
20362
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
20325
20363
  var DiskReconcileCountsSchema = object({
@@ -20489,6 +20527,47 @@ var RebuildStatusSchema = object({
20489
20527
  /** Present when the pass ended by throwing. */
20490
20528
  error: string().nullable()
20491
20529
  });
20530
+ /**
20531
+ * Acknowledgement that a debug-media reclaim STARTED.
20532
+ *
20533
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
20534
+ * it runs detached and this returns immediately. Awaiting it is how the
20535
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
20536
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
20537
+ */
20538
+ var MediaReclaimStartResultSchema = object({
20539
+ started: boolean(),
20540
+ /** True when a pass was already running; the new request is ignored. */
20541
+ alreadyRunning: boolean()
20542
+ });
20543
+ var MediaReclaimInputSchema = object({
20544
+ mode: _enum(["report", "reclaim"]).default("report"),
20545
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
20546
+ deviceIds: array(number().int()).min(1).optional(),
20547
+ restart: boolean().optional(),
20548
+ pageSize: number().int().min(50).max(5e3).optional(),
20549
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
20550
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
20551
+ maxBytesPerRun: number().int().min(1).optional(),
20552
+ budgetMinutes: number().int().min(1).max(720).optional(),
20553
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
20554
+ graceMinutes: number().int().min(1).max(10080).optional()
20555
+ });
20556
+ var MediaReclaimStatusSchema = object({
20557
+ running: boolean(),
20558
+ mode: _enum(["report", "reclaim"]).nullable(),
20559
+ totalExamined: number(),
20560
+ totalEligible: number(),
20561
+ totalReclaimed: number(),
20562
+ totalBytesReclaimed: number(),
20563
+ totalRefused: number(),
20564
+ /** Device+scope windows finished in this pass. */
20565
+ devicesDone: number(),
20566
+ complete: boolean().nullable(),
20567
+ startedAtMs: number().nullable(),
20568
+ finishedAtMs: number().nullable(),
20569
+ error: string().nullable()
20570
+ });
20492
20571
  var ReplayFrameInputSchema = object({
20493
20572
  timestamp: number(),
20494
20573
  frame: PipelineRunResultBridge
@@ -20527,10 +20606,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20527
20606
  * stationary registry). Default false: the timeline lists passages,
20528
20607
  * not parking records (operator decision, 2026-08-15). */
20529
20608
  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(), {
20609
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20534
20610
  kind: "mutation",
20535
20611
  auth: "admin"
20536
20612
  }), 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 +20706,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20630
20706
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20631
20707
  kind: "query",
20632
20708
  auth: "admin"
20709
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
20710
+ kind: "mutation",
20711
+ auth: "admin"
20712
+ }), method(object({}), MediaReclaimStatusSchema, {
20713
+ kind: "query",
20714
+ auth: "admin"
20633
20715
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
20634
20716
  kind: "query",
20635
20717
  auth: "admin"
@@ -22600,7 +22682,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
22600
22682
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
22601
22683
  kind: "mutation",
22602
22684
  auth: "admin"
22603
- });
22685
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
22686
+ kind: "mutation",
22687
+ auth: "admin"
22688
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
22689
+ kind: "mutation",
22690
+ auth: "admin"
22691
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
22604
22692
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
22605
22693
  providerId: string().min(1),
22606
22694
  displayName: string().min(1),
@@ -29701,6 +29789,33 @@ var RecordingRebalanceInputSchema = object({
29701
29789
  minMoveGb: number().min(0).optional()
29702
29790
  });
29703
29791
  /**
29792
+ * Operator-facing placement of one camera onto a recordings location.
29793
+ *
29794
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29795
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29796
+ * currently write — the plan, which may disagree with the pin when Auto.
29797
+ */
29798
+ var RecordingDevicePlacementSchema = object({
29799
+ deviceId: number().int(),
29800
+ profile: string(),
29801
+ locationId: string()
29802
+ });
29803
+ var RecordingDevicePinSchema = object({
29804
+ deviceId: number().int(),
29805
+ /** Recordings-class location this camera is pinned to. */
29806
+ locationId: string()
29807
+ });
29808
+ var RecordingPlacementViewSchema = object({
29809
+ assignments: array(RecordingDevicePlacementSchema),
29810
+ pins: array(RecordingDevicePinSchema),
29811
+ defaultLocations: record(string(), string())
29812
+ });
29813
+ var RecordingSetDevicePlacementInputSchema = object({
29814
+ deviceId: number().int(),
29815
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29816
+ locationId: string().nullable()
29817
+ });
29818
+ /**
29704
29819
  * Result of locating footage at a wall-clock instant for one device/profile.
29705
29820
  * `segment` carries the covering segment's window; `gap` reports the forward
29706
29821
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29926,6 +30041,12 @@ method(object({
29926
30041
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29927
30042
  kind: "mutation",
29928
30043
  auth: "admin"
30044
+ }), method(object({}), RecordingPlacementViewSchema, {
30045
+ kind: "query",
30046
+ auth: "admin"
30047
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
30048
+ kind: "mutation",
30049
+ auth: "admin"
29929
30050
  });
29930
30051
  /**
29931
30052
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34995,6 +35116,12 @@ Object.freeze({
34995
35116
  addonId: null,
34996
35117
  access: "delete"
34997
35118
  },
35119
+ "deviceManager.renameLocation": {
35120
+ capName: "device-manager",
35121
+ capScope: "system",
35122
+ addonId: null,
35123
+ access: "create"
35124
+ },
34998
35125
  "deviceManager.runDeviceAction": {
34999
35126
  capName: "device-manager",
35000
35127
  capScope: "system",
@@ -36687,19 +36814,19 @@ Object.freeze({
36687
36814
  addonId: null,
36688
36815
  access: "view"
36689
36816
  },
36690
- "pipelineAnalytics.getGroup": {
36817
+ "pipelineAnalytics.getKeyEvents": {
36691
36818
  capName: "pipeline-analytics",
36692
36819
  capScope: "device",
36693
36820
  addonId: null,
36694
36821
  access: "view"
36695
36822
  },
36696
- "pipelineAnalytics.getKeyEvents": {
36823
+ "pipelineAnalytics.getKeyEventsBatch": {
36697
36824
  capName: "pipeline-analytics",
36698
36825
  capScope: "device",
36699
36826
  addonId: null,
36700
36827
  access: "view"
36701
36828
  },
36702
- "pipelineAnalytics.getKeyEventsBatch": {
36829
+ "pipelineAnalytics.getMediaReclaimStatus": {
36703
36830
  capName: "pipeline-analytics",
36704
36831
  capScope: "device",
36705
36832
  addonId: null,
@@ -36789,12 +36916,6 @@ Object.freeze({
36789
36916
  addonId: null,
36790
36917
  access: "view"
36791
36918
  },
36792
- "pipelineAnalytics.listGroups": {
36793
- capName: "pipeline-analytics",
36794
- capScope: "device",
36795
- addonId: null,
36796
- access: "view"
36797
- },
36798
36919
  "pipelineAnalytics.listOpsLog": {
36799
36920
  capName: "pipeline-analytics",
36800
36921
  capScope: "device",
@@ -36879,6 +37000,12 @@ Object.freeze({
36879
37000
  addonId: null,
36880
37001
  access: "create"
36881
37002
  },
37003
+ "pipelineAnalytics.reclaimDebugMedia": {
37004
+ capName: "pipeline-analytics",
37005
+ capScope: "device",
37006
+ addonId: null,
37007
+ access: "create"
37008
+ },
36882
37009
  "pipelineAnalytics.reconcileFromDisk": {
36883
37010
  capName: "pipeline-analytics",
36884
37011
  capScope: "device",
@@ -37803,6 +37930,12 @@ Object.freeze({
37803
37930
  addonId: null,
37804
37931
  access: "view"
37805
37932
  },
37933
+ "recording.getPlacement": {
37934
+ capName: "recording",
37935
+ capScope: "system",
37936
+ addonId: null,
37937
+ access: "view"
37938
+ },
37806
37939
  "recording.getPlaybackManifest": {
37807
37940
  capName: "recording",
37808
37941
  capScope: "system",
@@ -37929,6 +38062,12 @@ Object.freeze({
37929
38062
  addonId: null,
37930
38063
  access: "create"
37931
38064
  },
38065
+ "recording.setDevicePlacement": {
38066
+ capName: "recording",
38067
+ capScope: "system",
38068
+ addonId: null,
38069
+ access: "create"
38070
+ },
37932
38071
  "recording.startStorageMigrationMove": {
37933
38072
  capName: "recording",
37934
38073
  capScope: "system",
@@ -38373,12 +38512,36 @@ Object.freeze({
38373
38512
  addonId: null,
38374
38513
  access: "create"
38375
38514
  },
38515
+ "storageMigration.cleanupCancel": {
38516
+ capName: "storage-migration",
38517
+ capScope: "system",
38518
+ addonId: null,
38519
+ access: "create"
38520
+ },
38521
+ "storageMigration.cleanupStart": {
38522
+ capName: "storage-migration",
38523
+ capScope: "system",
38524
+ addonId: null,
38525
+ access: "create"
38526
+ },
38527
+ "storageMigration.cleanupStatus": {
38528
+ capName: "storage-migration",
38529
+ capScope: "system",
38530
+ addonId: null,
38531
+ access: "view"
38532
+ },
38376
38533
  "storageMigration.drain": {
38377
38534
  capName: "storage-migration",
38378
38535
  capScope: "system",
38379
38536
  addonId: null,
38380
38537
  access: "create"
38381
38538
  },
38539
+ "storageMigration.history": {
38540
+ capName: "storage-migration",
38541
+ capScope: "system",
38542
+ addonId: null,
38543
+ access: "view"
38544
+ },
38382
38545
  "storageMigration.movers": {
38383
38546
  capName: "storage-migration",
38384
38547
  capScope: "system",
@@ -40375,11 +40538,6 @@ Object.freeze({
40375
40538
  form: "single",
40376
40539
  optional: true
40377
40540
  }],
40378
- "pipelineAnalytics.getGroup": [{
40379
- name: "deviceId",
40380
- form: "single",
40381
- optional: false
40382
- }],
40383
40541
  "pipelineAnalytics.getKeyEvents": [{
40384
40542
  name: "deviceId",
40385
40543
  form: "single",
@@ -40445,11 +40603,6 @@ Object.freeze({
40445
40603
  form: "single",
40446
40604
  optional: false
40447
40605
  }],
40448
- "pipelineAnalytics.listGroups": [{
40449
- name: "deviceIds",
40450
- form: "array",
40451
- optional: false
40452
- }],
40453
40606
  "pipelineAnalytics.listOpsLog": [{
40454
40607
  name: "deviceId",
40455
40608
  form: "single",
@@ -40495,6 +40648,11 @@ Object.freeze({
40495
40648
  form: "single",
40496
40649
  optional: true
40497
40650
  }],
40651
+ "pipelineAnalytics.reclaimDebugMedia": [{
40652
+ name: "deviceIds",
40653
+ form: "array",
40654
+ optional: true
40655
+ }],
40498
40656
  "pipelineAnalytics.reconcileFromDisk": [{
40499
40657
  name: "deviceId",
40500
40658
  form: "single",
@@ -40860,6 +41018,11 @@ Object.freeze({
40860
41018
  form: "single",
40861
41019
  optional: false
40862
41020
  }],
41021
+ "recording.setDevicePlacement": [{
41022
+ name: "deviceId",
41023
+ form: "single",
41024
+ optional: false
41025
+ }],
40863
41026
  "recording.startStorageMigrationMove": [{
40864
41027
  name: "deviceId",
40865
41028
  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()
@@ -16915,6 +16993,8 @@ var NcSystemEventKindSchema = _enum([
16915
16993
  "device-offline",
16916
16994
  "device-disabled",
16917
16995
  "device-enabled",
16996
+ "device-battery-low",
16997
+ "device-battery-normal",
16918
16998
  "stream-online",
16919
16999
  "stream-offline",
16920
17000
  "node-online",
@@ -20173,46 +20253,6 @@ var RecentTracksPageSchema = object({
20173
20253
  /** Cursor for the next page, or null when this page is the last. */
20174
20254
  nextCursor: string().nullable()
20175
20255
  });
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
20256
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
20217
20257
  var KEY_EVENTS_MAX_LIMIT = 200;
20218
20258
  var KeyEventQueryInput = object({
@@ -20316,9 +20356,7 @@ var TrackCascadeCountsSchema = object({
20316
20356
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
20317
20357
  plates: number().int(),
20318
20358
  /** 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()
20359
+ embeddings: number().int()
20322
20360
  });
20323
20361
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
20324
20362
  var DiskReconcileCountsSchema = object({
@@ -20488,6 +20526,47 @@ var RebuildStatusSchema = object({
20488
20526
  /** Present when the pass ended by throwing. */
20489
20527
  error: string().nullable()
20490
20528
  });
20529
+ /**
20530
+ * Acknowledgement that a debug-media reclaim STARTED.
20531
+ *
20532
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
20533
+ * it runs detached and this returns immediately. Awaiting it is how the
20534
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
20535
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
20536
+ */
20537
+ var MediaReclaimStartResultSchema = object({
20538
+ started: boolean(),
20539
+ /** True when a pass was already running; the new request is ignored. */
20540
+ alreadyRunning: boolean()
20541
+ });
20542
+ var MediaReclaimInputSchema = object({
20543
+ mode: _enum(["report", "reclaim"]).default("report"),
20544
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
20545
+ deviceIds: array(number().int()).min(1).optional(),
20546
+ restart: boolean().optional(),
20547
+ pageSize: number().int().min(50).max(5e3).optional(),
20548
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
20549
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
20550
+ maxBytesPerRun: number().int().min(1).optional(),
20551
+ budgetMinutes: number().int().min(1).max(720).optional(),
20552
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
20553
+ graceMinutes: number().int().min(1).max(10080).optional()
20554
+ });
20555
+ var MediaReclaimStatusSchema = object({
20556
+ running: boolean(),
20557
+ mode: _enum(["report", "reclaim"]).nullable(),
20558
+ totalExamined: number(),
20559
+ totalEligible: number(),
20560
+ totalReclaimed: number(),
20561
+ totalBytesReclaimed: number(),
20562
+ totalRefused: number(),
20563
+ /** Device+scope windows finished in this pass. */
20564
+ devicesDone: number(),
20565
+ complete: boolean().nullable(),
20566
+ startedAtMs: number().nullable(),
20567
+ finishedAtMs: number().nullable(),
20568
+ error: string().nullable()
20569
+ });
20491
20570
  var ReplayFrameInputSchema = object({
20492
20571
  timestamp: number(),
20493
20572
  frame: PipelineRunResultBridge
@@ -20526,10 +20605,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20526
20605
  * stationary registry). Default false: the timeline lists passages,
20527
20606
  * not parking records (operator decision, 2026-08-15). */
20528
20607
  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(), {
20608
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
20533
20609
  kind: "mutation",
20534
20610
  auth: "admin"
20535
20611
  }), 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 +20705,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20629
20705
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20630
20706
  kind: "query",
20631
20707
  auth: "admin"
20708
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
20709
+ kind: "mutation",
20710
+ auth: "admin"
20711
+ }), method(object({}), MediaReclaimStatusSchema, {
20712
+ kind: "query",
20713
+ auth: "admin"
20632
20714
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
20633
20715
  kind: "query",
20634
20716
  auth: "admin"
@@ -22599,7 +22681,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
22599
22681
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
22600
22682
  kind: "mutation",
22601
22683
  auth: "admin"
22602
- });
22684
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
22685
+ kind: "mutation",
22686
+ auth: "admin"
22687
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
22688
+ kind: "mutation",
22689
+ auth: "admin"
22690
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
22603
22691
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
22604
22692
  providerId: string().min(1),
22605
22693
  displayName: string().min(1),
@@ -29700,6 +29788,33 @@ var RecordingRebalanceInputSchema = object({
29700
29788
  minMoveGb: number().min(0).optional()
29701
29789
  });
29702
29790
  /**
29791
+ * Operator-facing placement of one camera onto a recordings location.
29792
+ *
29793
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29794
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29795
+ * currently write — the plan, which may disagree with the pin when Auto.
29796
+ */
29797
+ var RecordingDevicePlacementSchema = object({
29798
+ deviceId: number().int(),
29799
+ profile: string(),
29800
+ locationId: string()
29801
+ });
29802
+ var RecordingDevicePinSchema = object({
29803
+ deviceId: number().int(),
29804
+ /** Recordings-class location this camera is pinned to. */
29805
+ locationId: string()
29806
+ });
29807
+ var RecordingPlacementViewSchema = object({
29808
+ assignments: array(RecordingDevicePlacementSchema),
29809
+ pins: array(RecordingDevicePinSchema),
29810
+ defaultLocations: record(string(), string())
29811
+ });
29812
+ var RecordingSetDevicePlacementInputSchema = object({
29813
+ deviceId: number().int(),
29814
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29815
+ locationId: string().nullable()
29816
+ });
29817
+ /**
29703
29818
  * Result of locating footage at a wall-clock instant for one device/profile.
29704
29819
  * `segment` carries the covering segment's window; `gap` reports the forward
29705
29820
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29925,6 +30040,12 @@ method(object({
29925
30040
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29926
30041
  kind: "mutation",
29927
30042
  auth: "admin"
30043
+ }), method(object({}), RecordingPlacementViewSchema, {
30044
+ kind: "query",
30045
+ auth: "admin"
30046
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
30047
+ kind: "mutation",
30048
+ auth: "admin"
29928
30049
  });
29929
30050
  /**
29930
30051
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34994,6 +35115,12 @@ Object.freeze({
34994
35115
  addonId: null,
34995
35116
  access: "delete"
34996
35117
  },
35118
+ "deviceManager.renameLocation": {
35119
+ capName: "device-manager",
35120
+ capScope: "system",
35121
+ addonId: null,
35122
+ access: "create"
35123
+ },
34997
35124
  "deviceManager.runDeviceAction": {
34998
35125
  capName: "device-manager",
34999
35126
  capScope: "system",
@@ -36686,19 +36813,19 @@ Object.freeze({
36686
36813
  addonId: null,
36687
36814
  access: "view"
36688
36815
  },
36689
- "pipelineAnalytics.getGroup": {
36816
+ "pipelineAnalytics.getKeyEvents": {
36690
36817
  capName: "pipeline-analytics",
36691
36818
  capScope: "device",
36692
36819
  addonId: null,
36693
36820
  access: "view"
36694
36821
  },
36695
- "pipelineAnalytics.getKeyEvents": {
36822
+ "pipelineAnalytics.getKeyEventsBatch": {
36696
36823
  capName: "pipeline-analytics",
36697
36824
  capScope: "device",
36698
36825
  addonId: null,
36699
36826
  access: "view"
36700
36827
  },
36701
- "pipelineAnalytics.getKeyEventsBatch": {
36828
+ "pipelineAnalytics.getMediaReclaimStatus": {
36702
36829
  capName: "pipeline-analytics",
36703
36830
  capScope: "device",
36704
36831
  addonId: null,
@@ -36788,12 +36915,6 @@ Object.freeze({
36788
36915
  addonId: null,
36789
36916
  access: "view"
36790
36917
  },
36791
- "pipelineAnalytics.listGroups": {
36792
- capName: "pipeline-analytics",
36793
- capScope: "device",
36794
- addonId: null,
36795
- access: "view"
36796
- },
36797
36918
  "pipelineAnalytics.listOpsLog": {
36798
36919
  capName: "pipeline-analytics",
36799
36920
  capScope: "device",
@@ -36878,6 +36999,12 @@ Object.freeze({
36878
36999
  addonId: null,
36879
37000
  access: "create"
36880
37001
  },
37002
+ "pipelineAnalytics.reclaimDebugMedia": {
37003
+ capName: "pipeline-analytics",
37004
+ capScope: "device",
37005
+ addonId: null,
37006
+ access: "create"
37007
+ },
36881
37008
  "pipelineAnalytics.reconcileFromDisk": {
36882
37009
  capName: "pipeline-analytics",
36883
37010
  capScope: "device",
@@ -37802,6 +37929,12 @@ Object.freeze({
37802
37929
  addonId: null,
37803
37930
  access: "view"
37804
37931
  },
37932
+ "recording.getPlacement": {
37933
+ capName: "recording",
37934
+ capScope: "system",
37935
+ addonId: null,
37936
+ access: "view"
37937
+ },
37805
37938
  "recording.getPlaybackManifest": {
37806
37939
  capName: "recording",
37807
37940
  capScope: "system",
@@ -37928,6 +38061,12 @@ Object.freeze({
37928
38061
  addonId: null,
37929
38062
  access: "create"
37930
38063
  },
38064
+ "recording.setDevicePlacement": {
38065
+ capName: "recording",
38066
+ capScope: "system",
38067
+ addonId: null,
38068
+ access: "create"
38069
+ },
37931
38070
  "recording.startStorageMigrationMove": {
37932
38071
  capName: "recording",
37933
38072
  capScope: "system",
@@ -38372,12 +38511,36 @@ Object.freeze({
38372
38511
  addonId: null,
38373
38512
  access: "create"
38374
38513
  },
38514
+ "storageMigration.cleanupCancel": {
38515
+ capName: "storage-migration",
38516
+ capScope: "system",
38517
+ addonId: null,
38518
+ access: "create"
38519
+ },
38520
+ "storageMigration.cleanupStart": {
38521
+ capName: "storage-migration",
38522
+ capScope: "system",
38523
+ addonId: null,
38524
+ access: "create"
38525
+ },
38526
+ "storageMigration.cleanupStatus": {
38527
+ capName: "storage-migration",
38528
+ capScope: "system",
38529
+ addonId: null,
38530
+ access: "view"
38531
+ },
38375
38532
  "storageMigration.drain": {
38376
38533
  capName: "storage-migration",
38377
38534
  capScope: "system",
38378
38535
  addonId: null,
38379
38536
  access: "create"
38380
38537
  },
38538
+ "storageMigration.history": {
38539
+ capName: "storage-migration",
38540
+ capScope: "system",
38541
+ addonId: null,
38542
+ access: "view"
38543
+ },
38381
38544
  "storageMigration.movers": {
38382
38545
  capName: "storage-migration",
38383
38546
  capScope: "system",
@@ -40374,11 +40537,6 @@ Object.freeze({
40374
40537
  form: "single",
40375
40538
  optional: true
40376
40539
  }],
40377
- "pipelineAnalytics.getGroup": [{
40378
- name: "deviceId",
40379
- form: "single",
40380
- optional: false
40381
- }],
40382
40540
  "pipelineAnalytics.getKeyEvents": [{
40383
40541
  name: "deviceId",
40384
40542
  form: "single",
@@ -40444,11 +40602,6 @@ Object.freeze({
40444
40602
  form: "single",
40445
40603
  optional: false
40446
40604
  }],
40447
- "pipelineAnalytics.listGroups": [{
40448
- name: "deviceIds",
40449
- form: "array",
40450
- optional: false
40451
- }],
40452
40605
  "pipelineAnalytics.listOpsLog": [{
40453
40606
  name: "deviceId",
40454
40607
  form: "single",
@@ -40494,6 +40647,11 @@ Object.freeze({
40494
40647
  form: "single",
40495
40648
  optional: true
40496
40649
  }],
40650
+ "pipelineAnalytics.reclaimDebugMedia": [{
40651
+ name: "deviceIds",
40652
+ form: "array",
40653
+ optional: true
40654
+ }],
40497
40655
  "pipelineAnalytics.reconcileFromDisk": [{
40498
40656
  name: "deviceId",
40499
40657
  form: "single",
@@ -40859,6 +41017,11 @@ Object.freeze({
40859
41017
  form: "single",
40860
41018
  optional: false
40861
41019
  }],
41020
+ "recording.setDevicePlacement": [{
41021
+ name: "deviceId",
41022
+ form: "single",
41023
+ optional: false
41024
+ }],
40862
41025
  "recording.startStorageMigrationMove": [{
40863
41026
  name: "deviceId",
40864
41027
  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.51",
4
4
  "description": "PetKit smart-feeder device-provider addon for CamStack — wraps the @apocaliss92/nodepetkit PetKit cloud client",
5
5
  "keywords": [
6
6
  "camstack",