@camstack/addon-provider-homeassistant 1.1.30 → 1.1.31

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
@@ -7463,6 +7463,62 @@ var RecordingConfigSchema = object({
7463
7463
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7464
7464
  });
7465
7465
  /**
7466
+ * Ops-log — the durable, append-only operations audit shared by the
7467
+ * recordings and events management surfaces.
7468
+ *
7469
+ * ONE row shape is reused for both domains so a single "Activity" view can
7470
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7471
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7472
+ * management operation, WHY it ran (reason), and its measurable effect
7473
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7474
+ * never fail the operation it records.
7475
+ */
7476
+ /** Which management domain the operation belongs to. */
7477
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7478
+ /** The kind of management operation performed. */
7479
+ var OpsLogOpSchema = _enum([
7480
+ "prune",
7481
+ "manual-delete",
7482
+ "rescan",
7483
+ "retention-run"
7484
+ ]);
7485
+ /** Why the operation ran. */
7486
+ var OpsLogReasonSchema = _enum([
7487
+ "retention",
7488
+ "quota",
7489
+ "manual",
7490
+ "operator"
7491
+ ]);
7492
+ /** One audit row, shared verbatim by both domains. */
7493
+ var OpsLogEntrySchema = object({
7494
+ /** Unique row id. */
7495
+ id: string(),
7496
+ /** Epoch ms the operation completed. */
7497
+ at: number(),
7498
+ domain: OpsLogDomainSchema,
7499
+ op: OpsLogOpSchema,
7500
+ reason: OpsLogReasonSchema,
7501
+ /** The camera the op targeted; null for a cluster/global op. */
7502
+ deviceId: number().nullable(),
7503
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7504
+ nodeId: string(),
7505
+ /** Buckets / rows deleted (op-specific unit). */
7506
+ itemsAffected: number(),
7507
+ /** Bytes reclaimed by the op (0 when not measurable). */
7508
+ bytesReclaimed: number(),
7509
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7510
+ detail: string().nullable(),
7511
+ /** Who/what triggered the op. */
7512
+ actor: string()
7513
+ });
7514
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7515
+ var OpsLogQueryInputSchema = object({
7516
+ /** Restrict to a single camera; omit for every row. */
7517
+ deviceId: number().optional(),
7518
+ /** Max rows returned, newest-first. */
7519
+ limit: number().int().min(1).max(1e3).optional()
7520
+ });
7521
+ /**
7466
7522
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7467
7523
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7468
7524
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15164,9 +15220,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15164
15220
  * `package` backs the package-drop detector — a package zone is a
15165
15221
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15166
15222
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15167
- * The orchestrator provider that writes this stage lands in a later
15168
- * slice; until then the mirror carries only `{motion, detection}` and
15169
- * consumers read `package` as absent (treat as `[]`).
15223
+ * The orchestrator provider writes this stage as a first-class slice
15224
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15225
+ * package}` shape, so consumers read the current package rules directly
15226
+ * off `device.state.zoneRules.value.package`.
15170
15227
  */
