@camstack/addon-provider-dreo 0.1.21 → 0.1.22

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
@@ -7380,6 +7380,62 @@ var RecordingConfigSchema = object({
7380
7380
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7381
7381
  });
7382
7382
  /**
7383
+ * Ops-log — the durable, append-only operations audit shared by the
7384
+ * recordings and events management surfaces.
7385
+ *
7386
+ * ONE row shape is reused for both domains so a single "Activity" view can
7387
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7388
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7389
+ * management operation, WHY it ran (reason), and its measurable effect
7390
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7391
+ * never fail the operation it records.
7392
+ */
7393
+ /** Which management domain the operation belongs to. */
7394
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7395
+ /** The kind of management operation performed. */
7396
+ var OpsLogOpSchema = _enum([
7397
+ "prune",
7398
+ "manual-delete",
7399
+ "rescan",
7400
+ "retention-run"
7401
+ ]);
7402
+ /** Why the operation ran. */
7403
+ var OpsLogReasonSchema = _enum([
7404
+ "retention",
7405
+ "quota",
7406
+ "manual",
7407
+ "operator"
7408
+ ]);
7409
+ /** One audit row, shared verbatim by both domains. */
7410
+ var OpsLogEntrySchema = object({
7411
+ /** Unique row id. */
7412
+ id: string(),
7413
+ /** Epoch ms the operation completed. */
7414
+ at: number(),
7415
+ domain: OpsLogDomainSchema,
7416
+ op: OpsLogOpSchema,
7417
+ reason: OpsLogReasonSchema,
7418
+ /** The camera the op targeted; null for a cluster/global op. */
7419
+ deviceId: number().nullable(),
7420
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7421
+ nodeId: string(),
7422
+ /** Buckets / rows deleted (op-specific unit). */
7423
+ itemsAffected: number(),
7424
+ /** Bytes reclaimed by the op (0 when not measurable). */
7425
+ bytesReclaimed: number(),
7426
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7427
+ detail: string().nullable(),
7428
+ /** Who/what triggered the op. */
7429
+ actor: string()
7430
+ });
7431
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7432
+ var OpsLogQueryInputSchema = object({
7433
+ /** Restrict to a single camera; omit for every row. */
7434
+ deviceId: number().optional(),
7435
+ /** Max rows returned, newest-first. */
7436
+ limit: number().int().min(1).max(1e3).optional()
7437
+ });
7438
+ /**
7383
7439
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7384
7440
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7385
7441
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14843,9 +14899,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14843
14899
  * `package` backs the package-drop detector — a package zone is a
14844
14900
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14845
14901
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14846
- * The orchestrator provider that writes this stage lands in a later
14847
- * slice; until then the mirror carries only `{motion, detection}` and
14848
- * consumers read `package` as absent (treat as `[]`).
14902
+ * The orchestrator provider writes this stage as a first-class slice
14903
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14904
+ * package}` shape, so consumers read the current package rules directly
14905
+ * off `device.state.zoneRules.value.package`.
14849
14906
  */
