@camstack/addon-notifiers 1.2.53 → 1.2.54

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
@@ -8229,6 +8229,13 @@ var MediaRelocateModeSchema = _enum([
8229
8229
  ]);
8230
8230
  var RelocateMediaInputSchema = object({
8231
8231
  toLocationId: string(),
8232
+ /**
8233
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8234
+ * every row that is not already on `toLocationId` (the historical
8235
+ * behaviour). A named source is what a from→to migration needs: without it
8236
+ * "move events off disk 2" also emptied disk 1.
8237
+ */
8238
+ fromLocationId: string().optional(),
8232
8239
  throttleMbps: number().min(1).max(1e3).optional(),
8233
8240
  /** Omitted = `move`, the pre-existing behaviour. */
8234
8241
  mode: MediaRelocateModeSchema.optional()
@@ -8296,6 +8303,19 @@ var StorageMigrationDestinationsSchema = object({
8296
8303
  galleryMedia: string().min(1).optional()
8297
8304
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8298
8305
  /**
8306
+ * Optional named source per class. Omitted = the class's current default
8307
+ * (the historical behaviour). A named source that is NOT the default is a
8308
+ * drain of that disk: bytes move, the default stays, and the source is
8309
+ * disabled when the move finishes.
8310
+ */
8311
+ var StorageMigrationSourcesSchema = object({
8312
+ recordings: string().min(1).optional(),
8313
+ recordingsLow: string().min(1).optional(),
8314
+ eventMedia: string().min(1).optional(),
8315
+ backups: string().min(1).optional(),
8316
+ galleryMedia: string().min(1).optional()
8317
+ }).optional();
8318
+ /**
8299
8319
  * How a migration sequences the cutover against the byte move.
8300
8320
  *
8301
8321
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8317,6 +8337,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8317
8337
  /** Shared input for planning and starting an orchestrated storage migration. */
8318
8338
  var StorageMigrationInputSchema = object({
8319
8339
  destinations: StorageMigrationDestinationsSchema,
8340
+ /** Omitted = each class's current default. */
8341
+ sources: StorageMigrationSourcesSchema,
8320
8342
  throttleMbps: number().min(1).max(1e3).optional(),
8321
8343
  /** Omitted = `blocking`, which stays the default. */
8322
8344
  mode: StorageMigrationModeSchema.optional()
@@ -8396,6 +8418,13 @@ var StorageMigrationMoveSchema = object({
8396
8418
  storageClass: StorageMigrationClassSchema,
8397
8419
  fromLocationId: string(),
8398
8420
  toLocationId: string(),
8421
+ /**
8422
+ * True when `from` was NOT the class default at plan time. The move still
8423
+ * copies bytes, but the default is left alone and the source is disabled
8424
+ * once the copy verifies. Absent on jobs planned before this field existed
8425
+ * — those jobs always repointed, which is `false`.
8426
+ */
8427
+ freezeSource: boolean().optional(),
8399
8428
  moverJobId: string().nullable(),
8400
8429
  state: RelocateJobStateSchema.nullable(),
8401
8430
  error: string().nullable(),
@@ -8409,6 +8438,7 @@ var StorageMigrationJobSchema = object({
8409
8438
  * can tell a seconds-long cutover from a thirty-hour one. */
8410
8439
  mode: StorageMigrationModeSchema,
8411
8440
  destinations: StorageMigrationDestinationsSchema,
8441
+ sources: StorageMigrationSourcesSchema,
8412
8442
  throttleMbps: number(),
8413
8443
  moves: array(StorageMigrationMoveSchema),
8414
8444
  pauseLeaseId: string().nullable(),
@@ -8434,6 +8464,7 @@ var StorageMigrationFindingSchema = object({
8434
8464
  });
8435
8465
  var StorageMigrationPlanSchema = object({
8436
8466
  destinations: StorageMigrationDestinationsSchema,
8467
+ sources: StorageMigrationSourcesSchema,
8437
8468
  /** The mode this plan was built for. A plan is only valid for its mode: the
8438
8469
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8439
8470
  * it. */
@@ -8441,7 +8472,8 @@ var StorageMigrationPlanSchema = object({
8441
8472
  moves: array(object({
8442
8473
  storageClass: StorageMigrationClassSchema,
8443
8474
  fromLocationId: string(),
8444
- toLocationId: string()
8475
+ toLocationId: string(),
8476
+ freezeSource: boolean().optional()
8445
8477
  })),
8446
8478
  findings: array(StorageMigrationFindingSchema)
8447
8479
  });
@@ -8619,10 +8651,51 @@ var LedgerWalkReportSchema = object({
8619
8651
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8620
8652
  var RelocatableMediaCountInputSchema = object({
8621
8653
  toLocationId: string().min(1),
8654
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8655
+ fromLocationId: string().optional(),
8622
8656
  /** Omitted = `move`. */
8623
8657
  mode: MediaRelocateModeSchema.optional()
8624
8658
  });
8625
8659
  /**
8660
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8661
+ * ghost ledger entries on frozen footage locations.
8662
+ *
8663
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8664
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8665
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8666
+ * with no operator-visible status.
8667
+ */
8668
+ var StorageCleanupPhaseSchema = _enum([
8669
+ "orphans",
8670
+ "debug-media",
8671
+ "ghost-ledger",
8672
+ "done",
8673
+ "failed",
8674
+ "cancelled"
8675
+ ]);
8676
+ var StorageCleanupInputSchema = object({
8677
+ /** Also walk motion stills / track filmstrips. Off by default. */
8678
+ includeDebugMedia: boolean().optional() });
8679
+ var StorageCleanupJobSchema = object({
8680
+ jobId: string(),
8681
+ phase: StorageCleanupPhaseSchema,
8682
+ includeDebugMedia: boolean(),
8683
+ orphansReclaimed: number().int().nonnegative(),
8684
+ orphanBytesReclaimed: number().int().nonnegative(),
8685
+ debugMediaReclaimed: number().int().nonnegative(),
8686
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8687
+ ghostsForgotten: number().int().nonnegative(),
8688
+ ghostBytesForgotten: number().int().nonnegative(),
8689
+ /** Short operator-facing line: current collection, pass, or location. */
8690
+ detail: string().nullable(),
8691
+ cancelRequested: boolean(),
8692
+ startedAt: number(),
8693
+ updatedAt: number(),
8694
+ finishedAt: number().nullable(),
8695
+ error: string().nullable()
8696
+ });
8697
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8698
+ /**
8626
8699
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8627
8700
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8628
8701
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8650,11 +8723,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8650
8723
  * The default location for a type uses `id === <type>:default` by
8651
8724
  * convention (the bare type ref like `'backups'` resolves to it).
8652
8725
  *
8653
- * `isSystem: true` marks a location as orchestrator-seeded and
8654
- * undeletable. The bootstrap-installed defaults (one per type) carry
8655
- * this flag; operator-added locations don't. Editing the config of
8656
- * a system location is allowed (path migration, provider swap) but
8657
- * deleting it is rejected at the cap level.
8726
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8727
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8728
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8729
+ * / last-enabled, not on this bit.
8658
8730
  */
8659
8731
  var StorageLocationSchema = object({
8660
8732
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12957,6 +13029,12 @@ method(object({
12957
13029
  }), _void(), {
12958
13030
  kind: "mutation",
12959
13031
  auth: "admin"
13032
+ }), method(object({
13033
+ from: string(),
13034
+ to: string()
13035
+ }), object({ moved: number() }), {
13036
+ kind: "mutation",
13037
+ auth: "admin"
12960
13038
  }), method(object({
12961
13039
  deviceId: number(),
12962
13040
  disabled: boolean()
@@ -18901,46 +18979,6 @@ var RecentTracksPageSchema = object({
18901
18979
  /** Cursor for the next page, or null when this page is the last. */
18902
18980
  nextCursor: string().nullable()
18903
18981
  });
18904
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18905
- var LIST_GROUPS_MAX_LIMIT = 100;
18906
- var AnalyticsGroupRecordSchema = object({
18907
- id: string(),
18908
- deviceId: number().int(),
18909
- openedAt: number().int(),
18910
- closedAt: number().int(),
18911
- timestamp: number().int(),
18912
- memberCount: number().int(),
18913
- memberTrackIds: array(string()).readonly(),
18914
- className: string(),
18915
- classes: array(string()).readonly(),
18916
- /** Relative event-media path, or null when the group has no picture yet. */
18917
- mediaUrl: string().nullable(),
18918
- singleton: boolean()
18919
- });
18920
- var AnalyticsGroupMemberSchema = object({
18921
- trackId: string(),
18922
- deviceId: number().int(),
18923
- className: string(),
18924
- firstSeen: number().int(),
18925
- lastSeen: number().int(),
18926
- mediaUrl: string().nullable()
18927
- });
18928
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18929
- var ListGroupsQueryInput = object({
18930
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18931
- deviceIds: array(number()),
18932
- /** Window lower bound on `closedAt` (inclusive). */
18933
- since: number().optional(),
18934
- /** Window upper bound on `openedAt` (inclusive). */
18935
- until: number().optional(),
18936
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18937
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18938
- cursor: string().optional()
18939
- });
18940
- var ListGroupsPageSchema = object({
18941
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18942
- nextCursor: string().nullable()
18943
- });
18944
18982
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18945
18983
  var KEY_EVENTS_MAX_LIMIT = 200;
18946
18984
  var KeyEventQueryInput = object({
@@ -19044,9 +19082,7 @@ var TrackCascadeCountsSchema = object({
19044
19082
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19045
19083
  plates: number().int(),
19046
19084
  /** Per-track CLIP search vectors removed (best-effort). */
19047
- embeddings: number().int(),
19048
- /** Group membership + group rows removed with their last member (best-effort). */
19049
- groups: number().int()
19085
+ embeddings: number().int()
19050
19086
  });
19051
19087
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19052
19088
  var DiskReconcileCountsSchema = object({
@@ -19216,6 +19252,47 @@ var RebuildStatusSchema = object({
19216
19252
  /** Present when the pass ended by throwing. */
19217
19253
  error: string().nullable()
19218
19254
  });
19255
+ /**
19256
+ * Acknowledgement that a debug-media reclaim STARTED.
19257
+ *
19258
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19259
+ * it runs detached and this returns immediately. Awaiting it is how the
19260
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19261
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19262
+ */
19263
+ var MediaReclaimStartResultSchema = object({
19264
+ started: boolean(),
19265
+ /** True when a pass was already running; the new request is ignored. */
19266
+ alreadyRunning: boolean()
19267
+ });
19268
+ var MediaReclaimInputSchema = object({
19269
+ mode: _enum(["report", "reclaim"]).default("report"),
19270
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19271
+ deviceIds: array(number().int()).min(1).optional(),
19272
+ restart: boolean().optional(),
19273
+ pageSize: number().int().min(50).max(5e3).optional(),
19274
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19275
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19276
+ maxBytesPerRun: number().int().min(1).optional(),
19277
+ budgetMinutes: number().int().min(1).max(720).optional(),
19278
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19279
+ graceMinutes: number().int().min(1).max(10080).optional()
19280
+ });
19281
+ var MediaReclaimStatusSchema = object({
19282
+ running: boolean(),
19283
+ mode: _enum(["report", "reclaim"]).nullable(),
19284
+ totalExamined: number(),
19285
+ totalEligible: number(),
19286
+ totalReclaimed: number(),
19287
+ totalBytesReclaimed: number(),
19288
+ totalRefused: number(),
19289
+ /** Device+scope windows finished in this pass. */
19290
+ devicesDone: number(),
19291
+ complete: boolean().nullable(),
19292
+ startedAtMs: number().nullable(),
19293
+ finishedAtMs: number().nullable(),
19294
+ error: string().nullable()
19295
+ });
19219
19296
  var ReplayFrameInputSchema = object({
19220
19297
  timestamp: number(),
19221
19298
  frame: PipelineRunResultBridge
@@ -19254,10 +19331,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19254
19331
  * stationary registry). Default false: the timeline lists passages,
19255
19332
  * not parking records (operator decision, 2026-08-15). */
19256
19333
  includeStationary: boolean().optional()
19257
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19258
- deviceId: number(),
19259
- groupId: string().min(1)
19260
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19334
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19261
19335
  kind: "mutation",
19262
19336
  auth: "admin"
19263
19337
  }), 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({
@@ -19357,6 +19431,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19357
19431
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19358
19432
  kind: "query",
19359
19433
  auth: "admin"
19434
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19435
+ kind: "mutation",
19436
+ auth: "admin"
19437
+ }), method(object({}), MediaReclaimStatusSchema, {
19438
+ kind: "query",
19439
+ auth: "admin"
19360
19440
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19361
19441
  kind: "query",
19362
19442
  auth: "admin"
@@ -21327,7 +21407,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21327
21407
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21328
21408
  kind: "mutation",
21329
21409
  auth: "admin"
21330
- });
21410
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21411
+ kind: "mutation",
21412
+ auth: "admin"
21413
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21414
+ kind: "mutation",
21415
+ auth: "admin"
21416
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21331
21417
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21332
21418
  providerId: string().min(1),
21333
21419
  displayName: string().min(1),
@@ -26705,6 +26791,33 @@ var RecordingRebalanceInputSchema = object({
26705
26791
  minMoveGb: number().min(0).optional()
26706
26792
  });
26707
26793
  /**
26794
+ * Operator-facing placement of one camera onto a recordings location.
26795
+ *
26796
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26797
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26798
+ * currently write — the plan, which may disagree with the pin when Auto.
26799
+ */
26800
+ var RecordingDevicePlacementSchema = object({
26801
+ deviceId: number().int(),
26802
+ profile: string(),
26803
+ locationId: string()
26804
+ });
26805
+ var RecordingDevicePinSchema = object({
26806
+ deviceId: number().int(),
26807
+ /** Recordings-class location this camera is pinned to. */
26808
+ locationId: string()
26809
+ });
26810
+ var RecordingPlacementViewSchema = object({
26811
+ assignments: array(RecordingDevicePlacementSchema),
26812
+ pins: array(RecordingDevicePinSchema),
26813
+ defaultLocations: record(string(), string())
26814
+ });
26815
+ var RecordingSetDevicePlacementInputSchema = object({
26816
+ deviceId: number().int(),
26817
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26818
+ locationId: string().nullable()
26819
+ });
26820
+ /**
26708
26821
  * Result of locating footage at a wall-clock instant for one device/profile.
26709
26822
  * `segment` carries the covering segment's window; `gap` reports the forward
26710
26823
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26930,6 +27043,12 @@ method(object({
26930
27043
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26931
27044
  kind: "mutation",
26932
27045
  auth: "admin"
27046
+ }), method(object({}), RecordingPlacementViewSchema, {
27047
+ kind: "query",
27048
+ auth: "admin"
27049
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
27050
+ kind: "mutation",
27051
+ auth: "admin"
26933
27052
  });
26934
27053
  /**
26935
27054
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30300,6 +30419,12 @@ Object.freeze({
30300
30419
  addonId: null,
30301
30420
  access: "delete"
30302
30421
  },
30422
+ "deviceManager.renameLocation": {
30423
+ capName: "device-manager",
30424
+ capScope: "system",
30425
+ addonId: null,
30426
+ access: "create"
30427
+ },
30303
30428
  "deviceManager.runDeviceAction": {
30304
30429
  capName: "device-manager",
30305
30430
  capScope: "system",
@@ -31992,19 +32117,19 @@ Object.freeze({
31992
32117
  addonId: null,
31993
32118
  access: "view"
31994
32119
  },
31995
- "pipelineAnalytics.getGroup": {
32120
+ "pipelineAnalytics.getKeyEvents": {
31996
32121
  capName: "pipeline-analytics",
31997
32122
  capScope: "device",
31998
32123
  addonId: null,
31999
32124
  access: "view"
32000
32125
  },
32001
- "pipelineAnalytics.getKeyEvents": {
32126
+ "pipelineAnalytics.getKeyEventsBatch": {
32002
32127
  capName: "pipeline-analytics",
32003
32128
  capScope: "device",
32004
32129
  addonId: null,
32005
32130
  access: "view"
32006
32131
  },
32007
- "pipelineAnalytics.getKeyEventsBatch": {
32132
+ "pipelineAnalytics.getMediaReclaimStatus": {
32008
32133
  capName: "pipeline-analytics",
32009
32134
  capScope: "device",
32010
32135
  addonId: null,
@@ -32094,12 +32219,6 @@ Object.freeze({
32094
32219
  addonId: null,
32095
32220
  access: "view"
32096
32221
  },
32097
- "pipelineAnalytics.listGroups": {
32098
- capName: "pipeline-analytics",
32099
- capScope: "device",
32100
- addonId: null,
32101
- access: "view"
32102
- },
32103
32222
  "pipelineAnalytics.listOpsLog": {
32104
32223
  capName: "pipeline-analytics",
32105
32224
  capScope: "device",
@@ -32184,6 +32303,12 @@ Object.freeze({
32184
32303
  addonId: null,
32185
32304
  access: "create"
32186
32305
  },
32306
+ "pipelineAnalytics.reclaimDebugMedia": {
32307
+ capName: "pipeline-analytics",
32308
+ capScope: "device",
32309
+ addonId: null,
32310
+ access: "create"
32311
+ },
32187
32312
  "pipelineAnalytics.reconcileFromDisk": {
32188
32313
  capName: "pipeline-analytics",
32189
32314
  capScope: "device",
@@ -33108,6 +33233,12 @@ Object.freeze({
33108
33233
  addonId: null,
33109
33234
  access: "view"
33110
33235
  },
33236
+ "recording.getPlacement": {
33237
+ capName: "recording",
33238
+ capScope: "system",
33239
+ addonId: null,
33240
+ access: "view"
33241
+ },
33111
33242
  "recording.getPlaybackManifest": {
33112
33243
  capName: "recording",
33113
33244
  capScope: "system",
@@ -33234,6 +33365,12 @@ Object.freeze({
33234
33365
  addonId: null,
33235
33366
  access: "create"
33236
33367
  },
33368
+ "recording.setDevicePlacement": {
33369
+ capName: "recording",
33370
+ capScope: "system",
33371
+ addonId: null,
33372
+ access: "create"
33373
+ },
33237
33374
  "recording.startStorageMigrationMove": {
33238
33375
  capName: "recording",
33239
33376
  capScope: "system",
@@ -33678,12 +33815,36 @@ Object.freeze({
33678
33815
  addonId: null,
33679
33816
  access: "create"
33680
33817
  },
33818
+ "storageMigration.cleanupCancel": {
33819
+ capName: "storage-migration",
33820
+ capScope: "system",
33821
+ addonId: null,
33822
+ access: "create"
33823
+ },
33824
+ "storageMigration.cleanupStart": {
33825
+ capName: "storage-migration",
33826
+ capScope: "system",
33827
+ addonId: null,
33828
+ access: "create"
33829
+ },
33830
+ "storageMigration.cleanupStatus": {
33831
+ capName: "storage-migration",
33832
+ capScope: "system",
33833
+ addonId: null,
33834
+ access: "view"
33835
+ },
33681
33836
  "storageMigration.drain": {
33682
33837
  capName: "storage-migration",
33683
33838
  capScope: "system",
33684
33839
  addonId: null,
33685
33840
  access: "create"
33686
33841
  },
33842
+ "storageMigration.history": {
33843
+ capName: "storage-migration",
33844
+ capScope: "system",
33845
+ addonId: null,
33846
+ access: "view"
33847
+ },
33687
33848
  "storageMigration.movers": {
33688
33849
  capName: "storage-migration",
33689
33850
  capScope: "system",
@@ -35680,11 +35841,6 @@ Object.freeze({
35680
35841
  form: "single",
35681
35842
  optional: true
35682
35843
  }],
35683
- "pipelineAnalytics.getGroup": [{
35684
- name: "deviceId",
35685
- form: "single",
35686
- optional: false
35687
- }],
35688
35844
  "pipelineAnalytics.getKeyEvents": [{
35689
35845
  name: "deviceId",
35690
35846
  form: "single",
@@ -35750,11 +35906,6 @@ Object.freeze({
35750
35906
  form: "single",
35751
35907
  optional: false
35752
35908
  }],
35753
- "pipelineAnalytics.listGroups": [{
35754
- name: "deviceIds",
35755
- form: "array",
35756
- optional: false
35757
- }],
35758
35909
  "pipelineAnalytics.listOpsLog": [{
35759
35910
  name: "deviceId",
35760
35911
  form: "single",
@@ -35800,6 +35951,11 @@ Object.freeze({
35800
35951
  form: "single",
35801
35952
  optional: true
35802
35953
  }],
35954
+ "pipelineAnalytics.reclaimDebugMedia": [{
35955
+ name: "deviceIds",
35956
+ form: "array",
35957
+ optional: true
35958
+ }],
35803
35959
  "pipelineAnalytics.reconcileFromDisk": [{
35804
35960
  name: "deviceId",
35805
35961
  form: "single",
@@ -36165,6 +36321,11 @@ Object.freeze({
36165
36321
  form: "single",
36166
36322
  optional: false
36167
36323
  }],
36324
+ "recording.setDevicePlacement": [{
36325
+ name: "deviceId",
36326
+ form: "single",
36327
+ optional: false
36328
+ }],
36168
36329
  "recording.startStorageMigrationMove": [{
36169
36330
  name: "deviceId",
36170
36331
  form: "single",
package/dist/addon.mjs CHANGED
@@ -8202,6 +8202,13 @@ var MediaRelocateModeSchema = _enum([
8202
8202
  ]);
8203
8203
  var RelocateMediaInputSchema = object({
8204
8204
  toLocationId: string(),
8205
+ /**
8206
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8207
+ * every row that is not already on `toLocationId` (the historical
8208
+ * behaviour). A named source is what a from→to migration needs: without it
8209
+ * "move events off disk 2" also emptied disk 1.
8210
+ */
8211
+ fromLocationId: string().optional(),
8205
8212
  throttleMbps: number().min(1).max(1e3).optional(),
8206
8213
  /** Omitted = `move`, the pre-existing behaviour. */
8207
8214
  mode: MediaRelocateModeSchema.optional()
@@ -8269,6 +8276,19 @@ var StorageMigrationDestinationsSchema = object({
8269
8276
  galleryMedia: string().min(1).optional()
8270
8277
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8271
8278
  /**
8279
+ * Optional named source per class. Omitted = the class's current default
8280
+ * (the historical behaviour). A named source that is NOT the default is a
8281
+ * drain of that disk: bytes move, the default stays, and the source is
8282
+ * disabled when the move finishes.
8283
+ */
8284
+ var StorageMigrationSourcesSchema = object({
8285
+ recordings: string().min(1).optional(),
8286
+ recordingsLow: string().min(1).optional(),
8287
+ eventMedia: string().min(1).optional(),
8288
+ backups: string().min(1).optional(),
8289
+ galleryMedia: string().min(1).optional()
8290
+ }).optional();
8291
+ /**
8272
8292
  * How a migration sequences the cutover against the byte move.
8273
8293
  *
8274
8294
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8290,6 +8310,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8290
8310
  /** Shared input for planning and starting an orchestrated storage migration. */
8291
8311
  var StorageMigrationInputSchema = object({
8292
8312
  destinations: StorageMigrationDestinationsSchema,
8313
+ /** Omitted = each class's current default. */
8314
+ sources: StorageMigrationSourcesSchema,
8293
8315
  throttleMbps: number().min(1).max(1e3).optional(),
8294
8316
  /** Omitted = `blocking`, which stays the default. */
8295
8317
  mode: StorageMigrationModeSchema.optional()
@@ -8369,6 +8391,13 @@ var StorageMigrationMoveSchema = object({
8369
8391
  storageClass: StorageMigrationClassSchema,
8370
8392
  fromLocationId: string(),
8371
8393
  toLocationId: string(),
8394
+ /**
8395
+ * True when `from` was NOT the class default at plan time. The move still
8396
+ * copies bytes, but the default is left alone and the source is disabled
8397
+ * once the copy verifies. Absent on jobs planned before this field existed
8398
+ * — those jobs always repointed, which is `false`.
8399
+ */
8400
+ freezeSource: boolean().optional(),
8372
8401
  moverJobId: string().nullable(),
8373
8402
  state: RelocateJobStateSchema.nullable(),
8374
8403
  error: string().nullable(),
@@ -8382,6 +8411,7 @@ var StorageMigrationJobSchema = object({
8382
8411
  * can tell a seconds-long cutover from a thirty-hour one. */
8383
8412
  mode: StorageMigrationModeSchema,
8384
8413
  destinations: StorageMigrationDestinationsSchema,
8414
+ sources: StorageMigrationSourcesSchema,
8385
8415
  throttleMbps: number(),
8386
8416
  moves: array(StorageMigrationMoveSchema),
8387
8417
  pauseLeaseId: string().nullable(),
@@ -8407,6 +8437,7 @@ var StorageMigrationFindingSchema = object({
8407
8437
  });
8408
8438
  var StorageMigrationPlanSchema = object({
8409
8439
  destinations: StorageMigrationDestinationsSchema,
8440
+ sources: StorageMigrationSourcesSchema,
8410
8441
  /** The mode this plan was built for. A plan is only valid for its mode: the
8411
8442
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8412
8443
  * it. */
@@ -8414,7 +8445,8 @@ var StorageMigrationPlanSchema = object({
8414
8445
  moves: array(object({
8415
8446
  storageClass: StorageMigrationClassSchema,
8416
8447
  fromLocationId: string(),
8417
- toLocationId: string()
8448
+ toLocationId: string(),
8449
+ freezeSource: boolean().optional()
8418
8450
  })),
8419
8451
  findings: array(StorageMigrationFindingSchema)
8420
8452
  });
@@ -8592,10 +8624,51 @@ var LedgerWalkReportSchema = object({
8592
8624
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8593
8625
  var RelocatableMediaCountInputSchema = object({
8594
8626
  toLocationId: string().min(1),
8627
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8628
+ fromLocationId: string().optional(),
8595
8629
  /** Omitted = `move`. */
8596
8630
  mode: MediaRelocateModeSchema.optional()
8597
8631
  });
8598
8632
  /**
8633
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8634
+ * ghost ledger entries on frozen footage locations.
8635
+ *
8636
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8637
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8638
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8639
+ * with no operator-visible status.
8640
+ */
8641
+ var StorageCleanupPhaseSchema = _enum([
8642
+ "orphans",
8643
+ "debug-media",
8644
+ "ghost-ledger",
8645
+ "done",
8646
+ "failed",
8647
+ "cancelled"
8648
+ ]);
8649
+ var StorageCleanupInputSchema = object({
8650
+ /** Also walk motion stills / track filmstrips. Off by default. */
8651
+ includeDebugMedia: boolean().optional() });
8652
+ var StorageCleanupJobSchema = object({
8653
+ jobId: string(),
8654
+ phase: StorageCleanupPhaseSchema,
8655
+ includeDebugMedia: boolean(),
8656
+ orphansReclaimed: number().int().nonnegative(),
8657
+ orphanBytesReclaimed: number().int().nonnegative(),
8658
+ debugMediaReclaimed: number().int().nonnegative(),
8659
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8660
+ ghostsForgotten: number().int().nonnegative(),
8661
+ ghostBytesForgotten: number().int().nonnegative(),
8662
+ /** Short operator-facing line: current collection, pass, or location. */
8663
+ detail: string().nullable(),
8664
+ cancelRequested: boolean(),
8665
+ startedAt: number(),
8666
+ updatedAt: number(),
8667
+ finishedAt: number().nullable(),
8668
+ error: string().nullable()
8669
+ });
8670
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8671
+ /**
8599
8672
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8600
8673
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8601
8674
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8623,11 +8696,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8623
8696
  * The default location for a type uses `id === <type>:default` by
8624
8697
  * convention (the bare type ref like `'backups'` resolves to it).
8625
8698
  *
8626
- * `isSystem: true` marks a location as orchestrator-seeded and
8627
- * undeletable. The bootstrap-installed defaults (one per type) carry
8628
- * this flag; operator-added locations don't. Editing the config of
8629
- * a system location is allowed (path migration, provider swap) but
8630
- * deleting it is rejected at the cap level.
8699
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8700
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8701
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8702
+ * / last-enabled, not on this bit.
8631
8703
  */
8632
8704
  var StorageLocationSchema = object({
8633
8705
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12930,6 +13002,12 @@ method(object({
12930
13002
  }), _void(), {
12931
13003
  kind: "mutation",
12932
13004
  auth: "admin"
13005
+ }), method(object({
13006
+ from: string(),
13007
+ to: string()
13008
+ }), object({ moved: number() }), {
13009
+ kind: "mutation",
13010
+ auth: "admin"
12933
13011
  }), method(object({
12934
13012
  deviceId: number(),
12935
13013
  disabled: boolean()
@@ -18874,46 +18952,6 @@ var RecentTracksPageSchema = object({
18874
18952
  /** Cursor for the next page, or null when this page is the last. */
18875
18953
  nextCursor: string().nullable()
18876
18954
  });
18877
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18878
- var LIST_GROUPS_MAX_LIMIT = 100;
18879
- var AnalyticsGroupRecordSchema = object({
18880
- id: string(),
18881
- deviceId: number().int(),
18882
- openedAt: number().int(),
18883
- closedAt: number().int(),
18884
- timestamp: number().int(),
18885
- memberCount: number().int(),
18886
- memberTrackIds: array(string()).readonly(),
18887
- className: string(),
18888
- classes: array(string()).readonly(),
18889
- /** Relative event-media path, or null when the group has no picture yet. */
18890
- mediaUrl: string().nullable(),
18891
- singleton: boolean()
18892
- });
18893
- var AnalyticsGroupMemberSchema = object({
18894
- trackId: string(),
18895
- deviceId: number().int(),
18896
- className: string(),
18897
- firstSeen: number().int(),
18898
- lastSeen: number().int(),
18899
- mediaUrl: string().nullable()
18900
- });
18901
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18902
- var ListGroupsQueryInput = object({
18903
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18904
- deviceIds: array(number()),
18905
- /** Window lower bound on `closedAt` (inclusive). */
18906
- since: number().optional(),
18907
- /** Window upper bound on `openedAt` (inclusive). */
18908
- until: number().optional(),
18909
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18910
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18911
- cursor: string().optional()
18912
- });
18913
- var ListGroupsPageSchema = object({
18914
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18915
- nextCursor: string().nullable()
18916
- });
18917
18955
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18918
18956
  var KEY_EVENTS_MAX_LIMIT = 200;
18919
18957
  var KeyEventQueryInput = object({
@@ -19017,9 +19055,7 @@ var TrackCascadeCountsSchema = object({
19017
19055
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19018
19056
  plates: number().int(),
19019
19057
  /** Per-track CLIP search vectors removed (best-effort). */
19020
- embeddings: number().int(),
19021
- /** Group membership + group rows removed with their last member (best-effort). */
19022
- groups: number().int()
19058
+ embeddings: number().int()
19023
19059
  });
19024
19060
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19025
19061
  var DiskReconcileCountsSchema = object({
@@ -19189,6 +19225,47 @@ var RebuildStatusSchema = object({
19189
19225
  /** Present when the pass ended by throwing. */
19190
19226
  error: string().nullable()
19191
19227
  });
19228
+ /**
19229
+ * Acknowledgement that a debug-media reclaim STARTED.
19230
+ *
19231
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19232
+ * it runs detached and this returns immediately. Awaiting it is how the
19233
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19234
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19235
+ */
19236
+ var MediaReclaimStartResultSchema = object({
19237
+ started: boolean(),
19238
+ /** True when a pass was already running; the new request is ignored. */
19239
+ alreadyRunning: boolean()
19240
+ });
19241
+ var MediaReclaimInputSchema = object({
19242
+ mode: _enum(["report", "reclaim"]).default("report"),
19243
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19244
+ deviceIds: array(number().int()).min(1).optional(),
19245
+ restart: boolean().optional(),
19246
+ pageSize: number().int().min(50).max(5e3).optional(),
19247
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19248
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19249
+ maxBytesPerRun: number().int().min(1).optional(),
19250
+ budgetMinutes: number().int().min(1).max(720).optional(),
19251
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19252
+ graceMinutes: number().int().min(1).max(10080).optional()
19253
+ });
19254
+ var MediaReclaimStatusSchema = object({
19255
+ running: boolean(),
19256
+ mode: _enum(["report", "reclaim"]).nullable(),
19257
+ totalExamined: number(),
19258
+ totalEligible: number(),
19259
+ totalReclaimed: number(),
19260
+ totalBytesReclaimed: number(),
19261
+ totalRefused: number(),
19262
+ /** Device+scope windows finished in this pass. */
19263
+ devicesDone: number(),
19264
+ complete: boolean().nullable(),
19265
+ startedAtMs: number().nullable(),
19266
+ finishedAtMs: number().nullable(),
19267
+ error: string().nullable()
19268
+ });
19192
19269
  var ReplayFrameInputSchema = object({
19193
19270
  timestamp: number(),
19194
19271
  frame: PipelineRunResultBridge
@@ -19227,10 +19304,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19227
19304
  * stationary registry). Default false: the timeline lists passages,
19228
19305
  * not parking records (operator decision, 2026-08-15). */
19229
19306
  includeStationary: boolean().optional()
19230
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19231
- deviceId: number(),
19232
- groupId: string().min(1)
19233
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19307
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19234
19308
  kind: "mutation",
19235
19309
  auth: "admin"
19236
19310
  }), 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({
@@ -19330,6 +19404,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19330
19404
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19331
19405
  kind: "query",
19332
19406
  auth: "admin"
19407
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19408
+ kind: "mutation",
19409
+ auth: "admin"
19410
+ }), method(object({}), MediaReclaimStatusSchema, {
19411
+ kind: "query",
19412
+ auth: "admin"
19333
19413
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19334
19414
  kind: "query",
19335
19415
  auth: "admin"
@@ -21300,7 +21380,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21300
21380
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21301
21381
  kind: "mutation",
21302
21382
  auth: "admin"
21303
- });
21383
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21384
+ kind: "mutation",
21385
+ auth: "admin"
21386
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21387
+ kind: "mutation",
21388
+ auth: "admin"
21389
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21304
21390
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21305
21391
  providerId: string().min(1),
21306
21392
  displayName: string().min(1),
@@ -26678,6 +26764,33 @@ var RecordingRebalanceInputSchema = object({
26678
26764
  minMoveGb: number().min(0).optional()
26679
26765
  });
26680
26766
  /**
26767
+ * Operator-facing placement of one camera onto a recordings location.
26768
+ *
26769
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26770
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26771
+ * currently write — the plan, which may disagree with the pin when Auto.
26772
+ */
26773
+ var RecordingDevicePlacementSchema = object({
26774
+ deviceId: number().int(),
26775
+ profile: string(),
26776
+ locationId: string()
26777
+ });
26778
+ var RecordingDevicePinSchema = object({
26779
+ deviceId: number().int(),
26780
+ /** Recordings-class location this camera is pinned to. */
26781
+ locationId: string()
26782
+ });
26783
+ var RecordingPlacementViewSchema = object({
26784
+ assignments: array(RecordingDevicePlacementSchema),
26785
+ pins: array(RecordingDevicePinSchema),
26786
+ defaultLocations: record(string(), string())
26787
+ });
26788
+ var RecordingSetDevicePlacementInputSchema = object({
26789
+ deviceId: number().int(),
26790
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26791
+ locationId: string().nullable()
26792
+ });
26793
+ /**
26681
26794
  * Result of locating footage at a wall-clock instant for one device/profile.
26682
26795
  * `segment` carries the covering segment's window; `gap` reports the forward
26683
26796
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26903,6 +27016,12 @@ method(object({
26903
27016
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26904
27017
  kind: "mutation",
26905
27018
  auth: "admin"
27019
+ }), method(object({}), RecordingPlacementViewSchema, {
27020
+ kind: "query",
27021
+ auth: "admin"
27022
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
27023
+ kind: "mutation",
27024
+ auth: "admin"
26906
27025
  });
26907
27026
  /**
26908
27027
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30273,6 +30392,12 @@ Object.freeze({
30273
30392
  addonId: null,
30274
30393
  access: "delete"
30275
30394
  },
30395
+ "deviceManager.renameLocation": {
30396
+ capName: "device-manager",
30397
+ capScope: "system",
30398
+ addonId: null,
30399
+ access: "create"
30400
+ },
30276
30401
  "deviceManager.runDeviceAction": {
30277
30402
  capName: "device-manager",
30278
30403
  capScope: "system",
@@ -31965,19 +32090,19 @@ Object.freeze({
31965
32090
  addonId: null,
31966
32091
  access: "view"
31967
32092
  },
31968
- "pipelineAnalytics.getGroup": {
32093
+ "pipelineAnalytics.getKeyEvents": {
31969
32094
  capName: "pipeline-analytics",
31970
32095
  capScope: "device",
31971
32096
  addonId: null,
31972
32097
  access: "view"
31973
32098
  },
31974
- "pipelineAnalytics.getKeyEvents": {
32099
+ "pipelineAnalytics.getKeyEventsBatch": {
31975
32100
  capName: "pipeline-analytics",
31976
32101
  capScope: "device",
31977
32102
  addonId: null,
31978
32103
  access: "view"
31979
32104
  },
31980
- "pipelineAnalytics.getKeyEventsBatch": {
32105
+ "pipelineAnalytics.getMediaReclaimStatus": {
31981
32106
  capName: "pipeline-analytics",
31982
32107
  capScope: "device",
31983
32108
  addonId: null,
@@ -32067,12 +32192,6 @@ Object.freeze({
32067
32192
  addonId: null,
32068
32193
  access: "view"
32069
32194
  },
32070
- "pipelineAnalytics.listGroups": {
32071
- capName: "pipeline-analytics",
32072
- capScope: "device",
32073
- addonId: null,
32074
- access: "view"
32075
- },
32076
32195
  "pipelineAnalytics.listOpsLog": {
32077
32196
  capName: "pipeline-analytics",
32078
32197
  capScope: "device",
@@ -32157,6 +32276,12 @@ Object.freeze({
32157
32276
  addonId: null,
32158
32277
  access: "create"
32159
32278
  },
32279
+ "pipelineAnalytics.reclaimDebugMedia": {
32280
+ capName: "pipeline-analytics",
32281
+ capScope: "device",
32282
+ addonId: null,
32283
+ access: "create"
32284
+ },
32160
32285
  "pipelineAnalytics.reconcileFromDisk": {
32161
32286
  capName: "pipeline-analytics",
32162
32287
  capScope: "device",
@@ -33081,6 +33206,12 @@ Object.freeze({
33081
33206
  addonId: null,
33082
33207
  access: "view"
33083
33208
  },
33209
+ "recording.getPlacement": {
33210
+ capName: "recording",
33211
+ capScope: "system",
33212
+ addonId: null,
33213
+ access: "view"
33214
+ },
33084
33215
  "recording.getPlaybackManifest": {
33085
33216
  capName: "recording",
33086
33217
  capScope: "system",
@@ -33207,6 +33338,12 @@ Object.freeze({
33207
33338
  addonId: null,
33208
33339
  access: "create"
33209
33340
  },
33341
+ "recording.setDevicePlacement": {
33342
+ capName: "recording",
33343
+ capScope: "system",
33344
+ addonId: null,
33345
+ access: "create"
33346
+ },
33210
33347
  "recording.startStorageMigrationMove": {
33211
33348
  capName: "recording",
33212
33349
  capScope: "system",
@@ -33651,12 +33788,36 @@ Object.freeze({
33651
33788
  addonId: null,
33652
33789
  access: "create"
33653
33790
  },
33791
+ "storageMigration.cleanupCancel": {
33792
+ capName: "storage-migration",
33793
+ capScope: "system",
33794
+ addonId: null,
33795
+ access: "create"
33796
+ },
33797
+ "storageMigration.cleanupStart": {
33798
+ capName: "storage-migration",
33799
+ capScope: "system",
33800
+ addonId: null,
33801
+ access: "create"
33802
+ },
33803
+ "storageMigration.cleanupStatus": {
33804
+ capName: "storage-migration",
33805
+ capScope: "system",
33806
+ addonId: null,
33807
+ access: "view"
33808
+ },
33654
33809
  "storageMigration.drain": {
33655
33810
  capName: "storage-migration",
33656
33811
  capScope: "system",
33657
33812
  addonId: null,
33658
33813
  access: "create"
33659
33814
  },
33815
+ "storageMigration.history": {
33816
+ capName: "storage-migration",
33817
+ capScope: "system",
33818
+ addonId: null,
33819
+ access: "view"
33820
+ },
33660
33821
  "storageMigration.movers": {
33661
33822
  capName: "storage-migration",
33662
33823
  capScope: "system",
@@ -35653,11 +35814,6 @@ Object.freeze({
35653
35814
  form: "single",
35654
35815
  optional: true
35655
35816
  }],
35656
- "pipelineAnalytics.getGroup": [{
35657
- name: "deviceId",
35658
- form: "single",
35659
- optional: false
35660
- }],
35661
35817
  "pipelineAnalytics.getKeyEvents": [{
35662
35818
  name: "deviceId",
35663
35819
  form: "single",
@@ -35723,11 +35879,6 @@ Object.freeze({
35723
35879
  form: "single",
35724
35880
  optional: false
35725
35881
  }],
35726
- "pipelineAnalytics.listGroups": [{
35727
- name: "deviceIds",
35728
- form: "array",
35729
- optional: false
35730
- }],
35731
35882
  "pipelineAnalytics.listOpsLog": [{
35732
35883
  name: "deviceId",
35733
35884
  form: "single",
@@ -35773,6 +35924,11 @@ Object.freeze({
35773
35924
  form: "single",
35774
35925
  optional: true
35775
35926
  }],
35927
+ "pipelineAnalytics.reclaimDebugMedia": [{
35928
+ name: "deviceIds",
35929
+ form: "array",
35930
+ optional: true
35931
+ }],
35776
35932
  "pipelineAnalytics.reconcileFromDisk": [{
35777
35933
  name: "deviceId",
35778
35934
  form: "single",
@@ -36138,6 +36294,11 @@ Object.freeze({
36138
36294
  form: "single",
36139
36295
  optional: false
36140
36296
  }],
36297
+ "recording.setDevicePlacement": [{
36298
+ name: "deviceId",
36299
+ form: "single",
36300
+ optional: false
36301
+ }],
36141
36302
  "recording.startStorageMigrationMove": [{
36142
36303
  name: "deviceId",
36143
36304
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.53",
3
+ "version": "1.2.54",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",