@camstack/addon-provider-homeassistant 1.2.62 → 1.2.63

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.
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-u1L6UZmY.js");
2
+ const require_dist = require("./dist-D8uo_M4x.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-device-source.ts
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as presenceCapability, A as controlCapability, At as EventCategory, B as humiditySensorCapability, C as buildAddonRouteProvider, Ct as number, D as colorCapability, Dt as union, E as climateControlCapability, Et as string, F as eventEmitterCapability, G as motionCapability, H as lawnMowerControlCapability, I as fanControlCapability, J as notifierCapability, K as normalizeUnit, L as floodCapability, M as deviceAdoptionCapability, O as connectivityCapability, Ot as unknown, P as enumSensorCapability, Q as prepareNotification, R as gasCapability, S as brokerCapability, St as literal, T as carbonMonoxideCapability, Tt as record, U as lockControlCapability, V as imageCapability, W as mediaPlayerCapability, Y as numericSensorCapability, Z as powerMeterCapability, _ as automationControlCapability, _t as createEvent, at as temperatureSensorCapability, b as binaryCapability, bt as array, ct as valveCapability, d as TargetSchema, dt as weatherCapability, et as pressureSensorCapability, f as accessoriesCapability, ft as errMsg, g as ambientLightSensorCapability, gt as DeviceType, h as alarmPanelCapability, ht as DeviceRole, it as tamperCapability, j as coverCapability, k as contactCapability, kt as url, lt as vibrationCapability, m as airQualitySensorCapability, mt as DeviceFeature, n as BaseDevice, nt as smokeCapability, ot as updateCapability, p as addonRoutesCapability, q as notificationOutputCapability, r as BaseDeviceProvider, rt as switchCapability, s as EnumSensorDateTimeFormatSchema, st as vacuumControlCapability, tt as scriptRunnerCapability, ut as waterHeaterCapability, v as batteryCapability, w as buttonCapability, wt as object, x as brightnessCapability, xt as discriminatedUnion, y as bestLocationMatch, yt as _enum, z as humidifierCapability } from "./dist-DV4Xqi_x.mjs";
1
+ import { $ as presenceCapability, A as controlCapability, At as EventCategory, B as humiditySensorCapability, C as buildAddonRouteProvider, Ct as number, D as colorCapability, Dt as union, E as climateControlCapability, Et as string, F as eventEmitterCapability, G as motionCapability, H as lawnMowerControlCapability, I as fanControlCapability, J as notifierCapability, K as normalizeUnit, L as floodCapability, M as deviceAdoptionCapability, O as connectivityCapability, Ot as unknown, P as enumSensorCapability, Q as prepareNotification, R as gasCapability, S as brokerCapability, St as literal, T as carbonMonoxideCapability, Tt as record, U as lockControlCapability, V as imageCapability, W as mediaPlayerCapability, Y as numericSensorCapability, Z as powerMeterCapability, _ as automationControlCapability, _t as createEvent, at as temperatureSensorCapability, b as binaryCapability, bt as array, ct as valveCapability, d as TargetSchema, dt as weatherCapability, et as pressureSensorCapability, f as accessoriesCapability, ft as errMsg, g as ambientLightSensorCapability, gt as DeviceType, h as alarmPanelCapability, ht as DeviceRole, it as tamperCapability, j as coverCapability, k as contactCapability, kt as url, lt as vibrationCapability, m as airQualitySensorCapability, mt as DeviceFeature, n as BaseDevice, nt as smokeCapability, ot as updateCapability, p as addonRoutesCapability, q as notificationOutputCapability, r as BaseDeviceProvider, rt as switchCapability, s as EnumSensorDateTimeFormatSchema, st as vacuumControlCapability, tt as scriptRunnerCapability, ut as waterHeaterCapability, v as batteryCapability, w as buttonCapability, wt as object, x as brightnessCapability, xt as discriminatedUnion, y as bestLocationMatch, yt as _enum, z as humidifierCapability } from "./dist-COgdwHQp.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
4
4
  //#region src/ha-device-source.ts
@@ -8299,6 +8299,13 @@ var MediaRelocateModeSchema = _enum([
8299
8299
  ]);