15171
15228
  runtimeState: object({
15172
15229
  motion: array(ZoneRuleSchema).readonly(),
@@ -19582,6 +19639,26 @@ var TrackCascadeCountsSchema = object({
19582
19639
  /** Per-track CLIP search vectors removed (best-effort). */
19583
19640
  embeddings: number().int()
19584
19641
  });
19642
+ /** Event-store footprint for one camera. */
19643
+ var EventStoreDeviceFootprintSchema = object({
19644
+ deviceId: number(),
19645
+ /** Persisted event rows (motion + object + audio) for the camera. */
19646
+ rows: number().int(),
19647
+ /** Event-owned media bytes on disk for the camera. */
19648
+ bytes: number().int()
19649
+ });
19650
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19651
+ var EventStoreFootprintSchema = object({
19652
+ totalRows: number().int(),
19653
+ totalBytes: number().int(),
19654
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19655
+ });
19656
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19657
+ var EventPruneCountsSchema = object({
19658
+ motion: number().int(),
19659
+ object: number().int(),
19660
+ audio: number().int()
19661
+ });
19585
19662
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19586
19663
  deviceId: number(),
19587
19664
  trackId: string()
@@ -19645,6 +19722,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19645
19722
  }), {
19646
19723
  kind: "mutation",
19647
19724
  auth: "admin"
19725
+ }), method(object({}), EventStoreFootprintSchema, {
19726
+ kind: "query",
19727
+ auth: "admin"
19728
+ }), method(object({
19729
+ olderThanMs: number(),
19730
+ reason: OpsLogReasonSchema.optional()
19731
+ }), EventPruneCountsSchema, {
19732
+ kind: "mutation",
19733
+ auth: "admin"
19734
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19735
+ kind: "mutation",
19736
+ auth: "admin"
19737
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19738
+ kind: "query",
19739
+ auth: "admin"
19648
19740
  }), method(object({
19649
19741
  eventId: string(),
19650
19742
  kind: MediaFileKindEnum.optional()
@@ -22967,13 +23059,29 @@ method(object({
22967
23059
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22968
23060
  kind: "mutation",
22969
23061
  auth: "admin"
22970
- }), method(object({ deviceId: number() }), object({
23062
+ }), method(object({
23063
+ deviceId: number(),
23064
+ reason: OpsLogReasonSchema.optional()
23065
+ }), object({
22971
23066
  floorMs: number().nullable(),
22972
23067
  deletedBuckets: number().int(),
22973
23068
  reclaimedBytes: number().int()
22974
23069
  }), {
22975
23070
  kind: "mutation",
22976
23071
  auth: "admin"
23072
+ }), method(object({
23073
+ deviceId: number(),
23074
+ fromMs: number().optional(),
23075
+ toMs: number().optional()
23076
+ }), object({
23077
+ deletedBuckets: number().int(),
23078
+ reclaimedBytes: number().int()
23079
+ }), {
23080
+ kind: "mutation",
23081
+ auth: "admin"
23082
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23083
+ kind: "query",
23084
+ auth: "admin"
22977
23085
  });
22978
23086
  /**
22979
23087
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26095,6 +26203,12 @@ Object.freeze({
26095
26203
  addonId: null,
26096
26204
  access: "delete"
26097
26205
  },
26206
+ "pipelineAnalytics.deleteDeviceEvents": {
26207
+ capName: "pipeline-analytics",
26208
+ capScope: "device",
26209
+ addonId: null,
26210
+ access: "delete"
26211
+ },
26098
26212
  "pipelineAnalytics.deleteTracks": {
26099
26213
  capName: "pipeline-analytics",
26100
26214
  capScope: "device",
@@ -26125,6 +26239,12 @@ Object.freeze({
26125
26239
  addonId: null,
26126
26240
  access: "view"
26127
26241
  },
26242
+ "pipelineAnalytics.getEventStoreFootprint": {
26243
+ capName: "pipeline-analytics",
26244
+ capScope: "device",
26245
+ addonId: null,
26246
+ access: "view"
26247
+ },
26128
26248
  "pipelineAnalytics.getKeyEvents": {
26129
26249
  capName: "pipeline-analytics",
26130
26250
  capScope: "device",
@@ -26167,6 +26287,12 @@ Object.freeze({
26167
26287
  addonId: null,
26168
26288
  access: "view"
26169
26289
  },
26290
+ "pipelineAnalytics.listOpsLog": {
26291
+ capName: "pipeline-analytics",
26292
+ capScope: "device",
26293
+ addonId: null,
26294
+ access: "view"
26295
+ },
26170
26296
  "pipelineAnalytics.listRecentTracks": {
26171
26297
  capName: "pipeline-analytics",
26172
26298
  capScope: "device",
@@ -26179,6 +26305,12 @@ Object.freeze({
26179
26305
  addonId: null,
26180
26306
  access: "view"
26181
26307
  },
26308
+ "pipelineAnalytics.pruneEvents": {
26309
+ capName: "pipeline-analytics",
26310
+ capScope: "device",
26311
+ addonId: null,
26312
+ access: "create"
26313
+ },
26182
26314
  "pipelineAnalytics.pruneEventsBefore": {
26183
26315
  capName: "pipeline-analytics",
26184
26316
  capScope: "device",
@@ -26941,6 +27073,12 @@ Object.freeze({
26941
27073
  addonId: null,
26942
27074
  access: "create"
26943
27075
  },
27076
+ "recording.deleteFootprint": {
27077
+ capName: "recording",
27078
+ capScope: "system",
27079
+ addonId: null,
27080
+ access: "delete"
27081
+ },
26944
27082
  "recording.getAvailability": {
26945
27083
  capName: "recording",
26946
27084
  capScope: "system",
@@ -26971,6 +27109,12 @@ Object.freeze({
26971
27109
  addonId: null,
26972
27110
  access: "view"
26973
27111
  },
27112
+ "recording.listOpsLog": {
27113
+ capName: "recording",
27114
+ capScope: "system",
27115
+ addonId: null,
27116
+ access: "view"
27117
+ },
26974
27118
  "recording.locateSegment": {
26975
27119
  capName: "recording",
26976
27120
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7462,6 +7462,62 @@ var RecordingConfigSchema = object({
7462
7462
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7463
7463
  });
7464
7464
  /**
7465
+ * Ops-log — the durable, append-only operations audit shared by the
7466
+ * recordings and events management surfaces.
7467
+ *
7468
+ * ONE row shape is reused for both domains so a single "Activity" view can
7469
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7470
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7471
+ * management operation, WHY it ran (reason), and its measurable effect
7472
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7473
+ * never fail the operation it records.
7474
+ */
7475
+ /** Which management domain the operation belongs to. */
7476
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7477
+ /** The kind of management operation performed. */
7478
+ var OpsLogOpSchema = _enum([
7479
+ "prune",
7480
+ "manual-delete",
7481
+ "rescan",
7482
+ "retention-run"
7483
+ ]);
7484
+ /** Why the operation ran. */
7485
+ var OpsLogReasonSchema = _enum([
7486
+ "retention",
7487
+ "quota",
7488
+ "manual",
7489
+ "operator"
7490
+ ]);
7491
+ /** One audit row, shared verbatim by both domains. */
7492
+ var OpsLogEntrySchema = object({
7493
+ /** Unique row id. */
7494
+ id: string(),
7495
+ /** Epoch ms the operation completed. */
7496
+ at: number(),
7497
+ domain: OpsLogDomainSchema,
7498
+ op: OpsLogOpSchema,
7499
+ reason: OpsLogReasonSchema,
7500
+ /** The camera the op targeted; null for a cluster/global op. */
7501
+ deviceId: number().nullable(),
7502
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7503
+ nodeId: string(),
7504
+ /** Buckets / rows deleted (op-specific unit). */
7505
+ itemsAffected: number(),
7506
+ /** Bytes reclaimed by the op (0 when not measurable). */
7507
+ bytesReclaimed: number(),
7508
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7509
+ detail: string().nullable(),
7510
+ /** Who/what triggered the op. */
7511
+ actor: string()
7512
+ });
7513
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7514
+ var OpsLogQueryInputSchema = object({
7515
+ /** Restrict to a single camera; omit for every row. */
7516
+ deviceId: number().optional(),
7517
+ /** Max rows returned, newest-first. */
7518
+ limit: number().int().min(1).max(1e3).optional()
7519
+ });
7520
+ /**
7465
7521
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7466
7522
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7467
7523
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15163,9 +15219,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15163
15219
  * `package` backs the package-drop detector — a package zone is a
15164
15220
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15165
15221
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15166
- * The orchestrator provider that writes this stage lands in a later
15167
- * slice; until then the mirror carries only `{motion, detection}` and
15168
- * consumers read `package` as absent (treat as `[]`).
15222
+ * The orchestrator provider writes this stage as a first-class slice
15223
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15224
+ * package}` shape, so consumers read the current package rules directly
15225
+ * off `device.state.zoneRules.value.package`.
15169
15226
  */
15170
15227
  runtimeState: object({
15171
15228
  motion: array(ZoneRuleSchema).readonly(),
@@ -19581,6 +19638,26 @@ var TrackCascadeCountsSchema = object({
19581
19638
  /** Per-track CLIP search vectors removed (best-effort). */
19582
19639
  embeddings: number().int()
19583
19640
  });
19641
+ /** Event-store footprint for one camera. */
19642
+ var EventStoreDeviceFootprintSchema = object({
19643
+ deviceId: number(),
19644
+ /** Persisted event rows (motion + object + audio) for the camera. */
19645
+ rows: number().int(),
19646
+ /** Event-owned media bytes on disk for the camera. */
19647
+ bytes: number().int()
19648
+ });
19649
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19650
+ var EventStoreFootprintSchema = object({
19651
+ totalRows: number().int(),
19652
+ totalBytes: number().int(),
19653
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19654
+ });
19655
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19656
+ var EventPruneCountsSchema = object({
19657
+ motion: number().int(),
19658
+ object: number().int(),
19659
+ audio: number().int()
19660
+ });
19584
19661
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19585
19662
  deviceId: number(),
19586
19663
  trackId: string()
@@ -19644,6 +19721,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19644
19721
  }), {
19645
19722
  kind: "mutation",
19646
19723
  auth: "admin"
19724
+ }), method(object({}), EventStoreFootprintSchema, {
19725
+ kind: "query",
19726
+ auth: "admin"
19727
+ }), method(object({
19728
+ olderThanMs: number(),
19729
+ reason: OpsLogReasonSchema.optional()
19730
+ }), EventPruneCountsSchema, {
19731
+ kind: "mutation",
19732
+ auth: "admin"
19733
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19734
+ kind: "mutation",
19735
+ auth: "admin"
19736
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19737
+ kind: "query",
19738
+ auth: "admin"
19647
19739
  }), method(object({
19648
19740
  eventId: string(),
19649
19741
  kind: MediaFileKindEnum.optional()
@@ -22966,13 +23058,29 @@ method(object({
22966
23058
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22967
23059
  kind: "mutation",
22968
23060
  auth: "admin"
22969
- }), method(object({ deviceId: number() }), object({
23061
+ }), method(object({
23062
+ deviceId: number(),
23063
+ reason: OpsLogReasonSchema.optional()
23064
+ }), object({
22970
23065
  floorMs: number().nullable(),
22971
23066
  deletedBuckets: number().int(),
22972
23067
  reclaimedBytes: number().int()
22973
23068
  }), {
22974
23069
  kind: "mutation",
22975
23070
  auth: "admin"
23071
+ }), method(object({
23072
+ deviceId: number(),
23073
+ fromMs: number().optional(),
23074
+ toMs: number().optional()
23075
+ }), object({
23076
+ deletedBuckets: number().int(),
23077
+ reclaimedBytes: number().int()
23078
+ }), {
23079
+ kind: "mutation",
23080
+ auth: "admin"
23081
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23082
+ kind: "query",
23083
+ auth: "admin"
22976
23084
  });
22977
23085
  /**
22978
23086
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26094,6 +26202,12 @@ Object.freeze({
26094
26202
  addonId: null,
26095
26203
  access: "delete"
26096
26204
  },
26205
+ "pipelineAnalytics.deleteDeviceEvents": {
26206
+ capName: "pipeline-analytics",
26207
+ capScope: "device",
26208
+ addonId: null,
26209
+ access: "delete"
26210
+ },
26097
26211
  "pipelineAnalytics.deleteTracks": {
26098
26212
  capName: "pipeline-analytics",
26099
26213
  capScope: "device",
@@ -26124,6 +26238,12 @@ Object.freeze({
26124
26238
  addonId: null,
26125
26239
  access: "view"
26126
26240
  },
26241
+ "pipelineAnalytics.getEventStoreFootprint": {
26242
+ capName: "pipeline-analytics",
26243
+ capScope: "device",
26244
+ addonId: null,
26245
+ access: "view"
26246
+ },
26127
26247
  "pipelineAnalytics.getKeyEvents": {
26128
26248
  capName: "pipeline-analytics",
26129
26249
  capScope: "device",
@@ -26166,6 +26286,12 @@ Object.freeze({
26166
26286
  addonId: null,
26167
26287
  access: "view"
26168
26288
  },
26289
+ "pipelineAnalytics.listOpsLog": {
26290
+ capName: "pipeline-analytics",
26291
+ capScope: "device",
26292
+ addonId: null,
26293
+ access: "view"
26294
+ },
26169
26295
  "pipelineAnalytics.listRecentTracks": {
26170
26296
  capName: "pipeline-analytics",
26171
26297
  capScope: "device",
@@ -26178,6 +26304,12 @@ Object.freeze({
26178
26304
  addonId: null,
26179
26305
  access: "view"
26180
26306
  },
26307
+ "pipelineAnalytics.pruneEvents": {
26308
+ capName: "pipeline-analytics",
26309
+ capScope: "device",
26310
+ addonId: null,
26311
+ access: "create"
26312
+ },
26181
26313
  "pipelineAnalytics.pruneEventsBefore": {
26182
26314
  capName: "pipeline-analytics",
26183
26315
  capScope: "device",
@@ -26940,6 +27072,12 @@ Object.freeze({
26940
27072
  addonId: null,
26941
27073
  access: "create"
26942
27074
  },
27075
+ "recording.deleteFootprint": {
27076
+ capName: "recording",
27077
+ capScope: "system",
27078
+ addonId: null,
27079
+ access: "delete"
27080
+ },
26943
27081
  "recording.getAvailability": {
26944
27082
  capName: "recording",
26945
27083
  capScope: "system",
@@ -26970,6 +27108,12 @@ Object.freeze({
26970
27108
  addonId: null,
26971
27109
  access: "view"
26972
27110
  },
27111
+ "recording.listOpsLog": {
27112
+ capName: "recording",
27113
+ capScope: "system",
27114
+ addonId: null,
27115
+ access: "view"
27116
+ },
26973
27117
  "recording.locateSegment": {
26974
27118
  capName: "recording",
26975
27119
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.1.30",
3
+ "version": "1.1.31",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",