@camstack/addon-provider-rademacher 0.1.12 → 0.1.13

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
@@ -8343,6 +8343,62 @@ var RecordingConfigSchema = object({
8343
8343
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
8344
8344
  });
8345
8345
  /**
8346
+ * Ops-log — the durable, append-only operations audit shared by the
8347
+ * recordings and events management surfaces.
8348
+ *
8349
+ * ONE row shape is reused for both domains so a single "Activity" view can
8350
+ * merge the recorder's DurableState ring (recordings ops-log) and the
8351
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
8352
+ * management operation, WHY it ran (reason), and its measurable effect
8353
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
8354
+ * never fail the operation it records.
8355
+ */
8356
+ /** Which management domain the operation belongs to. */
8357
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
8358
+ /** The kind of management operation performed. */
8359
+ var OpsLogOpSchema = _enum([
8360
+ "prune",
8361
+ "manual-delete",
8362
+ "rescan",
8363
+ "retention-run"
8364
+ ]);
8365
+ /** Why the operation ran. */
8366
+ var OpsLogReasonSchema = _enum([
8367
+ "retention",
8368
+ "quota",
8369
+ "manual",
8370
+ "operator"
8371
+ ]);
8372
+ /** One audit row, shared verbatim by both domains. */
8373
+ var OpsLogEntrySchema = object({
8374
+ /** Unique row id. */
8375
+ id: string(),
8376
+ /** Epoch ms the operation completed. */
8377
+ at: number(),
8378
+ domain: OpsLogDomainSchema,
8379
+ op: OpsLogOpSchema,
8380
+ reason: OpsLogReasonSchema,
8381
+ /** The camera the op targeted; null for a cluster/global op. */
8382
+ deviceId: number().nullable(),
8383
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
8384
+ nodeId: string(),
8385
+ /** Buckets / rows deleted (op-specific unit). */
8386
+ itemsAffected: number(),
8387
+ /** Bytes reclaimed by the op (0 when not measurable). */
8388
+ bytesReclaimed: number(),
8389
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
8390
+ detail: string().nullable(),
8391
+ /** Who/what triggered the op. */
8392
+ actor: string()
8393
+ });
8394
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
8395
+ var OpsLogQueryInputSchema = object({
8396
+ /** Restrict to a single camera; omit for every row. */
8397
+ deviceId: number().optional(),
8398
+ /** Max rows returned, newest-first. */
8399
+ limit: number().int().min(1).max(1e3).optional()
8400
+ });
8401
+ /**
8346
8402
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8347
8403
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8348
8404
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15806,9 +15862,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15806
15862
  * `package` backs the package-drop detector — a package zone is a
15807
15863
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15808
15864
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15809
- * The orchestrator provider that writes this stage lands in a later
15810
- * slice; until then the mirror carries only `{motion, detection}` and
15811
- * consumers read `package` as absent (treat as `[]`).
15865
+ * The orchestrator provider writes this stage as a first-class slice
15866
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15867
+ * package}` shape, so consumers read the current package rules directly
15868
+ * off `device.state.zoneRules.value.package`.
15812
15869
  */