8300
8300
  var RelocateMediaInputSchema = object({
8301
8301
  toLocationId: string(),
8302
+ /**
8303
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8304
+ * every row that is not already on `toLocationId` (the historical
8305
+ * behaviour). A named source is what a from→to migration needs: without it
8306
+ * "move events off disk 2" also emptied disk 1.
8307
+ */
8308
+ fromLocationId: string().optional(),
8302
8309
  throttleMbps: number().min(1).max(1e3).optional(),
8303
8310
  /** Omitted = `move`, the pre-existing behaviour. */
8304
8311
  mode: MediaRelocateModeSchema.optional()
@@ -8366,6 +8373,19 @@ var StorageMigrationDestinationsSchema = object({
8366
8373
  galleryMedia: string().min(1).optional()
8367
8374
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8368
8375
  /**
8376
+ * Optional named source per class. Omitted = the class's current default
8377
+ * (the historical behaviour). A named source that is NOT the default is a
8378
+ * drain of that disk: bytes move, the default stays, and the source is
8379
+ * disabled when the move finishes.
8380
+ */
8381
+ var StorageMigrationSourcesSchema = object({
8382
+ recordings: string().min(1).optional(),
8383
+ recordingsLow: string().min(1).optional(),
8384
+ eventMedia: string().min(1).optional(),
8385
+ backups: string().min(1).optional(),
8386
+ galleryMedia: string().min(1).optional()
8387
+ }).optional();
8388
+ /**
8369
8389
  * How a migration sequences the cutover against the byte move.
8370
8390
  *
8371
8391
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8387,6 +8407,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8387
8407
  /** Shared input for planning and starting an orchestrated storage migration. */
8388
8408
  var StorageMigrationInputSchema = object({
8389
8409
  destinations: StorageMigrationDestinationsSchema,
8410
+ /** Omitted = each class's current default. */
8411
+ sources: StorageMigrationSourcesSchema,
8390
8412
  throttleMbps: number().min(1).max(1e3).optional(),
8391
8413
  /** Omitted = `blocking`, which stays the default. */
8392
8414
  mode: StorageMigrationModeSchema.optional()
@@ -8466,6 +8488,13 @@ var StorageMigrationMoveSchema = object({
8466
8488
  storageClass: StorageMigrationClassSchema,
8467
8489
  fromLocationId: string(),
8468
8490
  toLocationId: string(),
8491
+ /**
8492
+ * True when `from` was NOT the class default at plan time. The move still
8493
+ * copies bytes, but the default is left alone and the source is disabled
8494
+ * once the copy verifies. Absent on jobs planned before this field existed
8495
+ * — those jobs always repointed, which is `false`.
8496
+ */
8497
+ freezeSource: boolean().optional(),
8469
8498
  moverJobId: string().nullable(),
8470
8499
  state: RelocateJobStateSchema.nullable(),
8471
8500
  error: string().nullable(),
@@ -8479,6 +8508,7 @@ var StorageMigrationJobSchema = object({
8479
8508
  * can tell a seconds-long cutover from a thirty-hour one. */
8480
8509
  mode: StorageMigrationModeSchema,
8481
8510
  destinations: StorageMigrationDestinationsSchema,
8511
+ sources: StorageMigrationSourcesSchema,
8482
8512
  throttleMbps: number(),
8483
8513
  moves: array(StorageMigrationMoveSchema),
8484
8514
  pauseLeaseId: string().nullable(),
@@ -8504,6 +8534,7 @@ var StorageMigrationFindingSchema = object({
8504
8534
  });
8505
8535
  var StorageMigrationPlanSchema = object({
8506
8536
  destinations: StorageMigrationDestinationsSchema,
8537
+ sources: StorageMigrationSourcesSchema,
8507
8538
  /** The mode this plan was built for. A plan is only valid for its mode: the
8508
8539
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8509
8540
  * it. */
@@ -8511,7 +8542,8 @@ var StorageMigrationPlanSchema = object({
8511
8542
  moves: array(object({
8512
8543
  storageClass: StorageMigrationClassSchema,
8513
8544
  fromLocationId: string(),
8514
- toLocationId: string()
8545
+ toLocationId: string(),
8546
+ freezeSource: boolean().optional()
8515
8547
  })),
8516
8548
  findings: array(StorageMigrationFindingSchema)
8517
8549
  });
@@ -8689,10 +8721,51 @@ var LedgerWalkReportSchema = object({
8689
8721
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8690
8722
  var RelocatableMediaCountInputSchema = object({
8691
8723
  toLocationId: string().min(1),
8724
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8725
+ fromLocationId: string().optional(),
8692
8726
  /** Omitted = `move`. */
8693
8727
  mode: MediaRelocateModeSchema.optional()
8694
8728
  });
8695
8729
  /**
8730
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8731
+ * ghost ledger entries on frozen footage locations.
8732
+ *
8733
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8734
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8735
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8736
+ * with no operator-visible status.
8737
+ */
8738
+ var StorageCleanupPhaseSchema = _enum([
8739
+ "orphans",
8740
+ "debug-media",
8741
+ "ghost-ledger",
8742
+ "done",
8743
+ "failed",
8744
+ "cancelled"
8745
+ ]);
8746
+ var StorageCleanupInputSchema = object({
8747
+ /** Also walk motion stills / track filmstrips. Off by default. */
8748
+ includeDebugMedia: boolean().optional() });
8749
+ var StorageCleanupJobSchema = object({
8750
+ jobId: string(),
8751
+ phase: StorageCleanupPhaseSchema,
8752
+ includeDebugMedia: boolean(),
8753
+ orphansReclaimed: number().int().nonnegative(),
8754
+ orphanBytesReclaimed: number().int().nonnegative(),
8755
+ debugMediaReclaimed: number().int().nonnegative(),
8756
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8757
+ ghostsForgotten: number().int().nonnegative(),
8758
+ ghostBytesForgotten: number().int().nonnegative(),
8759
+ /** Short operator-facing line: current collection, pass, or location. */
8760
+ detail: string().nullable(),
8761
+ cancelRequested: boolean(),
8762
+ startedAt: number(),
8763
+ updatedAt: number(),
8764
+ finishedAt: number().nullable(),
8765
+ error: string().nullable()
8766
+ });
8767
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8768
+ /**
8696
8769
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8697
8770
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8698
8771
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8720,11 +8793,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8720
8793
  * The default location for a type uses `id === <type>:default` by
8721
8794
  * convention (the bare type ref like `'backups'` resolves to it).
8722
8795
  *
8723
- * `isSystem: true` marks a location as orchestrator-seeded and
8724
- * undeletable. The bootstrap-installed defaults (one per type) carry
8725
- * this flag; operator-added locations don't. Editing the config of
8726
- * a system location is allowed (path migration, provider swap) but
8727
- * deleting it is rejected at the cap level.
8796
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8797
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8798
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8799
+ * / last-enabled, not on this bit.
8728
8800
  */
8729
8801
  var StorageLocationSchema = object({
8730
8802
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13405,6 +13477,12 @@ method(object({
13405
13477
  }), _void(), {
13406
13478
  kind: "mutation",
13407
13479
  auth: "admin"
13480
+ }), method(object({
13481
+ from: string(),
13482
+ to: string()
13483
+ }), object({ moved: number() }), {
13484
+ kind: "mutation",
13485
+ auth: "admin"
13408
13486
  }), method(object({
13409
13487
  deviceId: number(),
13410
13488
  disabled: boolean()
@@ -19443,46 +19521,6 @@ var RecentTracksPageSchema = object({
19443
19521
  /** Cursor for the next page, or null when this page is the last. */
19444
19522
  nextCursor: string().nullable()
19445
19523
  });
19446
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19447
- var LIST_GROUPS_MAX_LIMIT = 100;
19448
- var AnalyticsGroupRecordSchema = object({
19449
- id: string(),
19450
- deviceId: number().int(),
19451
- openedAt: number().int(),
19452
- closedAt: number().int(),
19453
- timestamp: number().int(),
19454
- memberCount: number().int(),
19455
- memberTrackIds: array(string()).readonly(),
19456
- className: string(),
19457
- classes: array(string()).readonly(),
19458
- /** Relative event-media path, or null when the group has no picture yet. */
19459
- mediaUrl: string().nullable(),
19460
- singleton: boolean()
19461
- });
19462
- var AnalyticsGroupMemberSchema = object({
19463
- trackId: string(),
19464
- deviceId: number().int(),
19465
- className: string(),
19466
- firstSeen: number().int(),
19467
- lastSeen: number().int(),
19468
- mediaUrl: string().nullable()
19469
- });
19470
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19471
- var ListGroupsQueryInput = object({
19472
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19473
- deviceIds: array(number()),
19474
- /** Window lower bound on `closedAt` (inclusive). */
19475
- since: number().optional(),
19476
- /** Window upper bound on `openedAt` (inclusive). */
19477
- until: number().optional(),
19478
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19479
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19480
- cursor: string().optional()
19481
- });
19482
- var ListGroupsPageSchema = object({
19483
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19484
- nextCursor: string().nullable()
19485
- });
19486
19524
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19487
19525
  var KEY_EVENTS_MAX_LIMIT = 200;
19488
19526
  var KeyEventQueryInput = object({
@@ -19586,9 +19624,7 @@ var TrackCascadeCountsSchema = object({
19586
19624
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19587
19625
  plates: number().int(),
19588
19626
  /** Per-track CLIP search vectors removed (best-effort). */
19589
- embeddings: number().int(),
19590
- /** Group membership + group rows removed with their last member (best-effort). */
19591
- groups: number().int()
19627
+ embeddings: number().int()
19592
19628
  });
19593
19629
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19594
19630
  var DiskReconcileCountsSchema = object({
@@ -19758,6 +19794,47 @@ var RebuildStatusSchema = object({
19758
19794
  /** Present when the pass ended by throwing. */
19759
19795
  error: string().nullable()
19760
19796
  });
19797
+ /**
19798
+ * Acknowledgement that a debug-media reclaim STARTED.
19799
+ *
19800
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19801
+ * it runs detached and this returns immediately. Awaiting it is how the
19802
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19803
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19804
+ */
19805
+ var MediaReclaimStartResultSchema = object({
19806
+ started: boolean(),
19807
+ /** True when a pass was already running; the new request is ignored. */
19808
+ alreadyRunning: boolean()
19809
+ });
19810
+ var MediaReclaimInputSchema = object({
19811
+ mode: _enum(["report", "reclaim"]).default("report"),
19812
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19813
+ deviceIds: array(number().int()).min(1).optional(),
19814
+ restart: boolean().optional(),
19815
+ pageSize: number().int().min(50).max(5e3).optional(),
19816
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19817
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19818
+ maxBytesPerRun: number().int().min(1).optional(),
19819
+ budgetMinutes: number().int().min(1).max(720).optional(),
19820
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19821
+ graceMinutes: number().int().min(1).max(10080).optional()
19822
+ });
19823
+ var MediaReclaimStatusSchema = object({
19824
+ running: boolean(),
19825
+ mode: _enum(["report", "reclaim"]).nullable(),
19826
+ totalExamined: number(),
19827
+ totalEligible: number(),
19828
+ totalReclaimed: number(),
19829
+ totalBytesReclaimed: number(),
19830
+ totalRefused: number(),
19831
+ /** Device+scope windows finished in this pass. */
19832
+ devicesDone: number(),
19833
+ complete: boolean().nullable(),
19834
+ startedAtMs: number().nullable(),
19835
+ finishedAtMs: number().nullable(),
19836
+ error: string().nullable()
19837
+ });
19761
19838
  var ReplayFrameInputSchema = object({
19762
19839
  timestamp: number(),
19763
19840
  frame: PipelineRunResultBridge
@@ -19796,10 +19873,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19796
19873
  * stationary registry). Default false: the timeline lists passages,
19797
19874
  * not parking records (operator decision, 2026-08-15). */
19798
19875
  includeStationary: boolean().optional()
19799
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19800
- deviceId: number(),
19801
- groupId: string().min(1)
19802
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19876
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19803
19877
  kind: "mutation",
19804
19878
  auth: "admin"
19805
19879
  }), 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({
@@ -19899,6 +19973,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19899
19973
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19900
19974
  kind: "query",
19901
19975
  auth: "admin"
19976
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19977
+ kind: "mutation",
19978
+ auth: "admin"
19979
+ }), method(object({}), MediaReclaimStatusSchema, {
19980
+ kind: "query",
19981
+ auth: "admin"
19902
19982
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19903
19983
  kind: "query",
19904
19984
  auth: "admin"
@@ -21869,7 +21949,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21869
21949
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21870
21950
  kind: "mutation",
21871
21951
  auth: "admin"
21872
- });
21952
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21953
+ kind: "mutation",
21954
+ auth: "admin"
21955
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21956
+ kind: "mutation",
21957
+ auth: "admin"
21958
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21873
21959
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21874
21960
  providerId: string().min(1),
21875
21961
  displayName: string().min(1),
@@ -29051,6 +29137,33 @@ var RecordingRebalanceInputSchema = object({
29051
29137
  minMoveGb: number().min(0).optional()
29052
29138
  });
29053
29139
  /**
29140
+ * Operator-facing placement of one camera onto a recordings location.
29141
+ *
29142
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29143
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29144
+ * currently write — the plan, which may disagree with the pin when Auto.
29145
+ */
29146
+ var RecordingDevicePlacementSchema = object({
29147
+ deviceId: number().int(),
29148
+ profile: string(),
29149
+ locationId: string()
29150
+ });
29151
+ var RecordingDevicePinSchema = object({
29152
+ deviceId: number().int(),
29153
+ /** Recordings-class location this camera is pinned to. */
29154
+ locationId: string()
29155
+ });
29156
+ var RecordingPlacementViewSchema = object({
29157
+ assignments: array(RecordingDevicePlacementSchema),
29158
+ pins: array(RecordingDevicePinSchema),
29159
+ defaultLocations: record(string(), string())
29160
+ });
29161
+ var RecordingSetDevicePlacementInputSchema = object({
29162
+ deviceId: number().int(),
29163
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29164
+ locationId: string().nullable()
29165
+ });
29166
+ /**
29054
29167
  * Result of locating footage at a wall-clock instant for one device/profile.
29055
29168
  * `segment` carries the covering segment's window; `gap` reports the forward
29056
29169
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29276,6 +29389,12 @@ method(object({
29276
29389
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29277
29390
  kind: "mutation",
29278
29391
  auth: "admin"
29392
+ }), method(object({}), RecordingPlacementViewSchema, {
29393
+ kind: "query",
29394
+ auth: "admin"
29395
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
29396
+ kind: "mutation",
29397
+ auth: "admin"
29279
29398
  });
29280
29399
  /**
29281
29400
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34345,6 +34464,12 @@ Object.freeze({
34345
34464
  addonId: null,
34346
34465
  access: "delete"
34347
34466
  },
34467
+ "deviceManager.renameLocation": {
34468
+ capName: "device-manager",
34469
+ capScope: "system",
34470
+ addonId: null,
34471
+ access: "create"
34472
+ },
34348
34473
  "deviceManager.runDeviceAction": {
34349
34474
  capName: "device-manager",
34350
34475
  capScope: "system",
@@ -36037,19 +36162,19 @@ Object.freeze({
36037
36162
  addonId: null,
36038
36163
  access: "view"
36039
36164
  },
36040
- "pipelineAnalytics.getGroup": {
36165
+ "pipelineAnalytics.getKeyEvents": {
36041
36166
  capName: "pipeline-analytics",
36042
36167
  capScope: "device",
36043
36168
  addonId: null,
36044
36169
  access: "view"
36045
36170
  },
36046
- "pipelineAnalytics.getKeyEvents": {
36171
+ "pipelineAnalytics.getKeyEventsBatch": {
36047
36172
  capName: "pipeline-analytics",
36048
36173
  capScope: "device",
36049
36174
  addonId: null,
36050
36175
  access: "view"
36051
36176
  },
36052
- "pipelineAnalytics.getKeyEventsBatch": {
36177
+ "pipelineAnalytics.getMediaReclaimStatus": {
36053
36178
  capName: "pipeline-analytics",
36054
36179
  capScope: "device",
36055
36180
  addonId: null,
@@ -36139,12 +36264,6 @@ Object.freeze({
36139
36264
  addonId: null,
36140
36265
  access: "view"
36141
36266
  },
36142
- "pipelineAnalytics.listGroups": {
36143
- capName: "pipeline-analytics",
36144
- capScope: "device",
36145
- addonId: null,
36146
- access: "view"
36147
- },
36148
36267
  "pipelineAnalytics.listOpsLog": {
36149
36268
  capName: "pipeline-analytics",
36150
36269
  capScope: "device",
@@ -36229,6 +36348,12 @@ Object.freeze({
36229
36348
  addonId: null,
36230
36349
  access: "create"
36231
36350
  },
36351
+ "pipelineAnalytics.reclaimDebugMedia": {
36352
+ capName: "pipeline-analytics",
36353
+ capScope: "device",
36354
+ addonId: null,
36355
+ access: "create"
36356
+ },
36232
36357
  "pipelineAnalytics.reconcileFromDisk": {
36233
36358
  capName: "pipeline-analytics",
36234
36359
  capScope: "device",
@@ -37153,6 +37278,12 @@ Object.freeze({
37153
37278
  addonId: null,
37154
37279
  access: "view"
37155
37280
  },
37281
+ "recording.getPlacement": {
37282
+ capName: "recording",
37283
+ capScope: "system",
37284
+ addonId: null,
37285
+ access: "view"
37286
+ },
37156
37287
  "recording.getPlaybackManifest": {
37157
37288
  capName: "recording",
37158
37289
  capScope: "system",
@@ -37279,6 +37410,12 @@ Object.freeze({
37279
37410
  addonId: null,
37280
37411
  access: "create"
37281
37412
  },
37413
+ "recording.setDevicePlacement": {
37414
+ capName: "recording",
37415
+ capScope: "system",
37416
+ addonId: null,
37417
+ access: "create"
37418
+ },
37282
37419
  "recording.startStorageMigrationMove": {
37283
37420
  capName: "recording",
37284
37421
  capScope: "system",
@@ -37723,12 +37860,36 @@ Object.freeze({
37723
37860
  addonId: null,
37724
37861
  access: "create"
37725
37862
  },
37863
+ "storageMigration.cleanupCancel": {
37864
+ capName: "storage-migration",
37865
+ capScope: "system",
37866
+ addonId: null,
37867
+ access: "create"
37868
+ },
37869
+ "storageMigration.cleanupStart": {
37870
+ capName: "storage-migration",
37871
+ capScope: "system",
37872
+ addonId: null,
37873
+ access: "create"
37874
+ },
37875
+ "storageMigration.cleanupStatus": {
37876
+ capName: "storage-migration",
37877
+ capScope: "system",
37878
+ addonId: null,
37879
+ access: "view"
37880
+ },
37726
37881
  "storageMigration.drain": {
37727
37882
  capName: "storage-migration",
37728
37883
  capScope: "system",
37729
37884
  addonId: null,
37730
37885
  access: "create"
37731
37886
  },
37887
+ "storageMigration.history": {
37888
+ capName: "storage-migration",
37889
+ capScope: "system",
37890
+ addonId: null,
37891
+ access: "view"
37892
+ },
37732
37893
  "storageMigration.movers": {
37733
37894
  capName: "storage-migration",
37734
37895
  capScope: "system",
@@ -39725,11 +39886,6 @@ Object.freeze({
39725
39886
  form: "single",
39726
39887
  optional: true
39727
39888
  }],
39728
- "pipelineAnalytics.getGroup": [{
39729
- name: "deviceId",
39730
- form: "single",
39731
- optional: false
39732
- }],
39733
39889
  "pipelineAnalytics.getKeyEvents": [{
39734
39890
  name: "deviceId",
39735
39891
  form: "single",
@@ -39795,11 +39951,6 @@ Object.freeze({
39795
39951
  form: "single",
39796
39952
  optional: false
39797
39953
  }],
39798
- "pipelineAnalytics.listGroups": [{
39799
- name: "deviceIds",
39800
- form: "array",
39801
- optional: false
39802
- }],
39803
39954
  "pipelineAnalytics.listOpsLog": [{
39804
39955
  name: "deviceId",
39805
39956
  form: "single",
@@ -39845,6 +39996,11 @@ Object.freeze({
39845
39996
  form: "single",
39846
39997
  optional: true
39847
39998
  }],
39999
+ "pipelineAnalytics.reclaimDebugMedia": [{
40000
+ name: "deviceIds",
40001
+ form: "array",
40002
+ optional: true
40003
+ }],
39848
40004
  "pipelineAnalytics.reconcileFromDisk": [{
39849
40005
  name: "deviceId",
39850
40006
  form: "single",
@@ -40210,6 +40366,11 @@ Object.freeze({
40210
40366
  form: "single",
40211
40367
  optional: false
40212
40368
  }],
40369
+ "recording.setDevicePlacement": [{
40370
+ name: "deviceId",
40371
+ form: "single",
40372
+ optional: false
40373
+ }],
40213
40374
  "recording.startStorageMigrationMove": [{
40214
40375
  name: "deviceId",
40215
40376
  form: "single",
@@ -8299,6 +8299,13 @@ var MediaRelocateModeSchema = _enum([
8299
8299
  ]);
8300
8300
  var RelocateMediaInputSchema = object({
8301
8301
  toLocationId: string(),
8302
+ /**
8303
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8304
+ * every row that is not already on `toLocationId` (the historical
8305
+ * behaviour). A named source is what a from→to migration needs: without it
8306
+ * "move events off disk 2" also emptied disk 1.
8307
+ */
8308
+ fromLocationId: string().optional(),
8302
8309
  throttleMbps: number().min(1).max(1e3).optional(),
8303
8310
  /** Omitted = `move`, the pre-existing behaviour. */
8304
8311
  mode: MediaRelocateModeSchema.optional()
@@ -8366,6 +8373,19 @@ var StorageMigrationDestinationsSchema = object({
8366
8373
  galleryMedia: string().min(1).optional()
8367
8374
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8368
8375
  /**
8376
+ * Optional named source per class. Omitted = the class's current default
8377
+ * (the historical behaviour). A named source that is NOT the default is a
8378
+ * drain of that disk: bytes move, the default stays, and the source is
8379
+ * disabled when the move finishes.
8380
+ */
8381
+ var StorageMigrationSourcesSchema = object({
8382
+ recordings: string().min(1).optional(),
8383
+ recordingsLow: string().min(1).optional(),
8384
+ eventMedia: string().min(1).optional(),
8385
+ backups: string().min(1).optional(),
8386
+ galleryMedia: string().min(1).optional()
8387
+ }).optional();
8388
+ /**
8369
8389
  * How a migration sequences the cutover against the byte move.
8370
8390
  *
8371
8391
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8387,6 +8407,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8387
8407
  /** Shared input for planning and starting an orchestrated storage migration. */
8388
8408
  var StorageMigrationInputSchema = object({
8389
8409
  destinations: StorageMigrationDestinationsSchema,
8410
+ /** Omitted = each class's current default. */
8411
+ sources: StorageMigrationSourcesSchema,
8390
8412
  throttleMbps: number().min(1).max(1e3).optional(),
8391
8413
  /** Omitted = `blocking`, which stays the default. */
8392
8414
  mode: StorageMigrationModeSchema.optional()
@@ -8466,6 +8488,13 @@ var StorageMigrationMoveSchema = object({
8466
8488
  storageClass: StorageMigrationClassSchema,
8467
8489
  fromLocationId: string(),
8468
8490
  toLocationId: string(),
8491
+ /**
8492
+ * True when `from` was NOT the class default at plan time. The move still
8493
+ * copies bytes, but the default is left alone and the source is disabled
8494
+ * once the copy verifies. Absent on jobs planned before this field existed
8495
+ * — those jobs always repointed, which is `false`.
8496
+ */
8497
+ freezeSource: boolean().optional(),
8469
8498
  moverJobId: string().nullable(),
8470
8499
  state: RelocateJobStateSchema.nullable(),
8471
8500
  error: string().nullable(),
@@ -8479,6 +8508,7 @@ var StorageMigrationJobSchema = object({
8479
8508
  * can tell a seconds-long cutover from a thirty-hour one. */
8480
8509
  mode: StorageMigrationModeSchema,
8481
8510
  destinations: StorageMigrationDestinationsSchema,
8511
+ sources: StorageMigrationSourcesSchema,
8482
8512
  throttleMbps: number(),
8483
8513
  moves: array(StorageMigrationMoveSchema),
8484
8514
  pauseLeaseId: string().nullable(),
@@ -8504,6 +8534,7 @@ var StorageMigrationFindingSchema = object({
8504
8534
  });
8505
8535
  var StorageMigrationPlanSchema = object({
8506
8536
  destinations: StorageMigrationDestinationsSchema,
8537
+ sources: StorageMigrationSourcesSchema,
8507
8538
  /** The mode this plan was built for. A plan is only valid for its mode: the
8508
8539
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8509
8540
  * it. */
@@ -8511,7 +8542,8 @@ var StorageMigrationPlanSchema = object({
8511
8542
  moves: array(object({
8512
8543
  storageClass: StorageMigrationClassSchema,
8513
8544
  fromLocationId: string(),
8514
- toLocationId: string()
8545
+ toLocationId: string(),
8546
+ freezeSource: boolean().optional()
8515
8547
  })),
8516
8548
  findings: array(StorageMigrationFindingSchema)
8517
8549
  });
@@ -8689,10 +8721,51 @@ var LedgerWalkReportSchema = object({
8689
8721
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8690
8722
  var RelocatableMediaCountInputSchema = object({
8691
8723
  toLocationId: string().min(1),
8724
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8725
+ fromLocationId: string().optional(),
8692
8726
  /** Omitted = `move`. */
8693
8727
  mode: MediaRelocateModeSchema.optional()
8694
8728
  });
8695
8729
  /**
8730
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8731
+ * ghost ledger entries on frozen footage locations.
8732
+ *
8733
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8734
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8735
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8736
+ * with no operator-visible status.
8737
+ */
8738
+ var StorageCleanupPhaseSchema = _enum([
8739
+ "orphans",
8740
+ "debug-media",
8741
+ "ghost-ledger",
8742
+ "done",
8743
+ "failed",
8744
+ "cancelled"
8745
+ ]);
8746
+ var StorageCleanupInputSchema = object({
8747
+ /** Also walk motion stills / track filmstrips. Off by default. */
8748
+ includeDebugMedia: boolean().optional() });
8749
+ var StorageCleanupJobSchema = object({
8750
+ jobId: string(),
8751
+ phase: StorageCleanupPhaseSchema,
8752
+ includeDebugMedia: boolean(),
8753
+ orphansReclaimed: number().int().nonnegative(),
8754
+ orphanBytesReclaimed: number().int().nonnegative(),
8755
+ debugMediaReclaimed: number().int().nonnegative(),
8756
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8757
+ ghostsForgotten: number().int().nonnegative(),
8758
+ ghostBytesForgotten: number().int().nonnegative(),
8759
+ /** Short operator-facing line: current collection, pass, or location. */
8760
+ detail: string().nullable(),
8761
+ cancelRequested: boolean(),
8762
+ startedAt: number(),
8763
+ updatedAt: number(),
8764
+ finishedAt: number().nullable(),
8765
+ error: string().nullable()
8766
+ });
8767
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8768
+ /**
8696
8769
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8697
8770
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8698
8771
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8720,11 +8793,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8720
8793
  * The default location for a type uses `id === <type>:default` by
8721
8794
  * convention (the bare type ref like `'backups'` resolves to it).
8722
8795
  *
8723
- * `isSystem: true` marks a location as orchestrator-seeded and
8724
- * undeletable. The bootstrap-installed defaults (one per type) carry
8725
- * this flag; operator-added locations don't. Editing the config of
8726
- * a system location is allowed (path migration, provider swap) but
8727
- * deleting it is rejected at the cap level.
8796
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8797
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8798
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8799
+ * / last-enabled, not on this bit.
8728
8800
  */
8729
8801
  var StorageLocationSchema = object({
8730
8802
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -13405,6 +13477,12 @@ method(object({
13405
13477
  }), _void(), {
13406
13478
  kind: "mutation",
13407
13479
  auth: "admin"
13480
+ }), method(object({
13481
+ from: string(),
13482
+ to: string()
13483
+ }), object({ moved: number() }), {
13484
+ kind: "mutation",
13485
+ auth: "admin"
13408
13486
  }), method(object({
13409
13487
  deviceId: number(),
13410
13488
  disabled: boolean()
@@ -19443,46 +19521,6 @@ var RecentTracksPageSchema = object({
19443
19521
  /** Cursor for the next page, or null when this page is the last. */
19444
19522
  nextCursor: string().nullable()
19445
19523
  });
19446
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
19447
- var LIST_GROUPS_MAX_LIMIT = 100;
19448
- var AnalyticsGroupRecordSchema = object({
19449
- id: string(),
19450
- deviceId: number().int(),
19451
- openedAt: number().int(),
19452
- closedAt: number().int(),
19453
- timestamp: number().int(),
19454
- memberCount: number().int(),
19455
- memberTrackIds: array(string()).readonly(),
19456
- className: string(),
19457
- classes: array(string()).readonly(),
19458
- /** Relative event-media path, or null when the group has no picture yet. */
19459
- mediaUrl: string().nullable(),
19460
- singleton: boolean()
19461
- });
19462
- var AnalyticsGroupMemberSchema = object({
19463
- trackId: string(),
19464
- deviceId: number().int(),
19465
- className: string(),
19466
- firstSeen: number().int(),
19467
- lastSeen: number().int(),
19468
- mediaUrl: string().nullable()
19469
- });
19470
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
19471
- var ListGroupsQueryInput = object({
19472
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
19473
- deviceIds: array(number()),
19474
- /** Window lower bound on `closedAt` (inclusive). */
19475
- since: number().optional(),
19476
- /** Window upper bound on `openedAt` (inclusive). */
19477
- until: number().optional(),
19478
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
19479
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
19480
- cursor: string().optional()
19481
- });
19482
- var ListGroupsPageSchema = object({
19483
- groups: array(AnalyticsGroupRecordSchema).readonly(),
19484
- nextCursor: string().nullable()
19485
- });
19486
19524
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
19487
19525
  var KEY_EVENTS_MAX_LIMIT = 200;
19488
19526
  var KeyEventQueryInput = object({
@@ -19586,9 +19624,7 @@ var TrackCascadeCountsSchema = object({
19586
19624
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
19587
19625
  plates: number().int(),
19588
19626
  /** Per-track CLIP search vectors removed (best-effort). */
19589
- embeddings: number().int(),
19590
- /** Group membership + group rows removed with their last member (best-effort). */
19591
- groups: number().int()
19627
+ embeddings: number().int()
19592
19628
  });
19593
19629
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
19594
19630
  var DiskReconcileCountsSchema = object({
@@ -19758,6 +19794,47 @@ var RebuildStatusSchema = object({
19758
19794
  /** Present when the pass ended by throwing. */
19759
19795
  error: string().nullable()
19760
19796
  });
19797
+ /**
19798
+ * Acknowledgement that a debug-media reclaim STARTED.
19799
+ *
19800
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19801
+ * it runs detached and this returns immediately. Awaiting it is how the
19802
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19803
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19804
+ */
19805
+ var MediaReclaimStartResultSchema = object({
19806
+ started: boolean(),
19807
+ /** True when a pass was already running; the new request is ignored. */
19808
+ alreadyRunning: boolean()
19809
+ });
19810
+ var MediaReclaimInputSchema = object({
19811
+ mode: _enum(["report", "reclaim"]).default("report"),
19812
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19813
+ deviceIds: array(number().int()).min(1).optional(),
19814
+ restart: boolean().optional(),
19815
+ pageSize: number().int().min(50).max(5e3).optional(),
19816
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19817
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19818
+ maxBytesPerRun: number().int().min(1).optional(),
19819
+ budgetMinutes: number().int().min(1).max(720).optional(),
19820
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19821
+ graceMinutes: number().int().min(1).max(10080).optional()
19822
+ });
19823
+ var MediaReclaimStatusSchema = object({
19824
+ running: boolean(),
19825
+ mode: _enum(["report", "reclaim"]).nullable(),
19826
+ totalExamined: number(),
19827
+ totalEligible: number(),
19828
+ totalReclaimed: number(),
19829
+ totalBytesReclaimed: number(),
19830
+ totalRefused: number(),
19831
+ /** Device+scope windows finished in this pass. */
19832
+ devicesDone: number(),
19833
+ complete: boolean().nullable(),
19834
+ startedAtMs: number().nullable(),
19835
+ finishedAtMs: number().nullable(),
19836
+ error: string().nullable()
19837
+ });
19761
19838
  var ReplayFrameInputSchema = object({
19762
19839
  timestamp: number(),
19763
19840
  frame: PipelineRunResultBridge
@@ -19796,10 +19873,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19796
19873
  * stationary registry). Default false: the timeline lists passages,
19797
19874
  * not parking records (operator decision, 2026-08-15). */
19798
19875
  includeStationary: boolean().optional()
19799
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19800
- deviceId: number(),
19801
- groupId: string().min(1)
19802
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19876
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19803
19877
  kind: "mutation",
19804
19878
  auth: "admin"
19805
19879
  }), 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({
@@ -19899,6 +19973,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19899
19973
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19900
19974
  kind: "query",
19901
19975
  auth: "admin"
19976
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19977
+ kind: "mutation",
19978
+ auth: "admin"
19979
+ }), method(object({}), MediaReclaimStatusSchema, {
19980
+ kind: "query",
19981
+ auth: "admin"
19902
19982
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19903
19983
  kind: "query",
19904
19984
  auth: "admin"
@@ -21869,7 +21949,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21869
21949
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21870
21950
  kind: "mutation",
21871
21951
  auth: "admin"
21872
- });
21952
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21953
+ kind: "mutation",
21954
+ auth: "admin"
21955
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21956
+ kind: "mutation",
21957
+ auth: "admin"
21958
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21873
21959
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21874
21960
  providerId: string().min(1),
21875
21961
  displayName: string().min(1),
@@ -29051,6 +29137,33 @@ var RecordingRebalanceInputSchema = object({
29051
29137
  minMoveGb: number().min(0).optional()
29052
29138
  });
29053
29139
  /**
29140
+ * Operator-facing placement of one camera onto a recordings location.
29141
+ *
29142
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
29143
+ * Auto (the planner may move this camera). `locationId` is where high/mid
29144
+ * currently write — the plan, which may disagree with the pin when Auto.
29145
+ */
29146
+ var RecordingDevicePlacementSchema = object({
29147
+ deviceId: number().int(),
29148
+ profile: string(),
29149
+ locationId: string()
29150
+ });
29151
+ var RecordingDevicePinSchema = object({
29152
+ deviceId: number().int(),
29153
+ /** Recordings-class location this camera is pinned to. */
29154
+ locationId: string()
29155
+ });
29156
+ var RecordingPlacementViewSchema = object({
29157
+ assignments: array(RecordingDevicePlacementSchema),
29158
+ pins: array(RecordingDevicePinSchema),
29159
+ defaultLocations: record(string(), string())
29160
+ });
29161
+ var RecordingSetDevicePlacementInputSchema = object({
29162
+ deviceId: number().int(),
29163
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
29164
+ locationId: string().nullable()
29165
+ });
29166
+ /**
29054
29167
  * Result of locating footage at a wall-clock instant for one device/profile.
29055
29168
  * `segment` carries the covering segment's window; `gap` reports the forward
29056
29169
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -29276,6 +29389,12 @@ method(object({
29276
29389
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
29277
29390
  kind: "mutation",
29278
29391
  auth: "admin"
29392
+ }), method(object({}), RecordingPlacementViewSchema, {
29393
+ kind: "query",
29394
+ auth: "admin"
29395
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
29396
+ kind: "mutation",
29397
+ auth: "admin"
29279
29398
  });
29280
29399
  /**
29281
29400
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -34345,6 +34464,12 @@ Object.freeze({
34345
34464
  addonId: null,
34346
34465
  access: "delete"
34347
34466
  },
34467
+ "deviceManager.renameLocation": {
34468
+ capName: "device-manager",
34469
+ capScope: "system",
34470
+ addonId: null,
34471
+ access: "create"
34472
+ },
34348
34473
  "deviceManager.runDeviceAction": {
34349
34474
  capName: "device-manager",
34350
34475
  capScope: "system",
@@ -36037,19 +36162,19 @@ Object.freeze({
36037
36162
  addonId: null,
36038
36163
  access: "view"
36039
36164
  },
36040
- "pipelineAnalytics.getGroup": {
36165
+ "pipelineAnalytics.getKeyEvents": {
36041
36166
  capName: "pipeline-analytics",
36042
36167
  capScope: "device",
36043
36168
  addonId: null,
36044
36169
  access: "view"
36045
36170
  },
36046
- "pipelineAnalytics.getKeyEvents": {
36171
+ "pipelineAnalytics.getKeyEventsBatch": {
36047
36172
  capName: "pipeline-analytics",
36048
36173
  capScope: "device",
36049
36174
  addonId: null,
36050
36175
  access: "view"
36051
36176
  },
36052
- "pipelineAnalytics.getKeyEventsBatch": {
36177
+ "pipelineAnalytics.getMediaReclaimStatus": {
36053
36178
  capName: "pipeline-analytics",
36054
36179
  capScope: "device",
36055
36180
  addonId: null,
@@ -36139,12 +36264,6 @@ Object.freeze({
36139
36264
  addonId: null,
36140
36265
  access: "view"
36141
36266
  },
36142
- "pipelineAnalytics.listGroups": {
36143
- capName: "pipeline-analytics",
36144
- capScope: "device",
36145
- addonId: null,
36146
- access: "view"
36147
- },
36148
36267
  "pipelineAnalytics.listOpsLog": {
36149
36268
  capName: "pipeline-analytics",
36150
36269
  capScope: "device",
@@ -36229,6 +36348,12 @@ Object.freeze({
36229
36348
  addonId: null,
36230
36349
  access: "create"
36231
36350
  },
36351
+ "pipelineAnalytics.reclaimDebugMedia": {
36352
+ capName: "pipeline-analytics",
36353
+ capScope: "device",
36354
+ addonId: null,
36355
+ access: "create"
36356
+ },
36232
36357
  "pipelineAnalytics.reconcileFromDisk": {
36233
36358
  capName: "pipeline-analytics",
36234
36359
  capScope: "device",
@@ -37153,6 +37278,12 @@ Object.freeze({
37153
37278
  addonId: null,
37154
37279
  access: "view"
37155
37280
  },
37281
+ "recording.getPlacement": {
37282
+ capName: "recording",
37283
+ capScope: "system",
37284
+ addonId: null,
37285
+ access: "view"
37286
+ },
37156
37287
  "recording.getPlaybackManifest": {
37157
37288
  capName: "recording",
37158
37289
  capScope: "system",
@@ -37279,6 +37410,12 @@ Object.freeze({
37279
37410
  addonId: null,
37280
37411
  access: "create"
37281
37412
  },
37413
+ "recording.setDevicePlacement": {
37414
+ capName: "recording",
37415
+ capScope: "system",
37416
+ addonId: null,
37417
+ access: "create"
37418
+ },
37282
37419
  "recording.startStorageMigrationMove": {
37283
37420
  capName: "recording",
37284
37421
  capScope: "system",
@@ -37723,12 +37860,36 @@ Object.freeze({
37723
37860
  addonId: null,
37724
37861
  access: "create"
37725
37862
  },
37863
+ "storageMigration.cleanupCancel": {
37864
+ capName: "storage-migration",
37865
+ capScope: "system",
37866
+ addonId: null,
37867
+ access: "create"
37868
+ },
37869
+ "storageMigration.cleanupStart": {
37870
+ capName: "storage-migration",
37871
+ capScope: "system",
37872
+ addonId: null,
37873
+ access: "create"
37874
+ },
37875
+ "storageMigration.cleanupStatus": {
37876
+ capName: "storage-migration",
37877
+ capScope: "system",
37878
+ addonId: null,
37879
+ access: "view"
37880
+ },
37726
37881
  "storageMigration.drain": {
37727
37882
  capName: "storage-migration",
37728
37883
  capScope: "system",
37729
37884
  addonId: null,
37730
37885
  access: "create"
37731
37886
  },
37887
+ "storageMigration.history": {
37888
+ capName: "storage-migration",
37889
+ capScope: "system",
37890
+ addonId: null,
37891
+ access: "view"
37892
+ },
37732
37893
  "storageMigration.movers": {
37733
37894
  capName: "storage-migration",
37734
37895
  capScope: "system",
@@ -39725,11 +39886,6 @@ Object.freeze({
39725
39886
  form: "single",
39726
39887
  optional: true
39727
39888
  }],
39728
- "pipelineAnalytics.getGroup": [{
39729
- name: "deviceId",
39730
- form: "single",
39731
- optional: false
39732
- }],
39733
39889
  "pipelineAnalytics.getKeyEvents": [{
39734
39890
  name: "deviceId",
39735
39891
  form: "single",
@@ -39795,11 +39951,6 @@ Object.freeze({
39795
39951
  form: "single",
39796
39952
  optional: false
39797
39953
  }],
39798
- "pipelineAnalytics.listGroups": [{
39799
- name: "deviceIds",
39800
- form: "array",
39801
- optional: false
39802
- }],
39803
39954
  "pipelineAnalytics.listOpsLog": [{
39804
39955
  name: "deviceId",
39805
39956
  form: "single",
@@ -39845,6 +39996,11 @@ Object.freeze({
39845
39996
  form: "single",
39846
39997
  optional: true
39847
39998
  }],
39999
+ "pipelineAnalytics.reclaimDebugMedia": [{
40000
+ name: "deviceIds",
40001
+ form: "array",
40002
+ optional: true
40003
+ }],
39848
40004
  "pipelineAnalytics.reconcileFromDisk": [{
39849
40005
  name: "deviceId",
39850
40006
  form: "single",
@@ -40210,6 +40366,11 @@ Object.freeze({
40210
40366
  form: "single",
40211
40367
  optional: false
40212
40368
  }],
40369
+ "recording.setDevicePlacement": [{
40370
+ name: "deviceId",
40371
+ form: "single",
40372
+ optional: false
40373
+ }],
40213
40374
  "recording.startStorageMigrationMove": [{
40214
40375
  name: "deviceId",
40215
40376
  form: "single",
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  //#endregion
6
- const require_dist = require("../dist-u1L6UZmY.js");
6
+ const require_dist = require("../dist-D8uo_M4x.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  //#region src/ha-export/topics.ts
9
9
  /**
@@ -1,4 +1,4 @@
1
- import { At as EventCategory, C as buildAddonRouteProvider, Et as string, N as deviceExportCapability, X as oauthIntegrationCapability, a as COCO_TO_MACRO, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, pt as BaseAddon, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema, vt as nodePin } from "../dist-DV4Xqi_x.mjs";
1
+ import { At as EventCategory, C as buildAddonRouteProvider, Et as string, N as deviceExportCapability, X as oauthIntegrationCapability, a as COCO_TO_MACRO, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, pt as BaseAddon, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema, vt as nodePin } from "../dist-COgdwHQp.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/ha-export/topics.ts
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.62",
3
+ "version": "1.2.63",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",