@camstack/addon-export-google 0.1.13 → 0.1.15

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.
@@ -8289,6 +8289,13 @@ var MediaRelocateModeSchema = _enum([
8289
8289
  ]);
8290
8290
  var RelocateMediaInputSchema = object({
8291
8291
  toLocationId: string(),
8292
+ /**
8293
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8294
+ * every row that is not already on `toLocationId` (the historical
8295
+ * behaviour). A named source is what a from→to migration needs: without it
8296
+ * "move events off disk 2" also emptied disk 1.
8297
+ */
8298
+ fromLocationId: string().optional(),
8292
8299
  throttleMbps: number().min(1).max(1e3).optional(),
8293
8300
  /** Omitted = `move`, the pre-existing behaviour. */
8294
8301
  mode: MediaRelocateModeSchema.optional()
@@ -8356,6 +8363,19 @@ var StorageMigrationDestinationsSchema = object({
8356
8363
  galleryMedia: string().min(1).optional()
8357
8364
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8358
8365
  /**
8366
+ * Optional named source per class. Omitted = the class's current default
8367
+ * (the historical behaviour). A named source that is NOT the default is a
8368
+ * drain of that disk: bytes move, the default stays, and the source is
8369
+ * disabled when the move finishes.
8370
+ */
8371
+ var StorageMigrationSourcesSchema = object({
8372
+ recordings: string().min(1).optional(),
8373
+ recordingsLow: string().min(1).optional(),
8374
+ eventMedia: string().min(1).optional(),
8375
+ backups: string().min(1).optional(),
8376
+ galleryMedia: string().min(1).optional()
8377
+ }).optional();
8378
+ /**
8359
8379
  * How a migration sequences the cutover against the byte move.
8360
8380
  *
8361
8381
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8377,6 +8397,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8377
8397
  /** Shared input for planning and starting an orchestrated storage migration. */
8378
8398
  var StorageMigrationInputSchema = object({
8379
8399
  destinations: StorageMigrationDestinationsSchema,
8400
+ /** Omitted = each class's current default. */
8401
+ sources: StorageMigrationSourcesSchema,
8380
8402
  throttleMbps: number().min(1).max(1e3).optional(),
8381
8403
  /** Omitted = `blocking`, which stays the default. */
8382
8404
  mode: StorageMigrationModeSchema.optional()
@@ -8456,6 +8478,13 @@ var StorageMigrationMoveSchema = object({
8456
8478
  storageClass: StorageMigrationClassSchema,
8457
8479
  fromLocationId: string(),
8458
8480
  toLocationId: string(),
8481
+ /**
8482
+ * True when `from` was NOT the class default at plan time. The move still
8483
+ * copies bytes, but the default is left alone and the source is disabled
8484
+ * once the copy verifies. Absent on jobs planned before this field existed
8485
+ * — those jobs always repointed, which is `false`.
8486
+ */
8487
+ freezeSource: boolean().optional(),
8459
8488
  moverJobId: string().nullable(),
8460
8489
  state: RelocateJobStateSchema.nullable(),
8461
8490
  error: string().nullable(),
@@ -8469,6 +8498,7 @@ var StorageMigrationJobSchema = object({
8469
8498
  * can tell a seconds-long cutover from a thirty-hour one. */
8470
8499
  mode: StorageMigrationModeSchema,
8471
8500
  destinations: StorageMigrationDestinationsSchema,
8501
+ sources: StorageMigrationSourcesSchema,
8472
8502
  throttleMbps: number(),
8473
8503
  moves: array(StorageMigrationMoveSchema),
8474
8504
  pauseLeaseId: string().nullable(),
@@ -8494,6 +8524,7 @@ var StorageMigrationFindingSchema = object({
8494
8524
  });
8495
8525
  var StorageMigrationPlanSchema = object({
8496
8526
  destinations: StorageMigrationDestinationsSchema,
8527
+ sources: StorageMigrationSourcesSchema,
8497
8528
  /** The mode this plan was built for. A plan is only valid for its mode: the
8498
8529
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8499
8530
  * it. */
@@ -8501,7 +8532,8 @@ var StorageMigrationPlanSchema = object({
8501
8532
  moves: array(object({
8502
8533
  storageClass: StorageMigrationClassSchema,
8503
8534
  fromLocationId: string(),
8504
- toLocationId: string()
8535
+ toLocationId: string(),
8536
+ freezeSource: boolean().optional()
8505
8537
  })),
8506
8538
  findings: array(StorageMigrationFindingSchema)
8507
8539
  });
@@ -8679,10 +8711,51 @@ var LedgerWalkReportSchema = object({
8679
8711
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8680
8712
  var RelocatableMediaCountInputSchema = object({
8681
8713
  toLocationId: string().min(1),
8714
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8715
+ fromLocationId: string().optional(),
8682
8716
  /** Omitted = `move`. */
8683
8717
  mode: MediaRelocateModeSchema.optional()
8684
8718
  });
8685
8719
  /**
8720
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8721
+ * ghost ledger entries on frozen footage locations.
8722
+ *
8723
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8724
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8725
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8726
+ * with no operator-visible status.
8727
+ */
8728
+ var StorageCleanupPhaseSchema = _enum([
8729
+ "orphans",
8730
+ "debug-media",
8731
+ "ghost-ledger",
8732
+ "done",
8733
+ "failed",
8734
+ "cancelled"
8735
+ ]);
8736
+ var StorageCleanupInputSchema = object({
8737
+ /** Also walk motion stills / track filmstrips. Off by default. */
8738
+ includeDebugMedia: boolean().optional() });
8739
+ var StorageCleanupJobSchema = object({
8740
+ jobId: string(),
8741
+ phase: StorageCleanupPhaseSchema,
8742
+ includeDebugMedia: boolean(),
8743
+ orphansReclaimed: number().int().nonnegative(),
8744
+ orphanBytesReclaimed: number().int().nonnegative(),
8745
+ debugMediaReclaimed: number().int().nonnegative(),
8746
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8747
+ ghostsForgotten: number().int().nonnegative(),
8748
+ ghostBytesForgotten: number().int().nonnegative(),
8749
+ /** Short operator-facing line: current collection, pass, or location. */
8750
+ detail: string().nullable(),
8751
+ cancelRequested: boolean(),
8752
+ startedAt: number(),
8753
+ updatedAt: number(),
8754
+ finishedAt: number().nullable(),
8755
+ error: string().nullable()
8756
+ });
8757
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8758
+ /**
8686
8759
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8687
8760
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8688
8761
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8710,11 +8783,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8710
8783
  * The default location for a type uses `id === <type>:default` by
8711
8784
  * convention (the bare type ref like `'backups'` resolves to it).
8712
8785
  *
8713
- * `isSystem: true` marks a location as orchestrator-seeded and
8714
- * undeletable. The bootstrap-installed defaults (one per type) carry
8715
- * this flag; operator-added locations don't. Editing the config of
8716
- * a system location is allowed (path migration, provider swap) but
8717
- * deleting it is rejected at the cap level.
8786
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8787
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8788
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8789
+ * / last-enabled, not on this bit.
8718
8790
  */
8719
8791
  var StorageLocationSchema = object({
8720
8792
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13049,6 +13121,12 @@ method(object({
13049
13121
  }), _void(), {
13050
13122
  kind: "mutation",
13051
13123
  auth: "admin"
13124
+ }), method(object({
13125
+ from: string(),
13126
+ to: string()
13127
+ }), object({ moved: number() }), {
13128
+ kind: "mutation",
13129
+ auth: "admin"
13052
13130
  }), method(object({
13053
13131
  deviceId: number(),
13054
13132
  disabled: boolean()
@@ -15761,6 +15839,8 @@ var NcSystemEventKindSchema = _enum([
15761
15839
  "device-offline",
15762
15840
  "device-disabled",
15763
15841
  "device-enabled",
15842
+ "device-battery-low",
15843
+ "device-battery-normal",
15764
15844
  "stream-online",
15765
15845
  "stream-offline",
15766
15846
  "node-online",
@@ -18995,46 +19075,6 @@ var RecentTracksPageSchema = object({
18995
19075
  /** Cursor for the next page, or null when this page is the last. */
18996
19076
  nextCursor: string().nullable()
18997
19077
  });
18998
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18999
- var LIST_GROUPS_MAX_LIMIT = 100;
19000
- var AnalyticsGroupRecordSchema = object({
19001
- id: string(),
19002
- deviceId: number().int(),
19003
- openedAt: number().int(),
19004
- closedAt: number().int(),
19005
- timestamp: number().int(),
19006
- memberCount: number().int(),
19007
- memberTrackIds: array(string()).readonly(),
19008
- className: string(),
19009
- classes: array(string()).readonly(),
19010
- /** Relative event-media path, or null when the group has no picture yet. */
19011
- mediaUrl: string().nullable(),
19012
- singleton: boolean()
19013
- });
19014
- var AnalyticsGroupMemberSchema = object({
19015
- trackId: string(),
19016
- deviceId: number().int(),
19017
- className: string(),
19018
- firstSeen: number().int(),
19019
- lastSeen: number().int(),
19020
- mediaUrl: string().nullable()
19021
- });
19022
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19023
- var ListGroupsQueryInput = object({
19024
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19025
- deviceIds: array(number()),
19026
- /** Window lower bound on `closedAt` (inclusive). */
19027
- since: number().optional(),
19028
- /** Window upper bound on `openedAt` (inclusive). */
19029
- until: number().optional(),
19030
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19031
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19032
- cursor: string().optional()
19033
- });
19034
- var ListGroupsPageSchema = object({
19035
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19036
- nextCursor: string().nullable()
19037
- });
19038
19078
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19039
19079
  var KEY_EVENTS_MAX_LIMIT = 200;
19040
19080
  var KeyEventQueryInput = object({
@@ -19138,9 +19178,7 @@ var TrackCascadeCountsSchema = object({
19138
19178
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19139
19179
  plates: number().int(),
19140
19180
  /** Per-track CLIP search vectors removed (best-effort). */
19141
- embeddings: number().int(),
19142
- /** Group membership + group rows removed with their last member (best-effort). */
19143
- groups: number().int()
19181
+ embeddings: number().int()
19144
19182
  });
19145
19183
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19146
19184
  var DiskReconcileCountsSchema = object({
@@ -19310,6 +19348,47 @@ var RebuildStatusSchema = object({
19310
19348
  /** Present when the pass ended by throwing. */
19311
19349
  error: string().nullable()
19312
19350
  });
19351
+ /**
19352
+ * Acknowledgement that a debug-media reclaim STARTED.
19353
+ *
19354
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19355
+ * it runs detached and this returns immediately. Awaiting it is how the
19356
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19357
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19358
+ */
19359
+ var MediaReclaimStartResultSchema = object({
19360
+ started: boolean(),
19361
+ /** True when a pass was already running; the new request is ignored. */
19362
+ alreadyRunning: boolean()
19363
+ });
19364
+ var MediaReclaimInputSchema = object({
19365
+ mode: _enum(["report", "reclaim"]).default("report"),
19366
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19367
+ deviceIds: array(number().int()).min(1).optional(),
19368
+ restart: boolean().optional(),
19369
+ pageSize: number().int().min(50).max(5e3).optional(),
19370
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19371
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19372
+ maxBytesPerRun: number().int().min(1).optional(),
19373
+ budgetMinutes: number().int().min(1).max(720).optional(),
19374
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19375
+ graceMinutes: number().int().min(1).max(10080).optional()
19376
+ });
19377
+ var MediaReclaimStatusSchema = object({
19378
+ running: boolean(),
19379
+ mode: _enum(["report", "reclaim"]).nullable(),
19380
+ totalExamined: number(),
19381
+ totalEligible: number(),
19382
+ totalReclaimed: number(),
19383
+ totalBytesReclaimed: number(),
19384
+ totalRefused: number(),
19385
+ /** Device+scope windows finished in this pass. */
19386
+ devicesDone: number(),
19387
+ complete: boolean().nullable(),
19388
+ startedAtMs: number().nullable(),
19389
+ finishedAtMs: number().nullable(),
19390
+ error: string().nullable()
19391
+ });
19313
19392
  var ReplayFrameInputSchema = object({
19314
19393
  timestamp: number(),
19315
19394
  frame: PipelineRunResultBridge
@@ -19348,10 +19427,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19348
19427
  * stationary registry). Default false: the timeline lists passages,
19349
19428
  * not parking records (operator decision, 2026-08-15). */
19350
19429
  includeStationary: boolean().optional()
19351
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19352
- deviceId: number(),
19353
- groupId: string().min(1)
19354
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19430
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19355
19431
  kind: "mutation",
19356
19432
  auth: "admin"
19357
19433
  }), 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({
@@ -19451,6 +19527,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19451
19527
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19452
19528
  kind: "query",
19453
19529
  auth: "admin"
19530
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19531
+ kind: "mutation",
19532
+ auth: "admin"
19533
+ }), method(object({}), MediaReclaimStatusSchema, {
19534
+ kind: "query",
19535
+ auth: "admin"
19454
19536
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19455
19537
  kind: "query",
19456
19538
  auth: "admin"
@@ -21421,7 +21503,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21421
21503
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21422
21504
  kind: "mutation",
21423
21505
  auth: "admin"
21424
- });
21506
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21507
+ kind: "mutation",
21508
+ auth: "admin"
21509
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21510
+ kind: "mutation",
21511
+ auth: "admin"
21512
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21425
21513
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21426
21514
  providerId: string().min(1),
21427
21515
  displayName: string().min(1),
@@ -26811,6 +26899,33 @@ var RecordingRebalanceInputSchema = object({
26811
26899
  minMoveGb: number().min(0).optional()
26812
26900
  });
26813
26901
  /**
26902
+ * Operator-facing placement of one camera onto a recordings location.
26903
+ *
26904
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26905
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26906
+ * currently write — the plan, which may disagree with the pin when Auto.
26907
+ */
26908
+ var RecordingDevicePlacementSchema = object({
26909
+ deviceId: number().int(),
26910
+ profile: string(),
26911
+ locationId: string()
26912
+ });
26913
+ var RecordingDevicePinSchema = object({
26914
+ deviceId: number().int(),
26915
+ /** Recordings-class location this camera is pinned to. */
26916
+ locationId: string()
26917
+ });
26918
+ var RecordingPlacementViewSchema = object({
26919
+ assignments: array(RecordingDevicePlacementSchema),
26920
+ pins: array(RecordingDevicePinSchema),
26921
+ defaultLocations: record(string(), string())
26922
+ });
26923
+ var RecordingSetDevicePlacementInputSchema = object({
26924
+ deviceId: number().int(),
26925
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26926
+ locationId: string().nullable()
26927
+ });
26928
+ /**
26814
26929
  * Result of locating footage at a wall-clock instant for one device/profile.
26815
26930
  * `segment` carries the covering segment's window; `gap` reports the forward
26816
26931
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -27036,6 +27151,12 @@ method(object({
27036
27151
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
27037
27152
  kind: "mutation",
27038
27153
  auth: "admin"
27154
+ }), method(object({}), RecordingPlacementViewSchema, {
27155
+ kind: "query",
27156
+ auth: "admin"
27157
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
27158
+ kind: "mutation",
27159
+ auth: "admin"
27039
27160
  });
27040
27161
  /**
27041
27162
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30413,6 +30534,12 @@ Object.freeze({
30413
30534
  addonId: null,
30414
30535
  access: "delete"
30415
30536
  },
30537
+ "deviceManager.renameLocation": {
30538
+ capName: "device-manager",
30539
+ capScope: "system",
30540
+ addonId: null,
30541
+ access: "create"
30542
+ },
30416
30543
  "deviceManager.runDeviceAction": {
30417
30544
  capName: "device-manager",
30418
30545
  capScope: "system",
@@ -32105,19 +32232,19 @@ Object.freeze({
32105
32232
  addonId: null,
32106
32233
  access: "view"
32107
32234
  },
32108
- "pipelineAnalytics.getGroup": {
32235
+ "pipelineAnalytics.getKeyEvents": {
32109
32236
  capName: "pipeline-analytics",
32110
32237
  capScope: "device",
32111
32238
  addonId: null,
32112
32239
  access: "view"
32113
32240
  },
32114
- "pipelineAnalytics.getKeyEvents": {
32241
+ "pipelineAnalytics.getKeyEventsBatch": {
32115
32242
  capName: "pipeline-analytics",
32116
32243
  capScope: "device",
32117
32244
  addonId: null,
32118
32245
  access: "view"
32119
32246
  },
32120
- "pipelineAnalytics.getKeyEventsBatch": {
32247
+ "pipelineAnalytics.getMediaReclaimStatus": {
32121
32248
  capName: "pipeline-analytics",
32122
32249
  capScope: "device",
32123
32250
  addonId: null,
@@ -32207,12 +32334,6 @@ Object.freeze({
32207
32334
  addonId: null,
32208
32335
  access: "view"
32209
32336
  },
32210
- "pipelineAnalytics.listGroups": {
32211
- capName: "pipeline-analytics",
32212
- capScope: "device",
32213
- addonId: null,
32214
- access: "view"
32215
- },
32216
32337
  "pipelineAnalytics.listOpsLog": {
32217
32338
  capName: "pipeline-analytics",
32218
32339
  capScope: "device",
@@ -32297,6 +32418,12 @@ Object.freeze({
32297
32418
  addonId: null,
32298
32419
  access: "create"
32299
32420
  },
32421
+ "pipelineAnalytics.reclaimDebugMedia": {
32422
+ capName: "pipeline-analytics",
32423
+ capScope: "device",
32424
+ addonId: null,
32425
+ access: "create"
32426
+ },
32300
32427
  "pipelineAnalytics.reconcileFromDisk": {
32301
32428
  capName: "pipeline-analytics",
32302
32429
  capScope: "device",
@@ -33221,6 +33348,12 @@ Object.freeze({
33221
33348
  addonId: null,
33222
33349
  access: "view"
33223
33350
  },
33351
+ "recording.getPlacement": {
33352
+ capName: "recording",
33353
+ capScope: "system",
33354
+ addonId: null,
33355
+ access: "view"
33356
+ },
33224
33357
  "recording.getPlaybackManifest": {
33225
33358
  capName: "recording",
33226
33359
  capScope: "system",
@@ -33347,6 +33480,12 @@ Object.freeze({
33347
33480
  addonId: null,
33348
33481
  access: "create"
33349
33482
  },
33483
+ "recording.setDevicePlacement": {
33484
+ capName: "recording",
33485
+ capScope: "system",
33486
+ addonId: null,
33487
+ access: "create"
33488
+ },
33350
33489
  "recording.startStorageMigrationMove": {
33351
33490
  capName: "recording",
33352
33491
  capScope: "system",
@@ -33791,12 +33930,36 @@ Object.freeze({
33791
33930
  addonId: null,
33792
33931
  access: "create"
33793
33932
  },
33933
+ "storageMigration.cleanupCancel": {
33934
+ capName: "storage-migration",
33935
+ capScope: "system",
33936
+ addonId: null,
33937
+ access: "create"
33938
+ },
33939
+ "storageMigration.cleanupStart": {
33940
+ capName: "storage-migration",
33941
+ capScope: "system",
33942
+ addonId: null,
33943
+ access: "create"
33944
+ },
33945
+ "storageMigration.cleanupStatus": {
33946
+ capName: "storage-migration",
33947
+ capScope: "system",
33948
+ addonId: null,
33949
+ access: "view"
33950
+ },
33794
33951
  "storageMigration.drain": {
33795
33952
  capName: "storage-migration",
33796
33953
  capScope: "system",
33797
33954
  addonId: null,
33798
33955
  access: "create"
33799
33956
  },
33957
+ "storageMigration.history": {
33958
+ capName: "storage-migration",
33959
+ capScope: "system",
33960
+ addonId: null,
33961
+ access: "view"
33962
+ },
33800
33963
  "storageMigration.movers": {
33801
33964
  capName: "storage-migration",
33802
33965
  capScope: "system",
@@ -35793,11 +35956,6 @@ Object.freeze({
35793
35956
  form: "single",
35794
35957
  optional: true
35795
35958
  }],
35796
- "pipelineAnalytics.getGroup": [{
35797
- name: "deviceId",
35798
- form: "single",
35799
- optional: false
35800
- }],
35801
35959
  "pipelineAnalytics.getKeyEvents": [{
35802
35960
  name: "deviceId",
35803
35961
  form: "single",
@@ -35863,11 +36021,6 @@ Object.freeze({
35863
36021
  form: "single",
35864
36022
  optional: false
35865
36023
  }],
35866
- "pipelineAnalytics.listGroups": [{
35867
- name: "deviceIds",
35868
- form: "array",
35869
- optional: false
35870
- }],
35871
36024
  "pipelineAnalytics.listOpsLog": [{
35872
36025
  name: "deviceId",
35873
36026
  form: "single",
@@ -35913,6 +36066,11 @@ Object.freeze({
35913
36066
  form: "single",
35914
36067
  optional: true
35915
36068
  }],
36069
+ "pipelineAnalytics.reclaimDebugMedia": [{
36070
+ name: "deviceIds",
36071
+ form: "array",
36072
+ optional: true
36073
+ }],
35916
36074
  "pipelineAnalytics.reconcileFromDisk": [{
35917
36075
  name: "deviceId",
35918
36076
  form: "single",
@@ -36278,6 +36436,11 @@ Object.freeze({
36278
36436
  form: "single",
36279
36437
  optional: false
36280
36438
  }],
36439
+ "recording.setDevicePlacement": [{
36440
+ name: "deviceId",
36441
+ form: "single",
36442
+ optional: false
36443
+ }],
36281
36444
  "recording.startStorageMigrationMove": [{
36282
36445
  name: "deviceId",
36283
36446
  form: "single",
@@ -8285,6 +8285,13 @@ var MediaRelocateModeSchema = _enum([
8285
8285
  ]);
8286
8286
  var RelocateMediaInputSchema = object({
8287
8287
  toLocationId: string(),
8288
+ /**
8289
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8290
+ * every row that is not already on `toLocationId` (the historical
8291
+ * behaviour). A named source is what a from→to migration needs: without it
8292
+ * "move events off disk 2" also emptied disk 1.
8293
+ */
8294
+ fromLocationId: string().optional(),
8288
8295
  throttleMbps: number().min(1).max(1e3).optional(),
8289
8296
  /** Omitted = `move`, the pre-existing behaviour. */
8290
8297
  mode: MediaRelocateModeSchema.optional()
@@ -8352,6 +8359,19 @@ var StorageMigrationDestinationsSchema = object({
8352
8359
  galleryMedia: string().min(1).optional()
8353
8360
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8354
8361
  /**
8362
+ * Optional named source per class. Omitted = the class's current default
8363
+ * (the historical behaviour). A named source that is NOT the default is a
8364
+ * drain of that disk: bytes move, the default stays, and the source is
8365
+ * disabled when the move finishes.
8366
+ */
8367
+ var StorageMigrationSourcesSchema = object({
8368
+ recordings: string().min(1).optional(),
8369
+ recordingsLow: string().min(1).optional(),
8370
+ eventMedia: string().min(1).optional(),
8371
+ backups: string().min(1).optional(),
8372
+ galleryMedia: string().min(1).optional()
8373
+ }).optional();
8374
+ /**
8355
8375
  * How a migration sequences the cutover against the byte move.
8356
8376
  *
8357
8377
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8373,6 +8393,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8373
8393
  /** Shared input for planning and starting an orchestrated storage migration. */
8374
8394
  var StorageMigrationInputSchema = object({
8375
8395
  destinations: StorageMigrationDestinationsSchema,
8396
+ /** Omitted = each class's current default. */
8397
+ sources: StorageMigrationSourcesSchema,
8376
8398
  throttleMbps: number().min(1).max(1e3).optional(),
8377
8399
  /** Omitted = `blocking`, which stays the default. */
8378
8400
  mode: StorageMigrationModeSchema.optional()
@@ -8452,6 +8474,13 @@ var StorageMigrationMoveSchema = object({
8452
8474
  storageClass: StorageMigrationClassSchema,
8453
8475
  fromLocationId: string(),
8454
8476
  toLocationId: string(),
8477
+ /**
8478
+ * True when `from` was NOT the class default at plan time. The move still
8479
+ * copies bytes, but the default is left alone and the source is disabled
8480
+ * once the copy verifies. Absent on jobs planned before this field existed
8481
+ * — those jobs always repointed, which is `false`.
8482
+ */
8483
+ freezeSource: boolean().optional(),
8455
8484
  moverJobId: string().nullable(),
8456
8485
  state: RelocateJobStateSchema.nullable(),
8457
8486
  error: string().nullable(),
@@ -8465,6 +8494,7 @@ var StorageMigrationJobSchema = object({
8465
8494
  * can tell a seconds-long cutover from a thirty-hour one. */
8466
8495
  mode: StorageMigrationModeSchema,
8467
8496
  destinations: StorageMigrationDestinationsSchema,
8497
+ sources: StorageMigrationSourcesSchema,
8468
8498
  throttleMbps: number(),
8469
8499
  moves: array(StorageMigrationMoveSchema),
8470
8500
  pauseLeaseId: string().nullable(),
@@ -8490,6 +8520,7 @@ var StorageMigrationFindingSchema = object({
8490
8520
  });
8491
8521
  var StorageMigrationPlanSchema = object({
8492
8522
  destinations: StorageMigrationDestinationsSchema,
8523
+ sources: StorageMigrationSourcesSchema,
8493
8524
  /** The mode this plan was built for. A plan is only valid for its mode: the
8494
8525
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8495
8526
  * it. */
@@ -8497,7 +8528,8 @@ var StorageMigrationPlanSchema = object({
8497
8528
  moves: array(object({
8498
8529
  storageClass: StorageMigrationClassSchema,
8499
8530
  fromLocationId: string(),
8500
- toLocationId: string()
8531
+ toLocationId: string(),
8532
+ freezeSource: boolean().optional()
8501
8533
  })),
8502
8534
  findings: array(StorageMigrationFindingSchema)
8503
8535
  });
@@ -8675,10 +8707,51 @@ var LedgerWalkReportSchema = object({
8675
8707
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8676
8708
  var RelocatableMediaCountInputSchema = object({
8677
8709
  toLocationId: string().min(1),
8710
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8711
+ fromLocationId: string().optional(),
8678
8712
  /** Omitted = `move`. */
8679
8713
  mode: MediaRelocateModeSchema.optional()
8680
8714
  });
8681
8715
  /**
8716
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8717
+ * ghost ledger entries on frozen footage locations.
8718
+ *
8719
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8720
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8721
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8722
+ * with no operator-visible status.
8723
+ */
8724
+ var StorageCleanupPhaseSchema = _enum([
8725
+ "orphans",
8726
+ "debug-media",
8727
+ "ghost-ledger",
8728
+ "done",
8729
+ "failed",
8730
+ "cancelled"
8731
+ ]);
8732
+ var StorageCleanupInputSchema = object({
8733
+ /** Also walk motion stills / track filmstrips. Off by default. */
8734
+ includeDebugMedia: boolean().optional() });
8735
+ var StorageCleanupJobSchema = object({
8736
+ jobId: string(),
8737
+ phase: StorageCleanupPhaseSchema,
8738
+ includeDebugMedia: boolean(),
8739
+ orphansReclaimed: number().int().nonnegative(),
8740
+ orphanBytesReclaimed: number().int().nonnegative(),
8741
+ debugMediaReclaimed: number().int().nonnegative(),
8742
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8743
+ ghostsForgotten: number().int().nonnegative(),
8744
+ ghostBytesForgotten: number().int().nonnegative(),
8745
+ /** Short operator-facing line: current collection, pass, or location. */
8746
+ detail: string().nullable(),
8747
+ cancelRequested: boolean(),
8748
+ startedAt: number(),
8749
+ updatedAt: number(),
8750
+ finishedAt: number().nullable(),
8751
+ error: string().nullable()
8752
+ });
8753
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8754
+ /**
8682
8755
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8683
8756
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8684
8757
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8706,11 +8779,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8706
8779
  * The default location for a type uses `id === <type>:default` by
8707
8780
  * convention (the bare type ref like `'backups'` resolves to it).
8708
8781
  *
8709
- * `isSystem: true` marks a location as orchestrator-seeded and
8710
- * undeletable. The bootstrap-installed defaults (one per type) carry
8711
- * this flag; operator-added locations don't. Editing the config of
8712
- * a system location is allowed (path migration, provider swap) but
8713
- * deleting it is rejected at the cap level.
8782
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8783
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8784
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8785
+ * / last-enabled, not on this bit.
8714
8786
  */
8715
8787
  var StorageLocationSchema = object({
8716
8788
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13045,6 +13117,12 @@ method(object({
13045
13117
  }), _void(), {
13046
13118
  kind: "mutation",
13047
13119
  auth: "admin"
13120
+ }), method(object({
13121
+ from: string(),
13122
+ to: string()
13123
+ }), object({ moved: number() }), {
13124
+ kind: "mutation",
13125
+ auth: "admin"
13048
13126
  }), method(object({
13049
13127
  deviceId: number(),
13050
13128
  disabled: boolean()
@@ -15757,6 +15835,8 @@ var NcSystemEventKindSchema = _enum([
15757
15835
  "device-offline",
15758
15836
  "device-disabled",
15759
15837
  "device-enabled",
15838
+ "device-battery-low",
15839
+ "device-battery-normal",
15760
15840
  "stream-online",
15761
15841
  "stream-offline",
15762
15842
  "node-online",
@@ -18991,46 +19071,6 @@ var RecentTracksPageSchema = object({
18991
19071
  /** Cursor for the next page, or null when this page is the last. */
18992
19072
  nextCursor: string().nullable()
18993
19073
  });
18994
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18995
- var LIST_GROUPS_MAX_LIMIT = 100;
18996
- var AnalyticsGroupRecordSchema = object({
18997
- id: string(),
18998
- deviceId: number().int(),
18999
- openedAt: number().int(),
19000
- closedAt: number().int(),
19001
- timestamp: number().int(),
19002
- memberCount: number().int(),
19003
- memberTrackIds: array(string()).readonly(),
19004
- className: string(),
19005
- classes: array(string()).readonly(),
19006
- /** Relative event-media path, or null when the group has no picture yet. */
19007
- mediaUrl: string().nullable(),
19008
- singleton: boolean()
19009
- });
19010
- var AnalyticsGroupMemberSchema = object({
19011
- trackId: string(),
19012
- deviceId: number().int(),
19013
- className: string(),
19014
- firstSeen: number().int(),
19015
- lastSeen: number().int(),
19016
- mediaUrl: string().nullable()
19017
- });
19018
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19019
- var ListGroupsQueryInput = object({
19020
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19021
- deviceIds: array(number()),
19022
- /** Window lower bound on `closedAt` (inclusive). */
19023
- since: number().optional(),
19024
- /** Window upper bound on `openedAt` (inclusive). */
19025
- until: number().optional(),
19026
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19027
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19028
- cursor: string().optional()
19029
- });
19030
- var ListGroupsPageSchema = object({
19031
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19032
- nextCursor: string().nullable()
19033
- });
19034
19074
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19035
19075
  var KEY_EVENTS_MAX_LIMIT = 200;
19036
19076
  var KeyEventQueryInput = object({
@@ -19134,9 +19174,7 @@ var TrackCascadeCountsSchema = object({
19134
19174
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19135
19175
  plates: number().int(),
19136
19176
  /** Per-track CLIP search vectors removed (best-effort). */
19137
- embeddings: number().int(),
19138
- /** Group membership + group rows removed with their last member (best-effort). */
19139
- groups: number().int()
19177
+ embeddings: number().int()
19140
19178
  });
19141
19179
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19142
19180
  var DiskReconcileCountsSchema = object({
@@ -19306,6 +19344,47 @@ var RebuildStatusSchema = object({
19306
19344
  /** Present when the pass ended by throwing. */
19307
19345
  error: string().nullable()
19308
19346
  });
19347
+ /**
19348
+ * Acknowledgement that a debug-media reclaim STARTED.
19349
+ *
19350
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19351
+ * it runs detached and this returns immediately. Awaiting it is how the
19352
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19353
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19354
+ */
19355
+ var MediaReclaimStartResultSchema = object({
19356
+ started: boolean(),
19357
+ /** True when a pass was already running; the new request is ignored. */
19358
+ alreadyRunning: boolean()
19359
+ });
19360
+ var MediaReclaimInputSchema = object({
19361
+ mode: _enum(["report", "reclaim"]).default("report"),
19362
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19363
+ deviceIds: array(number().int()).min(1).optional(),
19364
+ restart: boolean().optional(),
19365
+ pageSize: number().int().min(50).max(5e3).optional(),
19366
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19367
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19368
+ maxBytesPerRun: number().int().min(1).optional(),
19369
+ budgetMinutes: number().int().min(1).max(720).optional(),
19370
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19371
+ graceMinutes: number().int().min(1).max(10080).optional()
19372
+ });
19373
+ var MediaReclaimStatusSchema = object({
19374
+ running: boolean(),
19375
+ mode: _enum(["report", "reclaim"]).nullable(),
19376
+ totalExamined: number(),
19377
+ totalEligible: number(),
19378
+ totalReclaimed: number(),
19379
+ totalBytesReclaimed: number(),
19380
+ totalRefused: number(),
19381
+ /** Device+scope windows finished in this pass. */
19382
+ devicesDone: number(),
19383
+ complete: boolean().nullable(),
19384
+ startedAtMs: number().nullable(),
19385
+ finishedAtMs: number().nullable(),
19386
+ error: string().nullable()
19387
+ });
19309
19388
  var ReplayFrameInputSchema = object({
19310
19389
  timestamp: number(),
19311
19390
  frame: PipelineRunResultBridge
@@ -19344,10 +19423,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19344
19423
  * stationary registry). Default false: the timeline lists passages,
19345
19424
  * not parking records (operator decision, 2026-08-15). */
19346
19425
  includeStationary: boolean().optional()
19347
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19348
- deviceId: number(),
19349
- groupId: string().min(1)
19350
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19426
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19351
19427
  kind: "mutation",
19352
19428
  auth: "admin"
19353
19429
  }), 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({
@@ -19447,6 +19523,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19447
19523
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19448
19524
  kind: "query",
19449
19525
  auth: "admin"
19526
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19527
+ kind: "mutation",
19528
+ auth: "admin"
19529
+ }), method(object({}), MediaReclaimStatusSchema, {
19530
+ kind: "query",
19531
+ auth: "admin"
19450
19532
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19451
19533
  kind: "query",
19452
19534
  auth: "admin"
@@ -21417,7 +21499,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21417
21499
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21418
21500
  kind: "mutation",
21419
21501
  auth: "admin"
21420
- });
21502
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21503
+ kind: "mutation",
21504
+ auth: "admin"
21505
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21506
+ kind: "mutation",
21507
+ auth: "admin"
21508
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21421
21509
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21422
21510
  providerId: string().min(1),
21423
21511
  displayName: string().min(1),
@@ -26807,6 +26895,33 @@ var RecordingRebalanceInputSchema = object({
26807
26895
  minMoveGb: number().min(0).optional()
26808
26896
  });
26809
26897
  /**
26898
+ * Operator-facing placement of one camera onto a recordings location.
26899
+ *
26900
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26901
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26902
+ * currently write — the plan, which may disagree with the pin when Auto.
26903
+ */
26904
+ var RecordingDevicePlacementSchema = object({
26905
+ deviceId: number().int(),
26906
+ profile: string(),
26907
+ locationId: string()
26908
+ });
26909
+ var RecordingDevicePinSchema = object({
26910
+ deviceId: number().int(),
26911
+ /** Recordings-class location this camera is pinned to. */
26912
+ locationId: string()
26913
+ });
26914
+ var RecordingPlacementViewSchema = object({
26915
+ assignments: array(RecordingDevicePlacementSchema),
26916
+ pins: array(RecordingDevicePinSchema),
26917
+ defaultLocations: record(string(), string())
26918
+ });
26919
+ var RecordingSetDevicePlacementInputSchema = object({
26920
+ deviceId: number().int(),
26921
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26922
+ locationId: string().nullable()
26923
+ });
26924
+ /**
26810
26925
  * Result of locating footage at a wall-clock instant for one device/profile.
26811
26926
  * `segment` carries the covering segment's window; `gap` reports the forward
26812
26927
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -27032,6 +27147,12 @@ method(object({
27032
27147
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
27033
27148
  kind: "mutation",
27034
27149
  auth: "admin"
27150
+ }), method(object({}), RecordingPlacementViewSchema, {
27151
+ kind: "query",
27152
+ auth: "admin"
27153
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
27154
+ kind: "mutation",
27155
+ auth: "admin"
27035
27156
  });
27036
27157
  /**
27037
27158
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30409,6 +30530,12 @@ Object.freeze({
30409
30530
  addonId: null,
30410
30531
  access: "delete"
30411
30532
  },
30533
+ "deviceManager.renameLocation": {
30534
+ capName: "device-manager",
30535
+ capScope: "system",
30536
+ addonId: null,
30537
+ access: "create"
30538
+ },
30412
30539
  "deviceManager.runDeviceAction": {
30413
30540
  capName: "device-manager",
30414
30541
  capScope: "system",
@@ -32101,19 +32228,19 @@ Object.freeze({
32101
32228
  addonId: null,
32102
32229
  access: "view"
32103
32230
  },
32104
- "pipelineAnalytics.getGroup": {
32231
+ "pipelineAnalytics.getKeyEvents": {
32105
32232
  capName: "pipeline-analytics",
32106
32233
  capScope: "device",
32107
32234
  addonId: null,
32108
32235
  access: "view"
32109
32236
  },
32110
- "pipelineAnalytics.getKeyEvents": {
32237
+ "pipelineAnalytics.getKeyEventsBatch": {
32111
32238
  capName: "pipeline-analytics",
32112
32239
  capScope: "device",
32113
32240
  addonId: null,
32114
32241
  access: "view"
32115
32242
  },
32116
- "pipelineAnalytics.getKeyEventsBatch": {
32243
+ "pipelineAnalytics.getMediaReclaimStatus": {
32117
32244
  capName: "pipeline-analytics",
32118
32245
  capScope: "device",
32119
32246
  addonId: null,
@@ -32203,12 +32330,6 @@ Object.freeze({
32203
32330
  addonId: null,
32204
32331
  access: "view"
32205
32332
  },
32206
- "pipelineAnalytics.listGroups": {
32207
- capName: "pipeline-analytics",
32208
- capScope: "device",
32209
- addonId: null,
32210
- access: "view"
32211
- },
32212
32333
  "pipelineAnalytics.listOpsLog": {
32213
32334
  capName: "pipeline-analytics",
32214
32335
  capScope: "device",
@@ -32293,6 +32414,12 @@ Object.freeze({
32293
32414
  addonId: null,
32294
32415
  access: "create"
32295
32416
  },
32417
+ "pipelineAnalytics.reclaimDebugMedia": {
32418
+ capName: "pipeline-analytics",
32419
+ capScope: "device",
32420
+ addonId: null,
32421
+ access: "create"
32422
+ },
32296
32423
  "pipelineAnalytics.reconcileFromDisk": {
32297
32424
  capName: "pipeline-analytics",
32298
32425
  capScope: "device",
@@ -33217,6 +33344,12 @@ Object.freeze({
33217
33344
  addonId: null,
33218
33345
  access: "view"
33219
33346
  },
33347
+ "recording.getPlacement": {
33348
+ capName: "recording",
33349
+ capScope: "system",
33350
+ addonId: null,
33351
+ access: "view"
33352
+ },
33220
33353
  "recording.getPlaybackManifest": {
33221
33354
  capName: "recording",
33222
33355
  capScope: "system",
@@ -33343,6 +33476,12 @@ Object.freeze({
33343
33476
  addonId: null,
33344
33477
  access: "create"
33345
33478
  },
33479
+ "recording.setDevicePlacement": {
33480
+ capName: "recording",
33481
+ capScope: "system",
33482
+ addonId: null,
33483
+ access: "create"
33484
+ },
33346
33485
  "recording.startStorageMigrationMove": {
33347
33486
  capName: "recording",
33348
33487
  capScope: "system",
@@ -33787,12 +33926,36 @@ Object.freeze({
33787
33926
  addonId: null,
33788
33927
  access: "create"
33789
33928
  },
33929
+ "storageMigration.cleanupCancel": {
33930
+ capName: "storage-migration",
33931
+ capScope: "system",
33932
+ addonId: null,
33933
+ access: "create"
33934
+ },
33935
+ "storageMigration.cleanupStart": {
33936
+ capName: "storage-migration",
33937
+ capScope: "system",
33938
+ addonId: null,
33939
+ access: "create"
33940
+ },
33941
+ "storageMigration.cleanupStatus": {
33942
+ capName: "storage-migration",
33943
+ capScope: "system",
33944
+ addonId: null,
33945
+ access: "view"
33946
+ },
33790
33947
  "storageMigration.drain": {
33791
33948
  capName: "storage-migration",
33792
33949
  capScope: "system",
33793
33950
  addonId: null,
33794
33951
  access: "create"
33795
33952
  },
33953
+ "storageMigration.history": {
33954
+ capName: "storage-migration",
33955
+ capScope: "system",
33956
+ addonId: null,
33957
+ access: "view"
33958
+ },
33796
33959
  "storageMigration.movers": {
33797
33960
  capName: "storage-migration",
33798
33961
  capScope: "system",
@@ -35789,11 +35952,6 @@ Object.freeze({
35789
35952
  form: "single",
35790
35953
  optional: true
35791
35954
  }],
35792
- "pipelineAnalytics.getGroup": [{
35793
- name: "deviceId",
35794
- form: "single",
35795
- optional: false
35796
- }],
35797
35955
  "pipelineAnalytics.getKeyEvents": [{
35798
35956
  name: "deviceId",
35799
35957
  form: "single",
@@ -35859,11 +36017,6 @@ Object.freeze({
35859
36017
  form: "single",
35860
36018
  optional: false
35861
36019
  }],
35862
- "pipelineAnalytics.listGroups": [{
35863
- name: "deviceIds",
35864
- form: "array",
35865
- optional: false
35866
- }],
35867
36020
  "pipelineAnalytics.listOpsLog": [{
35868
36021
  name: "deviceId",
35869
36022
  form: "single",
@@ -35909,6 +36062,11 @@ Object.freeze({
35909
36062
  form: "single",
35910
36063
  optional: true
35911
36064
  }],
36065
+ "pipelineAnalytics.reclaimDebugMedia": [{
36066
+ name: "deviceIds",
36067
+ form: "array",
36068
+ optional: true
36069
+ }],
35912
36070
  "pipelineAnalytics.reconcileFromDisk": [{
35913
36071
  name: "deviceId",
35914
36072
  form: "single",
@@ -36274,6 +36432,11 @@ Object.freeze({
36274
36432
  form: "single",
36275
36433
  optional: false
36276
36434
  }],
36435
+ "recording.setDevicePlacement": [{
36436
+ name: "deviceId",
36437
+ form: "single",
36438
+ optional: false
36439
+ }],
36277
36440
  "recording.startStorageMigrationMove": [{
36278
36441
  name: "deviceId",
36279
36442
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-google",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Google Home export — hub-side smart-home fulfillment (SYNC / QUERY / EXECUTE / DISCONNECT) for the non-camera fleet, served over the hub's own OAuth account link. No Google credential is stored, sent or required.",
5
5
  "keywords": [
6
6
  "camstack",