@camstack/addon-smtp-nodemailer 1.2.48 → 1.2.49

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.
@@ -8117,6 +8117,13 @@ var MediaRelocateModeSchema = _enum([
8117
8117
  ]);
8118
8118
  var RelocateMediaInputSchema = object({
8119
8119
  toLocationId: string(),
8120
+ /**
8121
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8122
+ * every row that is not already on `toLocationId` (the historical
8123
+ * behaviour). A named source is what a from→to migration needs: without it
8124
+ * "move events off disk 2" also emptied disk 1.
8125
+ */
8126
+ fromLocationId: string().optional(),
8120
8127
  throttleMbps: number().min(1).max(1e3).optional(),
8121
8128
  /** Omitted = `move`, the pre-existing behaviour. */
8122
8129
  mode: MediaRelocateModeSchema.optional()
@@ -8184,6 +8191,19 @@ var StorageMigrationDestinationsSchema = object({
8184
8191
  galleryMedia: string().min(1).optional()
8185
8192
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8186
8193
  /**
8194
+ * Optional named source per class. Omitted = the class's current default
8195
+ * (the historical behaviour). A named source that is NOT the default is a
8196
+ * drain of that disk: bytes move, the default stays, and the source is
8197
+ * disabled when the move finishes.
8198
+ */
8199
+ var StorageMigrationSourcesSchema = object({
8200
+ recordings: string().min(1).optional(),
8201
+ recordingsLow: string().min(1).optional(),
8202
+ eventMedia: string().min(1).optional(),
8203
+ backups: string().min(1).optional(),
8204
+ galleryMedia: string().min(1).optional()
8205
+ }).optional();
8206
+ /**
8187
8207
  * How a migration sequences the cutover against the byte move.
8188
8208
  *
8189
8209
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8205,6 +8225,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8205
8225
  /** Shared input for planning and starting an orchestrated storage migration. */
8206
8226
  var StorageMigrationInputSchema = object({
8207
8227
  destinations: StorageMigrationDestinationsSchema,
8228
+ /** Omitted = each class's current default. */
8229
+ sources: StorageMigrationSourcesSchema,
8208
8230
  throttleMbps: number().min(1).max(1e3).optional(),
8209
8231
  /** Omitted = `blocking`, which stays the default. */
8210
8232
  mode: StorageMigrationModeSchema.optional()
@@ -8284,6 +8306,13 @@ var StorageMigrationMoveSchema = object({
8284
8306
  storageClass: StorageMigrationClassSchema,
8285
8307
  fromLocationId: string(),
8286
8308
  toLocationId: string(),
8309
+ /**
8310
+ * True when `from` was NOT the class default at plan time. The move still
8311
+ * copies bytes, but the default is left alone and the source is disabled
8312
+ * once the copy verifies. Absent on jobs planned before this field existed
8313
+ * — those jobs always repointed, which is `false`.
8314
+ */
8315
+ freezeSource: boolean().optional(),
8287
8316
  moverJobId: string().nullable(),
8288
8317
  state: RelocateJobStateSchema.nullable(),
8289
8318
  error: string().nullable(),
@@ -8297,6 +8326,7 @@ var StorageMigrationJobSchema = object({
8297
8326
  * can tell a seconds-long cutover from a thirty-hour one. */
8298
8327
  mode: StorageMigrationModeSchema,
8299
8328
  destinations: StorageMigrationDestinationsSchema,
8329
+ sources: StorageMigrationSourcesSchema,
8300
8330
  throttleMbps: number(),
8301
8331
  moves: array(StorageMigrationMoveSchema),
8302
8332
  pauseLeaseId: string().nullable(),
@@ -8322,6 +8352,7 @@ var StorageMigrationFindingSchema = object({
8322
8352
  });
8323
8353
  var StorageMigrationPlanSchema = object({
8324
8354
  destinations: StorageMigrationDestinationsSchema,
8355
+ sources: StorageMigrationSourcesSchema,
8325
8356
  /** The mode this plan was built for. A plan is only valid for its mode: the
8326
8357
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8327
8358
  * it. */
@@ -8329,7 +8360,8 @@ var StorageMigrationPlanSchema = object({
8329
8360
  moves: array(object({
8330
8361
  storageClass: StorageMigrationClassSchema,
8331
8362
  fromLocationId: string(),
8332
- toLocationId: string()
8363
+ toLocationId: string(),
8364
+ freezeSource: boolean().optional()
8333
8365
  })),
8334
8366
  findings: array(StorageMigrationFindingSchema)
8335
8367
  });
@@ -8507,10 +8539,51 @@ var LedgerWalkReportSchema = object({
8507
8539
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8508
8540
  var RelocatableMediaCountInputSchema = object({
8509
8541
  toLocationId: string().min(1),
8542
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8543
+ fromLocationId: string().optional(),
8510
8544
  /** Omitted = `move`. */
8511
8545
  mode: MediaRelocateModeSchema.optional()
8512
8546
  });
8513
8547
  /**
8548
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8549
+ * ghost ledger entries on frozen footage locations.
8550
+ *
8551
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8552
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8553
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8554
+ * with no operator-visible status.
8555
+ */
8556
+ var StorageCleanupPhaseSchema = _enum([
8557
+ "orphans",
8558
+ "debug-media",
8559
+ "ghost-ledger",
8560
+ "done",
8561
+ "failed",
8562
+ "cancelled"
8563
+ ]);
8564
+ var StorageCleanupInputSchema = object({
8565
+ /** Also walk motion stills / track filmstrips. Off by default. */
8566
+ includeDebugMedia: boolean().optional() });
8567
+ var StorageCleanupJobSchema = object({
8568
+ jobId: string(),
8569
+ phase: StorageCleanupPhaseSchema,
8570
+ includeDebugMedia: boolean(),
8571
+ orphansReclaimed: number().int().nonnegative(),
8572
+ orphanBytesReclaimed: number().int().nonnegative(),
8573
+ debugMediaReclaimed: number().int().nonnegative(),
8574
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8575
+ ghostsForgotten: number().int().nonnegative(),
8576
+ ghostBytesForgotten: number().int().nonnegative(),
8577
+ /** Short operator-facing line: current collection, pass, or location. */
8578
+ detail: string().nullable(),
8579
+ cancelRequested: boolean(),
8580
+ startedAt: number(),
8581
+ updatedAt: number(),
8582
+ finishedAt: number().nullable(),
8583
+ error: string().nullable()
8584
+ });
8585
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8586
+ /**
8514
8587
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8515
8588
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8516
8589
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8538,11 +8611,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8538
8611
  * The default location for a type uses `id === <type>:default` by
8539
8612
  * convention (the bare type ref like `'backups'` resolves to it).
8540
8613
  *
8541
- * `isSystem: true` marks a location as orchestrator-seeded and
8542
- * undeletable. The bootstrap-installed defaults (one per type) carry
8543
- * this flag; operator-added locations don't. Editing the config of
8544
- * a system location is allowed (path migration, provider swap) but
8545
- * deleting it is rejected at the cap level.
8614
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8615
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8616
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8617
+ * / last-enabled, not on this bit.
8546
8618
  */
8547
8619
  var StorageLocationSchema = object({
8548
8620
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12804,6 +12876,12 @@ method(object({
12804
12876
  }), _void(), {
12805
12877
  kind: "mutation",
12806
12878
  auth: "admin"
12879
+ }), method(object({
12880
+ from: string(),
12881
+ to: string()
12882
+ }), object({ moved: number() }), {
12883
+ kind: "mutation",
12884
+ auth: "admin"
12807
12885
  }), method(object({
12808
12886
  deviceId: number(),
12809
12887
  disabled: boolean()
@@ -18734,46 +18812,6 @@ var RecentTracksPageSchema = object({
18734
18812
  /** Cursor for the next page, or null when this page is the last. */
18735
18813
  nextCursor: string().nullable()
18736
18814
  });
18737
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18738
- var LIST_GROUPS_MAX_LIMIT = 100;
18739
- var AnalyticsGroupRecordSchema = object({
18740
- id: string(),
18741
- deviceId: number().int(),
18742
- openedAt: number().int(),
18743
- closedAt: number().int(),
18744
- timestamp: number().int(),
18745
- memberCount: number().int(),
18746
- memberTrackIds: array(string()).readonly(),
18747
- className: string(),
18748
- classes: array(string()).readonly(),
18749
- /** Relative event-media path, or null when the group has no picture yet. */
18750
- mediaUrl: string().nullable(),
18751
- singleton: boolean()
18752
- });
18753
- var AnalyticsGroupMemberSchema = object({
18754
- trackId: string(),
18755
- deviceId: number().int(),
18756
- className: string(),
18757
- firstSeen: number().int(),
18758
- lastSeen: number().int(),
18759
- mediaUrl: string().nullable()
18760
- });
18761
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18762
- var ListGroupsQueryInput = object({
18763
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18764
- deviceIds: array(number()),
18765
- /** Window lower bound on `closedAt` (inclusive). */
18766
- since: number().optional(),
18767
- /** Window upper bound on `openedAt` (inclusive). */
18768
- until: number().optional(),
18769
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18770
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18771
- cursor: string().optional()
18772
- });
18773
- var ListGroupsPageSchema = object({
18774
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18775
- nextCursor: string().nullable()
18776
- });
18777
18815
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18778
18816
  var KEY_EVENTS_MAX_LIMIT = 200;
18779
18817
  var KeyEventQueryInput = object({
@@ -18877,9 +18915,7 @@ var TrackCascadeCountsSchema = object({
18877
18915
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
18878
18916
  plates: number().int(),
18879
18917
  /** Per-track CLIP search vectors removed (best-effort). */
18880
- embeddings: number().int(),
18881
- /** Group membership + group rows removed with their last member (best-effort). */
18882
- groups: number().int()
18918
+ embeddings: number().int()
18883
18919
  });
18884
18920
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18885
18921
  var DiskReconcileCountsSchema = object({
@@ -19049,6 +19085,47 @@ var RebuildStatusSchema = object({
19049
19085
  /** Present when the pass ended by throwing. */
19050
19086
  error: string().nullable()
19051
19087
  });
19088
+ /**
19089
+ * Acknowledgement that a debug-media reclaim STARTED.
19090
+ *
19091
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19092
+ * it runs detached and this returns immediately. Awaiting it is how the
19093
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19094
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19095
+ */
19096
+ var MediaReclaimStartResultSchema = object({
19097
+ started: boolean(),
19098
+ /** True when a pass was already running; the new request is ignored. */
19099
+ alreadyRunning: boolean()
19100
+ });
19101
+ var MediaReclaimInputSchema = object({
19102
+ mode: _enum(["report", "reclaim"]).default("report"),
19103
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19104
+ deviceIds: array(number().int()).min(1).optional(),
19105
+ restart: boolean().optional(),
19106
+ pageSize: number().int().min(50).max(5e3).optional(),
19107
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19108
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19109
+ maxBytesPerRun: number().int().min(1).optional(),
19110
+ budgetMinutes: number().int().min(1).max(720).optional(),
19111
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19112
+ graceMinutes: number().int().min(1).max(10080).optional()
19113
+ });
19114
+ var MediaReclaimStatusSchema = object({
19115
+ running: boolean(),
19116
+ mode: _enum(["report", "reclaim"]).nullable(),
19117
+ totalExamined: number(),
19118
+ totalEligible: number(),
19119
+ totalReclaimed: number(),
19120
+ totalBytesReclaimed: number(),
19121
+ totalRefused: number(),
19122
+ /** Device+scope windows finished in this pass. */
19123
+ devicesDone: number(),
19124
+ complete: boolean().nullable(),
19125
+ startedAtMs: number().nullable(),
19126
+ finishedAtMs: number().nullable(),
19127
+ error: string().nullable()
19128
+ });
19052
19129
  var ReplayFrameInputSchema = object({
19053
19130
  timestamp: number(),
19054
19131
  frame: PipelineRunResultBridge
@@ -19087,10 +19164,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19087
19164
  * stationary registry). Default false: the timeline lists passages,
19088
19165
  * not parking records (operator decision, 2026-08-15). */
19089
19166
  includeStationary: boolean().optional()
19090
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19091
- deviceId: number(),
19092
- groupId: string().min(1)
19093
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19167
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19094
19168
  kind: "mutation",
19095
19169
  auth: "admin"
19096
19170
  }), 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({
@@ -19190,6 +19264,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19190
19264
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19191
19265
  kind: "query",
19192
19266
  auth: "admin"
19267
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19268
+ kind: "mutation",
19269
+ auth: "admin"
19270
+ }), method(object({}), MediaReclaimStatusSchema, {
19271
+ kind: "query",
19272
+ auth: "admin"
19193
19273
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19194
19274
  kind: "query",
19195
19275
  auth: "admin"
@@ -21173,7 +21253,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21173
21253
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21174
21254
  kind: "mutation",
21175
21255
  auth: "admin"
21176
- });
21256
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21257
+ kind: "mutation",
21258
+ auth: "admin"
21259
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21260
+ kind: "mutation",
21261
+ auth: "admin"
21262
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21177
21263
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21178
21264
  providerId: string().min(1),
21179
21265
  displayName: string().min(1),
@@ -26551,6 +26637,33 @@ var RecordingRebalanceInputSchema = object({
26551
26637
  minMoveGb: number().min(0).optional()
26552
26638
  });
26553
26639
  /**
26640
+ * Operator-facing placement of one camera onto a recordings location.
26641
+ *
26642
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26643
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26644
+ * currently write — the plan, which may disagree with the pin when Auto.
26645
+ */
26646
+ var RecordingDevicePlacementSchema = object({
26647
+ deviceId: number().int(),
26648
+ profile: string(),
26649
+ locationId: string()
26650
+ });
26651
+ var RecordingDevicePinSchema = object({
26652
+ deviceId: number().int(),
26653
+ /** Recordings-class location this camera is pinned to. */
26654
+ locationId: string()
26655
+ });
26656
+ var RecordingPlacementViewSchema = object({
26657
+ assignments: array(RecordingDevicePlacementSchema),
26658
+ pins: array(RecordingDevicePinSchema),
26659
+ defaultLocations: record(string(), string())
26660
+ });
26661
+ var RecordingSetDevicePlacementInputSchema = object({
26662
+ deviceId: number().int(),
26663
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26664
+ locationId: string().nullable()
26665
+ });
26666
+ /**
26554
26667
  * Result of locating footage at a wall-clock instant for one device/profile.
26555
26668
  * `segment` carries the covering segment's window; `gap` reports the forward
26556
26669
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26776,6 +26889,12 @@ method(object({
26776
26889
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26777
26890
  kind: "mutation",
26778
26891
  auth: "admin"
26892
+ }), method(object({}), RecordingPlacementViewSchema, {
26893
+ kind: "query",
26894
+ auth: "admin"
26895
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
26896
+ kind: "mutation",
26897
+ auth: "admin"
26779
26898
  });
26780
26899
  /**
26781
26900
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30146,6 +30265,12 @@ Object.freeze({
30146
30265
  addonId: null,
30147
30266
  access: "delete"
30148
30267
  },
30268
+ "deviceManager.renameLocation": {
30269
+ capName: "device-manager",
30270
+ capScope: "system",
30271
+ addonId: null,
30272
+ access: "create"
30273
+ },
30149
30274
  "deviceManager.runDeviceAction": {
30150
30275
  capName: "device-manager",
30151
30276
  capScope: "system",
@@ -31838,19 +31963,19 @@ Object.freeze({
31838
31963
  addonId: null,
31839
31964
  access: "view"
31840
31965
  },
31841
- "pipelineAnalytics.getGroup": {
31966
+ "pipelineAnalytics.getKeyEvents": {
31842
31967
  capName: "pipeline-analytics",
31843
31968
  capScope: "device",
31844
31969
  addonId: null,
31845
31970
  access: "view"
31846
31971
  },
31847
- "pipelineAnalytics.getKeyEvents": {
31972
+ "pipelineAnalytics.getKeyEventsBatch": {
31848
31973
  capName: "pipeline-analytics",
31849
31974
  capScope: "device",
31850
31975
  addonId: null,
31851
31976
  access: "view"
31852
31977
  },
31853
- "pipelineAnalytics.getKeyEventsBatch": {
31978
+ "pipelineAnalytics.getMediaReclaimStatus": {
31854
31979
  capName: "pipeline-analytics",
31855
31980
  capScope: "device",
31856
31981
  addonId: null,
@@ -31940,12 +32065,6 @@ Object.freeze({
31940
32065
  addonId: null,
31941
32066
  access: "view"
31942
32067
  },
31943
- "pipelineAnalytics.listGroups": {
31944
- capName: "pipeline-analytics",
31945
- capScope: "device",
31946
- addonId: null,
31947
- access: "view"
31948
- },
31949
32068
  "pipelineAnalytics.listOpsLog": {
31950
32069
  capName: "pipeline-analytics",
31951
32070
  capScope: "device",
@@ -32030,6 +32149,12 @@ Object.freeze({
32030
32149
  addonId: null,
32031
32150
  access: "create"
32032
32151
  },
32152
+ "pipelineAnalytics.reclaimDebugMedia": {
32153
+ capName: "pipeline-analytics",
32154
+ capScope: "device",
32155
+ addonId: null,
32156
+ access: "create"
32157
+ },
32033
32158
  "pipelineAnalytics.reconcileFromDisk": {
32034
32159
  capName: "pipeline-analytics",
32035
32160
  capScope: "device",
@@ -32954,6 +33079,12 @@ Object.freeze({
32954
33079
  addonId: null,
32955
33080
  access: "view"
32956
33081
  },
33082
+ "recording.getPlacement": {
33083
+ capName: "recording",
33084
+ capScope: "system",
33085
+ addonId: null,
33086
+ access: "view"
33087
+ },
32957
33088
  "recording.getPlaybackManifest": {
32958
33089
  capName: "recording",
32959
33090
  capScope: "system",
@@ -33080,6 +33211,12 @@ Object.freeze({
33080
33211
  addonId: null,
33081
33212
  access: "create"
33082
33213
  },
33214
+ "recording.setDevicePlacement": {
33215
+ capName: "recording",
33216
+ capScope: "system",
33217
+ addonId: null,
33218
+ access: "create"
33219
+ },
33083
33220
  "recording.startStorageMigrationMove": {
33084
33221
  capName: "recording",
33085
33222
  capScope: "system",
@@ -33524,12 +33661,36 @@ Object.freeze({
33524
33661
  addonId: null,
33525
33662
  access: "create"
33526
33663
  },
33664
+ "storageMigration.cleanupCancel": {
33665
+ capName: "storage-migration",
33666
+ capScope: "system",
33667
+ addonId: null,
33668
+ access: "create"
33669
+ },
33670
+ "storageMigration.cleanupStart": {
33671
+ capName: "storage-migration",
33672
+ capScope: "system",
33673
+ addonId: null,
33674
+ access: "create"
33675
+ },
33676
+ "storageMigration.cleanupStatus": {
33677
+ capName: "storage-migration",
33678
+ capScope: "system",
33679
+ addonId: null,
33680
+ access: "view"
33681
+ },
33527
33682
  "storageMigration.drain": {
33528
33683
  capName: "storage-migration",
33529
33684
  capScope: "system",
33530
33685
  addonId: null,
33531
33686
  access: "create"
33532
33687
  },
33688
+ "storageMigration.history": {
33689
+ capName: "storage-migration",
33690
+ capScope: "system",
33691
+ addonId: null,
33692
+ access: "view"
33693
+ },
33533
33694
  "storageMigration.movers": {
33534
33695
  capName: "storage-migration",
33535
33696
  capScope: "system",
@@ -35526,11 +35687,6 @@ Object.freeze({
35526
35687
  form: "single",
35527
35688
  optional: true
35528
35689
  }],
35529
- "pipelineAnalytics.getGroup": [{
35530
- name: "deviceId",
35531
- form: "single",
35532
- optional: false
35533
- }],
35534
35690
  "pipelineAnalytics.getKeyEvents": [{
35535
35691
  name: "deviceId",
35536
35692
  form: "single",
@@ -35596,11 +35752,6 @@ Object.freeze({
35596
35752
  form: "single",
35597
35753
  optional: false
35598
35754
  }],
35599
- "pipelineAnalytics.listGroups": [{
35600
- name: "deviceIds",
35601
- form: "array",
35602
- optional: false
35603
- }],
35604
35755
  "pipelineAnalytics.listOpsLog": [{
35605
35756
  name: "deviceId",
35606
35757
  form: "single",
@@ -35646,6 +35797,11 @@ Object.freeze({
35646
35797
  form: "single",
35647
35798
  optional: true
35648
35799
  }],
35800
+ "pipelineAnalytics.reclaimDebugMedia": [{
35801
+ name: "deviceIds",
35802
+ form: "array",
35803
+ optional: true
35804
+ }],
35649
35805
  "pipelineAnalytics.reconcileFromDisk": [{
35650
35806
  name: "deviceId",
35651
35807
  form: "single",
@@ -36011,6 +36167,11 @@ Object.freeze({
36011
36167
  form: "single",
36012
36168
  optional: false
36013
36169
  }],
36170
+ "recording.setDevicePlacement": [{
36171
+ name: "deviceId",
36172
+ form: "single",
36173
+ optional: false
36174
+ }],
36014
36175
  "recording.startStorageMigrationMove": [{
36015
36176
  name: "deviceId",
36016
36177
  form: "single",
@@ -8115,6 +8115,13 @@ var MediaRelocateModeSchema = _enum([
8115
8115
  ]);
8116
8116
  var RelocateMediaInputSchema = object({
8117
8117
  toLocationId: string(),
8118
+ /**
8119
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8120
+ * every row that is not already on `toLocationId` (the historical
8121
+ * behaviour). A named source is what a from→to migration needs: without it
8122
+ * "move events off disk 2" also emptied disk 1.
8123
+ */
8124
+ fromLocationId: string().optional(),
8118
8125
  throttleMbps: number().min(1).max(1e3).optional(),
8119
8126
  /** Omitted = `move`, the pre-existing behaviour. */
8120
8127
  mode: MediaRelocateModeSchema.optional()
@@ -8182,6 +8189,19 @@ var StorageMigrationDestinationsSchema = object({
8182
8189
  galleryMedia: string().min(1).optional()
8183
8190
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8184
8191
  /**
8192
+ * Optional named source per class. Omitted = the class's current default
8193
+ * (the historical behaviour). A named source that is NOT the default is a
8194
+ * drain of that disk: bytes move, the default stays, and the source is
8195
+ * disabled when the move finishes.
8196
+ */
8197
+ var StorageMigrationSourcesSchema = object({
8198
+ recordings: string().min(1).optional(),
8199
+ recordingsLow: string().min(1).optional(),
8200
+ eventMedia: string().min(1).optional(),
8201
+ backups: string().min(1).optional(),
8202
+ galleryMedia: string().min(1).optional()
8203
+ }).optional();
8204
+ /**
8185
8205
  * How a migration sequences the cutover against the byte move.
8186
8206
  *
8187
8207
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8203,6 +8223,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8203
8223
  /** Shared input for planning and starting an orchestrated storage migration. */
8204
8224
  var StorageMigrationInputSchema = object({
8205
8225
  destinations: StorageMigrationDestinationsSchema,
8226
+ /** Omitted = each class's current default. */
8227
+ sources: StorageMigrationSourcesSchema,
8206
8228
  throttleMbps: number().min(1).max(1e3).optional(),
8207
8229
  /** Omitted = `blocking`, which stays the default. */
8208
8230
  mode: StorageMigrationModeSchema.optional()
@@ -8282,6 +8304,13 @@ var StorageMigrationMoveSchema = object({
8282
8304
  storageClass: StorageMigrationClassSchema,
8283
8305
  fromLocationId: string(),
8284
8306
  toLocationId: string(),
8307
+ /**
8308
+ * True when `from` was NOT the class default at plan time. The move still
8309
+ * copies bytes, but the default is left alone and the source is disabled
8310
+ * once the copy verifies. Absent on jobs planned before this field existed
8311
+ * — those jobs always repointed, which is `false`.
8312
+ */
8313
+ freezeSource: boolean().optional(),
8285
8314
  moverJobId: string().nullable(),
8286
8315
  state: RelocateJobStateSchema.nullable(),
8287
8316
  error: string().nullable(),
@@ -8295,6 +8324,7 @@ var StorageMigrationJobSchema = object({
8295
8324
  * can tell a seconds-long cutover from a thirty-hour one. */
8296
8325
  mode: StorageMigrationModeSchema,
8297
8326
  destinations: StorageMigrationDestinationsSchema,
8327
+ sources: StorageMigrationSourcesSchema,
8298
8328
  throttleMbps: number(),
8299
8329
  moves: array(StorageMigrationMoveSchema),
8300
8330
  pauseLeaseId: string().nullable(),
@@ -8320,6 +8350,7 @@ var StorageMigrationFindingSchema = object({
8320
8350
  });
8321
8351
  var StorageMigrationPlanSchema = object({
8322
8352
  destinations: StorageMigrationDestinationsSchema,
8353
+ sources: StorageMigrationSourcesSchema,
8323
8354
  /** The mode this plan was built for. A plan is only valid for its mode: the
8324
8355
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8325
8356
  * it. */
@@ -8327,7 +8358,8 @@ var StorageMigrationPlanSchema = object({
8327
8358
  moves: array(object({
8328
8359
  storageClass: StorageMigrationClassSchema,
8329
8360
  fromLocationId: string(),
8330
- toLocationId: string()
8361
+ toLocationId: string(),
8362
+ freezeSource: boolean().optional()
8331
8363
  })),
8332
8364
  findings: array(StorageMigrationFindingSchema)
8333
8365
  });
@@ -8505,10 +8537,51 @@ var LedgerWalkReportSchema = object({
8505
8537
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8506
8538
  var RelocatableMediaCountInputSchema = object({
8507
8539
  toLocationId: string().min(1),
8540
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8541
+ fromLocationId: string().optional(),
8508
8542
  /** Omitted = `move`. */
8509
8543
  mode: MediaRelocateModeSchema.optional()
8510
8544
  });
8511
8545
  /**
8546
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8547
+ * ghost ledger entries on frozen footage locations.
8548
+ *
8549
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8550
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8551
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8552
+ * with no operator-visible status.
8553
+ */
8554
+ var StorageCleanupPhaseSchema = _enum([
8555
+ "orphans",
8556
+ "debug-media",
8557
+ "ghost-ledger",
8558
+ "done",
8559
+ "failed",
8560
+ "cancelled"
8561
+ ]);
8562
+ var StorageCleanupInputSchema = object({
8563
+ /** Also walk motion stills / track filmstrips. Off by default. */
8564
+ includeDebugMedia: boolean().optional() });
8565
+ var StorageCleanupJobSchema = object({
8566
+ jobId: string(),
8567
+ phase: StorageCleanupPhaseSchema,
8568
+ includeDebugMedia: boolean(),
8569
+ orphansReclaimed: number().int().nonnegative(),
8570
+ orphanBytesReclaimed: number().int().nonnegative(),
8571
+ debugMediaReclaimed: number().int().nonnegative(),
8572
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8573
+ ghostsForgotten: number().int().nonnegative(),
8574
+ ghostBytesForgotten: number().int().nonnegative(),
8575
+ /** Short operator-facing line: current collection, pass, or location. */
8576
+ detail: string().nullable(),
8577
+ cancelRequested: boolean(),
8578
+ startedAt: number(),
8579
+ updatedAt: number(),
8580
+ finishedAt: number().nullable(),
8581
+ error: string().nullable()
8582
+ });
8583
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8584
+ /**
8512
8585
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8513
8586
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8514
8587
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8536,11 +8609,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8536
8609
  * The default location for a type uses `id === <type>:default` by
8537
8610
  * convention (the bare type ref like `'backups'` resolves to it).
8538
8611
  *
8539
- * `isSystem: true` marks a location as orchestrator-seeded and
8540
- * undeletable. The bootstrap-installed defaults (one per type) carry
8541
- * this flag; operator-added locations don't. Editing the config of
8542
- * a system location is allowed (path migration, provider swap) but
8543
- * deleting it is rejected at the cap level.
8612
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8613
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8614
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8615
+ * / last-enabled, not on this bit.
8544
8616
  */
8545
8617
  var StorageLocationSchema = object({
8546
8618
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12802,6 +12874,12 @@ method(object({
12802
12874
  }), _void(), {
12803
12875
  kind: "mutation",
12804
12876
  auth: "admin"
12877
+ }), method(object({
12878
+ from: string(),
12879
+ to: string()
12880
+ }), object({ moved: number() }), {
12881
+ kind: "mutation",
12882
+ auth: "admin"
12805
12883
  }), method(object({
12806
12884
  deviceId: number(),
12807
12885
  disabled: boolean()
@@ -18732,46 +18810,6 @@ var RecentTracksPageSchema = object({
18732
18810
  /** Cursor for the next page, or null when this page is the last. */
18733
18811
  nextCursor: string().nullable()
18734
18812
  });
18735
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18736
- var LIST_GROUPS_MAX_LIMIT = 100;
18737
- var AnalyticsGroupRecordSchema = object({
18738
- id: string(),
18739
- deviceId: number().int(),
18740
- openedAt: number().int(),
18741
- closedAt: number().int(),
18742
- timestamp: number().int(),
18743
- memberCount: number().int(),
18744
- memberTrackIds: array(string()).readonly(),
18745
- className: string(),
18746
- classes: array(string()).readonly(),
18747
- /** Relative event-media path, or null when the group has no picture yet. */
18748
- mediaUrl: string().nullable(),
18749
- singleton: boolean()
18750
- });
18751
- var AnalyticsGroupMemberSchema = object({
18752
- trackId: string(),
18753
- deviceId: number().int(),
18754
- className: string(),
18755
- firstSeen: number().int(),
18756
- lastSeen: number().int(),
18757
- mediaUrl: string().nullable()
18758
- });
18759
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18760
- var ListGroupsQueryInput = object({
18761
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18762
- deviceIds: array(number()),
18763
- /** Window lower bound on `closedAt` (inclusive). */
18764
- since: number().optional(),
18765
- /** Window upper bound on `openedAt` (inclusive). */
18766
- until: number().optional(),
18767
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18768
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18769
- cursor: string().optional()
18770
- });
18771
- var ListGroupsPageSchema = object({
18772
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18773
- nextCursor: string().nullable()
18774
- });
18775
18813
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18776
18814
  var KEY_EVENTS_MAX_LIMIT = 200;
18777
18815
  var KeyEventQueryInput = object({
@@ -18875,9 +18913,7 @@ var TrackCascadeCountsSchema = object({
18875
18913
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
18876
18914
  plates: number().int(),
18877
18915
  /** Per-track CLIP search vectors removed (best-effort). */
18878
- embeddings: number().int(),
18879
- /** Group membership + group rows removed with their last member (best-effort). */
18880
- groups: number().int()
18916
+ embeddings: number().int()
18881
18917
  });
18882
18918
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18883
18919
  var DiskReconcileCountsSchema = object({
@@ -19047,6 +19083,47 @@ var RebuildStatusSchema = object({
19047
19083
  /** Present when the pass ended by throwing. */
19048
19084
  error: string().nullable()
19049
19085
  });
19086
+ /**
19087
+ * Acknowledgement that a debug-media reclaim STARTED.
19088
+ *
19089
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19090
+ * it runs detached and this returns immediately. Awaiting it is how the
19091
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19092
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19093
+ */
19094
+ var MediaReclaimStartResultSchema = object({
19095
+ started: boolean(),
19096
+ /** True when a pass was already running; the new request is ignored. */
19097
+ alreadyRunning: boolean()
19098
+ });
19099
+ var MediaReclaimInputSchema = object({
19100
+ mode: _enum(["report", "reclaim"]).default("report"),
19101
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19102
+ deviceIds: array(number().int()).min(1).optional(),
19103
+ restart: boolean().optional(),
19104
+ pageSize: number().int().min(50).max(5e3).optional(),
19105
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19106
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19107
+ maxBytesPerRun: number().int().min(1).optional(),
19108
+ budgetMinutes: number().int().min(1).max(720).optional(),
19109
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19110
+ graceMinutes: number().int().min(1).max(10080).optional()
19111
+ });
19112
+ var MediaReclaimStatusSchema = object({
19113
+ running: boolean(),
19114
+ mode: _enum(["report", "reclaim"]).nullable(),
19115
+ totalExamined: number(),
19116
+ totalEligible: number(),
19117
+ totalReclaimed: number(),
19118
+ totalBytesReclaimed: number(),
19119
+ totalRefused: number(),
19120
+ /** Device+scope windows finished in this pass. */
19121
+ devicesDone: number(),
19122
+ complete: boolean().nullable(),
19123
+ startedAtMs: number().nullable(),
19124
+ finishedAtMs: number().nullable(),
19125
+ error: string().nullable()
19126
+ });
19050
19127
  var ReplayFrameInputSchema = object({
19051
19128
  timestamp: number(),
19052
19129
  frame: PipelineRunResultBridge
@@ -19085,10 +19162,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19085
19162
  * stationary registry). Default false: the timeline lists passages,
19086
19163
  * not parking records (operator decision, 2026-08-15). */
19087
19164
  includeStationary: boolean().optional()
19088
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19089
- deviceId: number(),
19090
- groupId: string().min(1)
19091
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19165
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19092
19166
  kind: "mutation",
19093
19167
  auth: "admin"
19094
19168
  }), 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({
@@ -19188,6 +19262,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19188
19262
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19189
19263
  kind: "query",
19190
19264
  auth: "admin"
19265
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19266
+ kind: "mutation",
19267
+ auth: "admin"
19268
+ }), method(object({}), MediaReclaimStatusSchema, {
19269
+ kind: "query",
19270
+ auth: "admin"
19191
19271
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19192
19272
  kind: "query",
19193
19273
  auth: "admin"
@@ -21171,7 +21251,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21171
21251
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21172
21252
  kind: "mutation",
21173
21253
  auth: "admin"
21174
- });
21254
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21255
+ kind: "mutation",
21256
+ auth: "admin"
21257
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21258
+ kind: "mutation",
21259
+ auth: "admin"
21260
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21175
21261
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21176
21262
  providerId: string().min(1),
21177
21263
  displayName: string().min(1),
@@ -26549,6 +26635,33 @@ var RecordingRebalanceInputSchema = object({
26549
26635
  minMoveGb: number().min(0).optional()
26550
26636
  });
26551
26637
  /**
26638
+ * Operator-facing placement of one camera onto a recordings location.
26639
+ *
26640
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26641
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26642
+ * currently write — the plan, which may disagree with the pin when Auto.
26643
+ */
26644
+ var RecordingDevicePlacementSchema = object({
26645
+ deviceId: number().int(),
26646
+ profile: string(),
26647
+ locationId: string()
26648
+ });
26649
+ var RecordingDevicePinSchema = object({
26650
+ deviceId: number().int(),
26651
+ /** Recordings-class location this camera is pinned to. */
26652
+ locationId: string()
26653
+ });
26654
+ var RecordingPlacementViewSchema = object({
26655
+ assignments: array(RecordingDevicePlacementSchema),
26656
+ pins: array(RecordingDevicePinSchema),
26657
+ defaultLocations: record(string(), string())
26658
+ });
26659
+ var RecordingSetDevicePlacementInputSchema = object({
26660
+ deviceId: number().int(),
26661
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26662
+ locationId: string().nullable()
26663
+ });
26664
+ /**
26552
26665
  * Result of locating footage at a wall-clock instant for one device/profile.
26553
26666
  * `segment` carries the covering segment's window; `gap` reports the forward
26554
26667
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26774,6 +26887,12 @@ method(object({
26774
26887
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26775
26888
  kind: "mutation",
26776
26889
  auth: "admin"
26890
+ }), method(object({}), RecordingPlacementViewSchema, {
26891
+ kind: "query",
26892
+ auth: "admin"
26893
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
26894
+ kind: "mutation",
26895
+ auth: "admin"
26777
26896
  });
26778
26897
  /**
26779
26898
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30144,6 +30263,12 @@ Object.freeze({
30144
30263
  addonId: null,
30145
30264
  access: "delete"
30146
30265
  },
30266
+ "deviceManager.renameLocation": {
30267
+ capName: "device-manager",
30268
+ capScope: "system",
30269
+ addonId: null,
30270
+ access: "create"
30271
+ },
30147
30272
  "deviceManager.runDeviceAction": {
30148
30273
  capName: "device-manager",
30149
30274
  capScope: "system",
@@ -31836,19 +31961,19 @@ Object.freeze({
31836
31961
  addonId: null,
31837
31962
  access: "view"
31838
31963
  },
31839
- "pipelineAnalytics.getGroup": {
31964
+ "pipelineAnalytics.getKeyEvents": {
31840
31965
  capName: "pipeline-analytics",
31841
31966
  capScope: "device",
31842
31967
  addonId: null,
31843
31968
  access: "view"
31844
31969
  },
31845
- "pipelineAnalytics.getKeyEvents": {
31970
+ "pipelineAnalytics.getKeyEventsBatch": {
31846
31971
  capName: "pipeline-analytics",
31847
31972
  capScope: "device",
31848
31973
  addonId: null,
31849
31974
  access: "view"
31850
31975
  },
31851
- "pipelineAnalytics.getKeyEventsBatch": {
31976
+ "pipelineAnalytics.getMediaReclaimStatus": {
31852
31977
  capName: "pipeline-analytics",
31853
31978
  capScope: "device",
31854
31979
  addonId: null,
@@ -31938,12 +32063,6 @@ Object.freeze({
31938
32063
  addonId: null,
31939
32064
  access: "view"
31940
32065
  },
31941
- "pipelineAnalytics.listGroups": {
31942
- capName: "pipeline-analytics",
31943
- capScope: "device",
31944
- addonId: null,
31945
- access: "view"
31946
- },
31947
32066
  "pipelineAnalytics.listOpsLog": {
31948
32067
  capName: "pipeline-analytics",
31949
32068
  capScope: "device",
@@ -32028,6 +32147,12 @@ Object.freeze({
32028
32147
  addonId: null,
32029
32148
  access: "create"
32030
32149
  },
32150
+ "pipelineAnalytics.reclaimDebugMedia": {
32151
+ capName: "pipeline-analytics",
32152
+ capScope: "device",
32153
+ addonId: null,
32154
+ access: "create"
32155
+ },
32031
32156
  "pipelineAnalytics.reconcileFromDisk": {
32032
32157
  capName: "pipeline-analytics",
32033
32158
  capScope: "device",
@@ -32952,6 +33077,12 @@ Object.freeze({
32952
33077
  addonId: null,
32953
33078
  access: "view"
32954
33079
  },
33080
+ "recording.getPlacement": {
33081
+ capName: "recording",
33082
+ capScope: "system",
33083
+ addonId: null,
33084
+ access: "view"
33085
+ },
32955
33086
  "recording.getPlaybackManifest": {
32956
33087
  capName: "recording",
32957
33088
  capScope: "system",
@@ -33078,6 +33209,12 @@ Object.freeze({
33078
33209
  addonId: null,
33079
33210
  access: "create"
33080
33211
  },
33212
+ "recording.setDevicePlacement": {
33213
+ capName: "recording",
33214
+ capScope: "system",
33215
+ addonId: null,
33216
+ access: "create"
33217
+ },
33081
33218
  "recording.startStorageMigrationMove": {
33082
33219
  capName: "recording",
33083
33220
  capScope: "system",
@@ -33522,12 +33659,36 @@ Object.freeze({
33522
33659
  addonId: null,
33523
33660
  access: "create"
33524
33661
  },
33662
+ "storageMigration.cleanupCancel": {
33663
+ capName: "storage-migration",
33664
+ capScope: "system",
33665
+ addonId: null,
33666
+ access: "create"
33667
+ },
33668
+ "storageMigration.cleanupStart": {
33669
+ capName: "storage-migration",
33670
+ capScope: "system",
33671
+ addonId: null,
33672
+ access: "create"
33673
+ },
33674
+ "storageMigration.cleanupStatus": {
33675
+ capName: "storage-migration",
33676
+ capScope: "system",
33677
+ addonId: null,
33678
+ access: "view"
33679
+ },
33525
33680
  "storageMigration.drain": {
33526
33681
  capName: "storage-migration",
33527
33682
  capScope: "system",
33528
33683
  addonId: null,
33529
33684
  access: "create"
33530
33685
  },
33686
+ "storageMigration.history": {
33687
+ capName: "storage-migration",
33688
+ capScope: "system",
33689
+ addonId: null,
33690
+ access: "view"
33691
+ },
33531
33692
  "storageMigration.movers": {
33532
33693
  capName: "storage-migration",
33533
33694
  capScope: "system",
@@ -35524,11 +35685,6 @@ Object.freeze({
35524
35685
  form: "single",
35525
35686
  optional: true
35526
35687
  }],
35527
- "pipelineAnalytics.getGroup": [{
35528
- name: "deviceId",
35529
- form: "single",
35530
- optional: false
35531
- }],
35532
35688
  "pipelineAnalytics.getKeyEvents": [{
35533
35689
  name: "deviceId",
35534
35690
  form: "single",
@@ -35594,11 +35750,6 @@ Object.freeze({
35594
35750
  form: "single",
35595
35751
  optional: false
35596
35752
  }],
35597
- "pipelineAnalytics.listGroups": [{
35598
- name: "deviceIds",
35599
- form: "array",
35600
- optional: false
35601
- }],
35602
35753
  "pipelineAnalytics.listOpsLog": [{
35603
35754
  name: "deviceId",
35604
35755
  form: "single",
@@ -35644,6 +35795,11 @@ Object.freeze({
35644
35795
  form: "single",
35645
35796
  optional: true
35646
35797
  }],
35798
+ "pipelineAnalytics.reclaimDebugMedia": [{
35799
+ name: "deviceIds",
35800
+ form: "array",
35801
+ optional: true
35802
+ }],
35647
35803
  "pipelineAnalytics.reconcileFromDisk": [{
35648
35804
  name: "deviceId",
35649
35805
  form: "single",
@@ -36009,6 +36165,11 @@ Object.freeze({
36009
36165
  form: "single",
36010
36166
  optional: false
36011
36167
  }],
36168
+ "recording.setDevicePlacement": [{
36169
+ name: "deviceId",
36170
+ form: "single",
36171
+ optional: false
36172
+ }],
36012
36173
  "recording.startStorageMigrationMove": [{
36013
36174
  name: "deviceId",
36014
36175
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-smtp-nodemailer",
3
- "version": "1.2.48",
3
+ "version": "1.2.49",
4
4
  "description": "SMTP email provider addon for CamStack — wraps `nodemailer` and registers a `smtp-provider` cap collection entry. Used by magic-link login + notifier addons.",
5
5
  "keywords": [
6
6
  "camstack",