15813
15870
  runtimeState: object({
15814
15871
  motion: array(ZoneRuleSchema).readonly(),
@@ -20125,6 +20182,26 @@ var TrackCascadeCountsSchema = object({
20125
20182
  /** Per-track CLIP search vectors removed (best-effort). */
20126
20183
  embeddings: number().int()
20127
20184
  });
20185
+ /** Event-store footprint for one camera. */
20186
+ var EventStoreDeviceFootprintSchema = object({
20187
+ deviceId: number(),
20188
+ /** Persisted event rows (motion + object + audio) for the camera. */
20189
+ rows: number().int(),
20190
+ /** Event-owned media bytes on disk for the camera. */
20191
+ bytes: number().int()
20192
+ });
20193
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
20194
+ var EventStoreFootprintSchema = object({
20195
+ totalRows: number().int(),
20196
+ totalBytes: number().int(),
20197
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
20198
+ });
20199
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
20200
+ var EventPruneCountsSchema = object({
20201
+ motion: number().int(),
20202
+ object: number().int(),
20203
+ audio: number().int()
20204
+ });
20128
20205
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
20129
20206
  deviceId: number(),
20130
20207
  trackId: string()
@@ -20188,6 +20265,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20188
20265
  }), {
20189
20266
  kind: "mutation",
20190
20267
  auth: "admin"
20268
+ }), method(object({}), EventStoreFootprintSchema, {
20269
+ kind: "query",
20270
+ auth: "admin"
20271
+ }), method(object({
20272
+ olderThanMs: number(),
20273
+ reason: OpsLogReasonSchema.optional()
20274
+ }), EventPruneCountsSchema, {
20275
+ kind: "mutation",
20276
+ auth: "admin"
20277
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
20278
+ kind: "mutation",
20279
+ auth: "admin"
20280
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20281
+ kind: "query",
20282
+ auth: "admin"
20191
20283
  }), method(object({
20192
20284
  eventId: string(),
20193
20285
  kind: MediaFileKindEnum.optional()
@@ -23421,13 +23513,29 @@ method(object({
23421
23513
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
23422
23514
  kind: "mutation",
23423
23515
  auth: "admin"
23424
- }), method(object({ deviceId: number() }), object({
23516
+ }), method(object({
23517
+ deviceId: number(),
23518
+ reason: OpsLogReasonSchema.optional()
23519
+ }), object({
23425
23520
  floorMs: number().nullable(),
23426
23521
  deletedBuckets: number().int(),
23427
23522
  reclaimedBytes: number().int()
23428
23523
  }), {
23429
23524
  kind: "mutation",
23430
23525
  auth: "admin"
23526
+ }), method(object({
23527
+ deviceId: number(),
23528
+ fromMs: number().optional(),
23529
+ toMs: number().optional()
23530
+ }), object({
23531
+ deletedBuckets: number().int(),
23532
+ reclaimedBytes: number().int()
23533
+ }), {
23534
+ kind: "mutation",
23535
+ auth: "admin"
23536
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23537
+ kind: "query",
23538
+ auth: "admin"
23431
23539
  });
23432
23540
  /**
23433
23541
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26549,6 +26657,12 @@ Object.freeze({
26549
26657
  addonId: null,
26550
26658
  access: "delete"
26551
26659
  },
26660
+ "pipelineAnalytics.deleteDeviceEvents": {
26661
+ capName: "pipeline-analytics",
26662
+ capScope: "device",
26663
+ addonId: null,
26664
+ access: "delete"
26665
+ },
26552
26666
  "pipelineAnalytics.deleteTracks": {
26553
26667
  capName: "pipeline-analytics",
26554
26668
  capScope: "device",
@@ -26579,6 +26693,12 @@ Object.freeze({
26579
26693
  addonId: null,
26580
26694
  access: "view"
26581
26695
  },
26696
+ "pipelineAnalytics.getEventStoreFootprint": {
26697
+ capName: "pipeline-analytics",
26698
+ capScope: "device",
26699
+ addonId: null,
26700
+ access: "view"
26701
+ },
26582
26702
  "pipelineAnalytics.getKeyEvents": {
26583
26703
  capName: "pipeline-analytics",
26584
26704
  capScope: "device",
@@ -26621,6 +26741,12 @@ Object.freeze({
26621
26741
  addonId: null,
26622
26742
  access: "view"
26623
26743
  },
26744
+ "pipelineAnalytics.listOpsLog": {
26745
+ capName: "pipeline-analytics",
26746
+ capScope: "device",
26747
+ addonId: null,
26748
+ access: "view"
26749
+ },
26624
26750
  "pipelineAnalytics.listRecentTracks": {
26625
26751
  capName: "pipeline-analytics",
26626
26752
  capScope: "device",
@@ -26633,6 +26759,12 @@ Object.freeze({
26633
26759
  addonId: null,
26634
26760
  access: "view"
26635
26761
  },
26762
+ "pipelineAnalytics.pruneEvents": {
26763
+ capName: "pipeline-analytics",
26764
+ capScope: "device",
26765
+ addonId: null,
26766
+ access: "create"
26767
+ },
26636
26768
  "pipelineAnalytics.pruneEventsBefore": {
26637
26769
  capName: "pipeline-analytics",
26638
26770
  capScope: "device",
@@ -27395,6 +27527,12 @@ Object.freeze({
27395
27527
  addonId: null,
27396
27528
  access: "create"
27397
27529
  },
27530
+ "recording.deleteFootprint": {
27531
+ capName: "recording",
27532
+ capScope: "system",
27533
+ addonId: null,
27534
+ access: "delete"
27535
+ },
27398
27536
  "recording.getAvailability": {
27399
27537
  capName: "recording",
27400
27538
  capScope: "system",
@@ -27425,6 +27563,12 @@ Object.freeze({
27425
27563
  addonId: null,
27426
27564
  access: "view"
27427
27565
  },
27566
+ "recording.listOpsLog": {
27567
+ capName: "recording",
27568
+ capScope: "system",
27569
+ addonId: null,
27570
+ access: "view"
27571
+ },
27428
27572
  "recording.locateSegment": {
27429
27573
  capName: "recording",
27430
27574
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -8342,6 +8342,62 @@ var RecordingConfigSchema = object({
8342
8342
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
8343
8343
  });
8344
8344
  /**
8345
+ * Ops-log — the durable, append-only operations audit shared by the
8346
+ * recordings and events management surfaces.
8347
+ *
8348
+ * ONE row shape is reused for both domains so a single "Activity" view can
8349
+ * merge the recorder's DurableState ring (recordings ops-log) and the
8350
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
8351
+ * management operation, WHY it ran (reason), and its measurable effect
8352
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
8353
+ * never fail the operation it records.
8354
+ */
8355
+ /** Which management domain the operation belongs to. */
8356
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
8357
+ /** The kind of management operation performed. */
8358
+ var OpsLogOpSchema = _enum([
8359
+ "prune",
8360
+ "manual-delete",
8361
+ "rescan",
8362
+ "retention-run"
8363
+ ]);
8364
+ /** Why the operation ran. */
8365
+ var OpsLogReasonSchema = _enum([
8366
+ "retention",
8367
+ "quota",
8368
+ "manual",
8369
+ "operator"
8370
+ ]);
8371
+ /** One audit row, shared verbatim by both domains. */
8372
+ var OpsLogEntrySchema = object({
8373
+ /** Unique row id. */
8374
+ id: string(),
8375
+ /** Epoch ms the operation completed. */
8376
+ at: number(),
8377
+ domain: OpsLogDomainSchema,
8378
+ op: OpsLogOpSchema,
8379
+ reason: OpsLogReasonSchema,
8380
+ /** The camera the op targeted; null for a cluster/global op. */
8381
+ deviceId: number().nullable(),
8382
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
8383
+ nodeId: string(),
8384
+ /** Buckets / rows deleted (op-specific unit). */
8385
+ itemsAffected: number(),
8386
+ /** Bytes reclaimed by the op (0 when not measurable). */
8387
+ bytesReclaimed: number(),
8388
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
8389
+ detail: string().nullable(),
8390
+ /** Who/what triggered the op. */
8391
+ actor: string()
8392
+ });
8393
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
8394
+ var OpsLogQueryInputSchema = object({
8395
+ /** Restrict to a single camera; omit for every row. */
8396
+ deviceId: number().optional(),
8397
+ /** Max rows returned, newest-first. */
8398
+ limit: number().int().min(1).max(1e3).optional()
8399
+ });
8400
+ /**
8345
8401
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8346
8402
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8347
8403
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15805,9 +15861,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15805
15861
  * `package` backs the package-drop detector — a package zone is a
15806
15862
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15807
15863
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15808
- * The orchestrator provider that writes this stage lands in a later
15809
- * slice; until then the mirror carries only `{motion, detection}` and
15810
- * consumers read `package` as absent (treat as `[]`).
15864
+ * The orchestrator provider writes this stage as a first-class slice
15865
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15866
+ * package}` shape, so consumers read the current package rules directly
15867
+ * off `device.state.zoneRules.value.package`.
15811
15868
  */
15812
15869
  runtimeState: object({
15813
15870
  motion: array(ZoneRuleSchema).readonly(),
@@ -20124,6 +20181,26 @@ var TrackCascadeCountsSchema = object({
20124
20181
  /** Per-track CLIP search vectors removed (best-effort). */
20125
20182
  embeddings: number().int()
20126
20183
  });
20184
+ /** Event-store footprint for one camera. */
20185
+ var EventStoreDeviceFootprintSchema = object({
20186
+ deviceId: number(),
20187
+ /** Persisted event rows (motion + object + audio) for the camera. */
20188
+ rows: number().int(),
20189
+ /** Event-owned media bytes on disk for the camera. */
20190
+ bytes: number().int()
20191
+ });
20192
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
20193
+ var EventStoreFootprintSchema = object({
20194
+ totalRows: number().int(),
20195
+ totalBytes: number().int(),
20196
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
20197
+ });
20198
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
20199
+ var EventPruneCountsSchema = object({
20200
+ motion: number().int(),
20201
+ object: number().int(),
20202
+ audio: number().int()
20203
+ });
20127
20204
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
20128
20205
  deviceId: number(),
20129
20206
  trackId: string()
@@ -20187,6 +20264,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20187
20264
  }), {
20188
20265
  kind: "mutation",
20189
20266
  auth: "admin"
20267
+ }), method(object({}), EventStoreFootprintSchema, {
20268
+ kind: "query",
20269
+ auth: "admin"
20270
+ }), method(object({
20271
+ olderThanMs: number(),
20272
+ reason: OpsLogReasonSchema.optional()
20273
+ }), EventPruneCountsSchema, {
20274
+ kind: "mutation",
20275
+ auth: "admin"
20276
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
20277
+ kind: "mutation",
20278
+ auth: "admin"
20279
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
20280
+ kind: "query",
20281
+ auth: "admin"
20190
20282
  }), method(object({
20191
20283
  eventId: string(),
20192
20284
  kind: MediaFileKindEnum.optional()
@@ -23420,13 +23512,29 @@ method(object({
23420
23512
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
23421
23513
  kind: "mutation",
23422
23514
  auth: "admin"
23423
- }), method(object({ deviceId: number() }), object({
23515
+ }), method(object({
23516
+ deviceId: number(),
23517
+ reason: OpsLogReasonSchema.optional()
23518
+ }), object({
23424
23519
  floorMs: number().nullable(),
23425
23520
  deletedBuckets: number().int(),
23426
23521
  reclaimedBytes: number().int()
23427
23522
  }), {
23428
23523
  kind: "mutation",
23429
23524
  auth: "admin"
23525
+ }), method(object({
23526
+ deviceId: number(),
23527
+ fromMs: number().optional(),
23528
+ toMs: number().optional()
23529
+ }), object({
23530
+ deletedBuckets: number().int(),
23531
+ reclaimedBytes: number().int()
23532
+ }), {
23533
+ kind: "mutation",
23534
+ auth: "admin"
23535
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23536
+ kind: "query",
23537
+ auth: "admin"
23430
23538
  });
23431
23539
  /**
23432
23540
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26548,6 +26656,12 @@ Object.freeze({
26548
26656
  addonId: null,
26549
26657
  access: "delete"
26550
26658
  },
26659
+ "pipelineAnalytics.deleteDeviceEvents": {
26660
+ capName: "pipeline-analytics",
26661
+ capScope: "device",
26662
+ addonId: null,
26663
+ access: "delete"
26664
+ },
26551
26665
  "pipelineAnalytics.deleteTracks": {
26552
26666
  capName: "pipeline-analytics",
26553
26667
  capScope: "device",
@@ -26578,6 +26692,12 @@ Object.freeze({
26578
26692
  addonId: null,
26579
26693
  access: "view"
26580
26694
  },
26695
+ "pipelineAnalytics.getEventStoreFootprint": {
26696
+ capName: "pipeline-analytics",
26697
+ capScope: "device",
26698
+ addonId: null,
26699
+ access: "view"
26700
+ },
26581
26701
  "pipelineAnalytics.getKeyEvents": {
26582
26702
  capName: "pipeline-analytics",
26583
26703
  capScope: "device",
@@ -26620,6 +26740,12 @@ Object.freeze({
26620
26740
  addonId: null,
26621
26741
  access: "view"
26622
26742
  },
26743
+ "pipelineAnalytics.listOpsLog": {
26744
+ capName: "pipeline-analytics",
26745
+ capScope: "device",
26746
+ addonId: null,
26747
+ access: "view"
26748
+ },
26623
26749
  "pipelineAnalytics.listRecentTracks": {
26624
26750
  capName: "pipeline-analytics",
26625
26751
  capScope: "device",
@@ -26632,6 +26758,12 @@ Object.freeze({
26632
26758
  addonId: null,
26633
26759
  access: "view"
26634
26760
  },
26761
+ "pipelineAnalytics.pruneEvents": {
26762
+ capName: "pipeline-analytics",
26763
+ capScope: "device",
26764
+ addonId: null,
26765
+ access: "create"
26766
+ },
26635
26767
  "pipelineAnalytics.pruneEventsBefore": {
26636
26768
  capName: "pipeline-analytics",
26637
26769
  capScope: "device",
@@ -27394,6 +27526,12 @@ Object.freeze({
27394
27526
  addonId: null,
27395
27527
  access: "create"
27396
27528
  },
27529
+ "recording.deleteFootprint": {
27530
+ capName: "recording",
27531
+ capScope: "system",
27532
+ addonId: null,
27533
+ access: "delete"
27534
+ },
27397
27535
  "recording.getAvailability": {
27398
27536
  capName: "recording",
27399
27537
  capScope: "system",
@@ -27424,6 +27562,12 @@ Object.freeze({
27424
27562
  addonId: null,
27425
27563
  access: "view"
27426
27564
  },
27565
+ "recording.listOpsLog": {
27566
+ capName: "recording",
27567
+ capScope: "system",
27568
+ addonId: null,
27569
+ access: "view"
27570
+ },
27427
27571
  "recording.locateSegment": {
27428
27572
  capName: "recording",
27429
27573
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",