14850
14907
  runtimeState: object({
14851
14908
  motion: array(ZoneRuleSchema).readonly(),
@@ -19179,6 +19236,26 @@ var TrackCascadeCountsSchema = object({
19179
19236
  /** Per-track CLIP search vectors removed (best-effort). */
19180
19237
  embeddings: number().int()
19181
19238
  });
19239
+ /** Event-store footprint for one camera. */
19240
+ var EventStoreDeviceFootprintSchema = object({
19241
+ deviceId: number(),
19242
+ /** Persisted event rows (motion + object + audio) for the camera. */
19243
+ rows: number().int(),
19244
+ /** Event-owned media bytes on disk for the camera. */
19245
+ bytes: number().int()
19246
+ });
19247
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19248
+ var EventStoreFootprintSchema = object({
19249
+ totalRows: number().int(),
19250
+ totalBytes: number().int(),
19251
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19252
+ });
19253
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19254
+ var EventPruneCountsSchema = object({
19255
+ motion: number().int(),
19256
+ object: number().int(),
19257
+ audio: number().int()
19258
+ });
19182
19259
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19183
19260
  deviceId: number(),
19184
19261
  trackId: string()
@@ -19242,6 +19319,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19242
19319
  }), {
19243
19320
  kind: "mutation",
19244
19321
  auth: "admin"
19322
+ }), method(object({}), EventStoreFootprintSchema, {
19323
+ kind: "query",
19324
+ auth: "admin"
19325
+ }), method(object({
19326
+ olderThanMs: number(),
19327
+ reason: OpsLogReasonSchema.optional()
19328
+ }), EventPruneCountsSchema, {
19329
+ kind: "mutation",
19330
+ auth: "admin"
19331
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19332
+ kind: "mutation",
19333
+ auth: "admin"
19334
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19335
+ kind: "query",
19336
+ auth: "admin"
19245
19337
  }), method(object({
19246
19338
  eventId: string(),
19247
19339
  kind: MediaFileKindEnum.optional()
@@ -22475,13 +22567,29 @@ method(object({
22475
22567
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22476
22568
  kind: "mutation",
22477
22569
  auth: "admin"
22478
- }), method(object({ deviceId: number() }), object({
22570
+ }), method(object({
22571
+ deviceId: number(),
22572
+ reason: OpsLogReasonSchema.optional()
22573
+ }), object({
22479
22574
  floorMs: number().nullable(),
22480
22575
  deletedBuckets: number().int(),
22481
22576
  reclaimedBytes: number().int()
22482
22577
  }), {
22483
22578
  kind: "mutation",
22484
22579
  auth: "admin"
22580
+ }), method(object({
22581
+ deviceId: number(),
22582
+ fromMs: number().optional(),
22583
+ toMs: number().optional()
22584
+ }), object({
22585
+ deletedBuckets: number().int(),
22586
+ reclaimedBytes: number().int()
22587
+ }), {
22588
+ kind: "mutation",
22589
+ auth: "admin"
22590
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22591
+ kind: "query",
22592
+ auth: "admin"
22485
22593
  });
22486
22594
  /**
22487
22595
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25603,6 +25711,12 @@ Object.freeze({
25603
25711
  addonId: null,
25604
25712
  access: "delete"
25605
25713
  },
25714
+ "pipelineAnalytics.deleteDeviceEvents": {
25715
+ capName: "pipeline-analytics",
25716
+ capScope: "device",
25717
+ addonId: null,
25718
+ access: "delete"
25719
+ },
25606
25720
  "pipelineAnalytics.deleteTracks": {
25607
25721
  capName: "pipeline-analytics",
25608
25722
  capScope: "device",
@@ -25633,6 +25747,12 @@ Object.freeze({
25633
25747
  addonId: null,
25634
25748
  access: "view"
25635
25749
  },
25750
+ "pipelineAnalytics.getEventStoreFootprint": {
25751
+ capName: "pipeline-analytics",
25752
+ capScope: "device",
25753
+ addonId: null,
25754
+ access: "view"
25755
+ },
25636
25756
  "pipelineAnalytics.getKeyEvents": {
25637
25757
  capName: "pipeline-analytics",
25638
25758
  capScope: "device",
@@ -25675,6 +25795,12 @@ Object.freeze({
25675
25795
  addonId: null,
25676
25796
  access: "view"
25677
25797
  },
25798
+ "pipelineAnalytics.listOpsLog": {
25799
+ capName: "pipeline-analytics",
25800
+ capScope: "device",
25801
+ addonId: null,
25802
+ access: "view"
25803
+ },
25678
25804
  "pipelineAnalytics.listRecentTracks": {
25679
25805
  capName: "pipeline-analytics",
25680
25806
  capScope: "device",
@@ -25687,6 +25813,12 @@ Object.freeze({
25687
25813
  addonId: null,
25688
25814
  access: "view"
25689
25815
  },
25816
+ "pipelineAnalytics.pruneEvents": {
25817
+ capName: "pipeline-analytics",
25818
+ capScope: "device",
25819
+ addonId: null,
25820
+ access: "create"
25821
+ },
25690
25822
  "pipelineAnalytics.pruneEventsBefore": {
25691
25823
  capName: "pipeline-analytics",
25692
25824
  capScope: "device",
@@ -26449,6 +26581,12 @@ Object.freeze({
26449
26581
  addonId: null,
26450
26582
  access: "create"
26451
26583
  },
26584
+ "recording.deleteFootprint": {
26585
+ capName: "recording",
26586
+ capScope: "system",
26587
+ addonId: null,
26588
+ access: "delete"
26589
+ },
26452
26590
  "recording.getAvailability": {
26453
26591
  capName: "recording",
26454
26592
  capScope: "system",
@@ -26479,6 +26617,12 @@ Object.freeze({
26479
26617
  addonId: null,
26480
26618
  access: "view"
26481
26619
  },
26620
+ "recording.listOpsLog": {
26621
+ capName: "recording",
26622
+ capScope: "system",
26623
+ addonId: null,
26624
+ access: "view"
26625
+ },
26482
26626
  "recording.locateSegment": {
26483
26627
  capName: "recording",
26484
26628
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7381,6 +7381,62 @@ var RecordingConfigSchema = object({
7381
7381
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7382
7382
  });
7383
7383
  /**
7384
+ * Ops-log — the durable, append-only operations audit shared by the
7385
+ * recordings and events management surfaces.
7386
+ *
7387
+ * ONE row shape is reused for both domains so a single "Activity" view can
7388
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7389
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7390
+ * management operation, WHY it ran (reason), and its measurable effect
7391
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7392
+ * never fail the operation it records.
7393
+ */
7394
+ /** Which management domain the operation belongs to. */
7395
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7396
+ /** The kind of management operation performed. */
7397
+ var OpsLogOpSchema = _enum([
7398
+ "prune",
7399
+ "manual-delete",
7400
+ "rescan",
7401
+ "retention-run"
7402
+ ]);
7403
+ /** Why the operation ran. */
7404
+ var OpsLogReasonSchema = _enum([
7405
+ "retention",
7406
+ "quota",
7407
+ "manual",
7408
+ "operator"
7409
+ ]);
7410
+ /** One audit row, shared verbatim by both domains. */
7411
+ var OpsLogEntrySchema = object({
7412
+ /** Unique row id. */
7413
+ id: string(),
7414
+ /** Epoch ms the operation completed. */
7415
+ at: number(),
7416
+ domain: OpsLogDomainSchema,
7417
+ op: OpsLogOpSchema,
7418
+ reason: OpsLogReasonSchema,
7419
+ /** The camera the op targeted; null for a cluster/global op. */
7420
+ deviceId: number().nullable(),
7421
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7422
+ nodeId: string(),
7423
+ /** Buckets / rows deleted (op-specific unit). */
7424
+ itemsAffected: number(),
7425
+ /** Bytes reclaimed by the op (0 when not measurable). */
7426
+ bytesReclaimed: number(),
7427
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7428
+ detail: string().nullable(),
7429
+ /** Who/what triggered the op. */
7430
+ actor: string()
7431
+ });
7432
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7433
+ var OpsLogQueryInputSchema = object({
7434
+ /** Restrict to a single camera; omit for every row. */
7435
+ deviceId: number().optional(),
7436
+ /** Max rows returned, newest-first. */
7437
+ limit: number().int().min(1).max(1e3).optional()
7438
+ });
7439
+ /**
7384
7440
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7385
7441
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7386
7442
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14844,9 +14900,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14844
14900
  * `package` backs the package-drop detector — a package zone is a
14845
14901
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14846
14902
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14847
- * The orchestrator provider that writes this stage lands in a later
14848
- * slice; until then the mirror carries only `{motion, detection}` and
14849
- * consumers read `package` as absent (treat as `[]`).
14903
+ * The orchestrator provider writes this stage as a first-class slice
14904
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14905
+ * package}` shape, so consumers read the current package rules directly
14906
+ * off `device.state.zoneRules.value.package`.
14850
14907
  */
14851
14908
  runtimeState: object({
14852
14909
  motion: array(ZoneRuleSchema).readonly(),
@@ -19180,6 +19237,26 @@ var TrackCascadeCountsSchema = object({
19180
19237
  /** Per-track CLIP search vectors removed (best-effort). */
19181
19238
  embeddings: number().int()
19182
19239
  });
19240
+ /** Event-store footprint for one camera. */
19241
+ var EventStoreDeviceFootprintSchema = object({
19242
+ deviceId: number(),
19243
+ /** Persisted event rows (motion + object + audio) for the camera. */
19244
+ rows: number().int(),
19245
+ /** Event-owned media bytes on disk for the camera. */
19246
+ bytes: number().int()
19247
+ });
19248
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19249
+ var EventStoreFootprintSchema = object({
19250
+ totalRows: number().int(),
19251
+ totalBytes: number().int(),
19252
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19253
+ });
19254
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19255
+ var EventPruneCountsSchema = object({
19256
+ motion: number().int(),
19257
+ object: number().int(),
19258
+ audio: number().int()
19259
+ });
19183
19260
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19184
19261
  deviceId: number(),
19185
19262
  trackId: string()
@@ -19243,6 +19320,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19243
19320
  }), {
19244
19321
  kind: "mutation",
19245
19322
  auth: "admin"
19323
+ }), method(object({}), EventStoreFootprintSchema, {
19324
+ kind: "query",
19325
+ auth: "admin"
19326
+ }), method(object({
19327
+ olderThanMs: number(),
19328
+ reason: OpsLogReasonSchema.optional()
19329
+ }), EventPruneCountsSchema, {
19330
+ kind: "mutation",
19331
+ auth: "admin"
19332
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19333
+ kind: "mutation",
19334
+ auth: "admin"
19335
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19336
+ kind: "query",
19337
+ auth: "admin"
19246
19338
  }), method(object({
19247
19339
  eventId: string(),
19248
19340
  kind: MediaFileKindEnum.optional()
@@ -22476,13 +22568,29 @@ method(object({
22476
22568
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22477
22569
  kind: "mutation",
22478
22570
  auth: "admin"
22479
- }), method(object({ deviceId: number() }), object({
22571
+ }), method(object({
22572
+ deviceId: number(),
22573
+ reason: OpsLogReasonSchema.optional()
22574
+ }), object({
22480
22575
  floorMs: number().nullable(),
22481
22576
  deletedBuckets: number().int(),
22482
22577
  reclaimedBytes: number().int()
22483
22578
  }), {
22484
22579
  kind: "mutation",
22485
22580
  auth: "admin"
22581
+ }), method(object({
22582
+ deviceId: number(),
22583
+ fromMs: number().optional(),
22584
+ toMs: number().optional()
22585
+ }), object({
22586
+ deletedBuckets: number().int(),
22587
+ reclaimedBytes: number().int()
22588
+ }), {
22589
+ kind: "mutation",
22590
+ auth: "admin"
22591
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22592
+ kind: "query",
22593
+ auth: "admin"
22486
22594
  });
22487
22595
  /**
22488
22596
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25604,6 +25712,12 @@ Object.freeze({
25604
25712
  addonId: null,
25605
25713
  access: "delete"
25606
25714
  },
25715
+ "pipelineAnalytics.deleteDeviceEvents": {
25716
+ capName: "pipeline-analytics",
25717
+ capScope: "device",
25718
+ addonId: null,
25719
+ access: "delete"
25720
+ },
25607
25721
  "pipelineAnalytics.deleteTracks": {
25608
25722
  capName: "pipeline-analytics",
25609
25723
  capScope: "device",
@@ -25634,6 +25748,12 @@ Object.freeze({
25634
25748
  addonId: null,
25635
25749
  access: "view"
25636
25750
  },
25751
+ "pipelineAnalytics.getEventStoreFootprint": {
25752
+ capName: "pipeline-analytics",
25753
+ capScope: "device",
25754
+ addonId: null,
25755
+ access: "view"
25756
+ },
25637
25757
  "pipelineAnalytics.getKeyEvents": {
25638
25758
  capName: "pipeline-analytics",
25639
25759
  capScope: "device",
@@ -25676,6 +25796,12 @@ Object.freeze({
25676
25796
  addonId: null,
25677
25797
  access: "view"
25678
25798
  },
25799
+ "pipelineAnalytics.listOpsLog": {
25800
+ capName: "pipeline-analytics",
25801
+ capScope: "device",
25802
+ addonId: null,
25803
+ access: "view"
25804
+ },
25679
25805
  "pipelineAnalytics.listRecentTracks": {
25680
25806
  capName: "pipeline-analytics",
25681
25807
  capScope: "device",
@@ -25688,6 +25814,12 @@ Object.freeze({
25688
25814
  addonId: null,
25689
25815
  access: "view"
25690
25816
  },
25817
+ "pipelineAnalytics.pruneEvents": {
25818
+ capName: "pipeline-analytics",
25819
+ capScope: "device",
25820
+ addonId: null,
25821
+ access: "create"
25822
+ },
25691
25823
  "pipelineAnalytics.pruneEventsBefore": {
25692
25824
  capName: "pipeline-analytics",
25693
25825
  capScope: "device",
@@ -26450,6 +26582,12 @@ Object.freeze({
26450
26582
  addonId: null,
26451
26583
  access: "create"
26452
26584
  },
26585
+ "recording.deleteFootprint": {
26586
+ capName: "recording",
26587
+ capScope: "system",
26588
+ addonId: null,
26589
+ access: "delete"
26590
+ },
26453
26591
  "recording.getAvailability": {
26454
26592
  capName: "recording",
26455
26593
  capScope: "system",
@@ -26480,6 +26618,12 @@ Object.freeze({
26480
26618
  addonId: null,
26481
26619
  access: "view"
26482
26620
  },
26621
+ "recording.listOpsLog": {
26622
+ capName: "recording",
26623
+ capScope: "system",
26624
+ addonId: null,
26625
+ access: "view"
26626
+ },
26483
26627
  "recording.locateSegment": {
26484
26628
  capName: "recording",
26485
26629
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",