@camstack/addon-provider-ecowitt 0.1.25 → 0.1.26

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
@@ -7361,6 +7361,62 @@ var RecordingConfigSchema = object({
7361
7361
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7362
7362
  });
7363
7363
  /**
7364
+ * Ops-log — the durable, append-only operations audit shared by the
7365
+ * recordings and events management surfaces.
7366
+ *
7367
+ * ONE row shape is reused for both domains so a single "Activity" view can
7368
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7369
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7370
+ * management operation, WHY it ran (reason), and its measurable effect
7371
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7372
+ * never fail the operation it records.
7373
+ */
7374
+ /** Which management domain the operation belongs to. */
7375
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7376
+ /** The kind of management operation performed. */
7377
+ var OpsLogOpSchema = _enum([
7378
+ "prune",
7379
+ "manual-delete",
7380
+ "rescan",
7381
+ "retention-run"
7382
+ ]);
7383
+ /** Why the operation ran. */
7384
+ var OpsLogReasonSchema = _enum([
7385
+ "retention",
7386
+ "quota",
7387
+ "manual",
7388
+ "operator"
7389
+ ]);
7390
+ /** One audit row, shared verbatim by both domains. */
7391
+ var OpsLogEntrySchema = object({
7392
+ /** Unique row id. */
7393
+ id: string(),
7394
+ /** Epoch ms the operation completed. */
7395
+ at: number(),
7396
+ domain: OpsLogDomainSchema,
7397
+ op: OpsLogOpSchema,
7398
+ reason: OpsLogReasonSchema,
7399
+ /** The camera the op targeted; null for a cluster/global op. */
7400
+ deviceId: number().nullable(),
7401
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7402
+ nodeId: string(),
7403
+ /** Buckets / rows deleted (op-specific unit). */
7404
+ itemsAffected: number(),
7405
+ /** Bytes reclaimed by the op (0 when not measurable). */
7406
+ bytesReclaimed: number(),
7407
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7408
+ detail: string().nullable(),
7409
+ /** Who/what triggered the op. */
7410
+ actor: string()
7411
+ });
7412
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7413
+ var OpsLogQueryInputSchema = object({
7414
+ /** Restrict to a single camera; omit for every row. */
7415
+ deviceId: number().optional(),
7416
+ /** Max rows returned, newest-first. */
7417
+ limit: number().int().min(1).max(1e3).optional()
7418
+ });
7419
+ /**
7364
7420
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7365
7421
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7366
7422
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14824,9 +14880,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14824
14880
  * `package` backs the package-drop detector — a package zone is a
14825
14881
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14826
14882
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14827
- * The orchestrator provider that writes this stage lands in a later
14828
- * slice; until then the mirror carries only `{motion, detection}` and
14829
- * consumers read `package` as absent (treat as `[]`).
14883
+ * The orchestrator provider writes this stage as a first-class slice
14884
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14885
+ * package}` shape, so consumers read the current package rules directly
14886
+ * off `device.state.zoneRules.value.package`.
14830
14887
  */
14831
14888
  runtimeState: object({
14832
14889
  motion: array(ZoneRuleSchema).readonly(),
@@ -19143,6 +19200,26 @@ var TrackCascadeCountsSchema = object({
19143
19200
  /** Per-track CLIP search vectors removed (best-effort). */
19144
19201
  embeddings: number().int()
19145
19202
  });
19203
+ /** Event-store footprint for one camera. */
19204
+ var EventStoreDeviceFootprintSchema = object({
19205
+ deviceId: number(),
19206
+ /** Persisted event rows (motion + object + audio) for the camera. */
19207
+ rows: number().int(),
19208
+ /** Event-owned media bytes on disk for the camera. */
19209
+ bytes: number().int()
19210
+ });
19211
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19212
+ var EventStoreFootprintSchema = object({
19213
+ totalRows: number().int(),
19214
+ totalBytes: number().int(),
19215
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19216
+ });
19217
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19218
+ var EventPruneCountsSchema = object({
19219
+ motion: number().int(),
19220
+ object: number().int(),
19221
+ audio: number().int()
19222
+ });
19146
19223
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19147
19224
  deviceId: number(),
19148
19225
  trackId: string()
@@ -19206,6 +19283,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19206
19283
  }), {
19207
19284
  kind: "mutation",
19208
19285
  auth: "admin"
19286
+ }), method(object({}), EventStoreFootprintSchema, {
19287
+ kind: "query",
19288
+ auth: "admin"
19289
+ }), method(object({
19290
+ olderThanMs: number(),
19291
+ reason: OpsLogReasonSchema.optional()
19292
+ }), EventPruneCountsSchema, {
19293
+ kind: "mutation",
19294
+ auth: "admin"
19295
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19296
+ kind: "mutation",
19297
+ auth: "admin"
19298
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19299
+ kind: "query",
19300
+ auth: "admin"
19209
19301
  }), method(object({
19210
19302
  eventId: string(),
19211
19303
  kind: MediaFileKindEnum.optional()
@@ -22439,13 +22531,29 @@ method(object({
22439
22531
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22440
22532
  kind: "mutation",
22441
22533
  auth: "admin"
22442
- }), method(object({ deviceId: number() }), object({
22534
+ }), method(object({
22535
+ deviceId: number(),
22536
+ reason: OpsLogReasonSchema.optional()
22537
+ }), object({
22443
22538
  floorMs: number().nullable(),
22444
22539
  deletedBuckets: number().int(),
22445
22540
  reclaimedBytes: number().int()
22446
22541
  }), {
22447
22542
  kind: "mutation",
22448
22543
  auth: "admin"
22544
+ }), method(object({
22545
+ deviceId: number(),
22546
+ fromMs: number().optional(),
22547
+ toMs: number().optional()
22548
+ }), object({
22549
+ deletedBuckets: number().int(),
22550
+ reclaimedBytes: number().int()
22551
+ }), {
22552
+ kind: "mutation",
22553
+ auth: "admin"
22554
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22555
+ kind: "query",
22556
+ auth: "admin"
22449
22557
  });
22450
22558
  /**
22451
22559
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25567,6 +25675,12 @@ Object.freeze({
25567
25675
  addonId: null,
25568
25676
  access: "delete"
25569
25677
  },
25678
+ "pipelineAnalytics.deleteDeviceEvents": {
25679
+ capName: "pipeline-analytics",
25680
+ capScope: "device",
25681
+ addonId: null,
25682
+ access: "delete"
25683
+ },
25570
25684
  "pipelineAnalytics.deleteTracks": {
25571
25685
  capName: "pipeline-analytics",
25572
25686
  capScope: "device",
@@ -25597,6 +25711,12 @@ Object.freeze({
25597
25711
  addonId: null,
25598
25712
  access: "view"
25599
25713
  },
25714
+ "pipelineAnalytics.getEventStoreFootprint": {
25715
+ capName: "pipeline-analytics",
25716
+ capScope: "device",
25717
+ addonId: null,
25718
+ access: "view"
25719
+ },
25600
25720
  "pipelineAnalytics.getKeyEvents": {
25601
25721
  capName: "pipeline-analytics",
25602
25722
  capScope: "device",
@@ -25639,6 +25759,12 @@ Object.freeze({
25639
25759
  addonId: null,
25640
25760
  access: "view"
25641
25761
  },
25762
+ "pipelineAnalytics.listOpsLog": {
25763
+ capName: "pipeline-analytics",
25764
+ capScope: "device",
25765
+ addonId: null,
25766
+ access: "view"
25767
+ },
25642
25768
  "pipelineAnalytics.listRecentTracks": {
25643
25769
  capName: "pipeline-analytics",
25644
25770
  capScope: "device",
@@ -25651,6 +25777,12 @@ Object.freeze({
25651
25777
  addonId: null,
25652
25778
  access: "view"
25653
25779
  },
25780
+ "pipelineAnalytics.pruneEvents": {
25781
+ capName: "pipeline-analytics",
25782
+ capScope: "device",
25783
+ addonId: null,
25784
+ access: "create"
25785
+ },
25654
25786
  "pipelineAnalytics.pruneEventsBefore": {
25655
25787
  capName: "pipeline-analytics",
25656
25788
  capScope: "device",
@@ -26413,6 +26545,12 @@ Object.freeze({
26413
26545
  addonId: null,
26414
26546
  access: "create"
26415
26547
  },
26548
+ "recording.deleteFootprint": {
26549
+ capName: "recording",
26550
+ capScope: "system",
26551
+ addonId: null,
26552
+ access: "delete"
26553
+ },
26416
26554
  "recording.getAvailability": {
26417
26555
  capName: "recording",
26418
26556
  capScope: "system",
@@ -26443,6 +26581,12 @@ Object.freeze({
26443
26581
  addonId: null,
26444
26582
  access: "view"
26445
26583
  },
26584
+ "recording.listOpsLog": {
26585
+ capName: "recording",
26586
+ capScope: "system",
26587
+ addonId: null,
26588
+ access: "view"
26589
+ },
26446
26590
  "recording.locateSegment": {
26447
26591
  capName: "recording",
26448
26592
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7360,6 +7360,62 @@ var RecordingConfigSchema = object({
7360
7360
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7361
7361
  });
7362
7362
  /**
7363
+ * Ops-log — the durable, append-only operations audit shared by the
7364
+ * recordings and events management surfaces.
7365
+ *
7366
+ * ONE row shape is reused for both domains so a single "Activity" view can
7367
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7368
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7369
+ * management operation, WHY it ran (reason), and its measurable effect
7370
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7371
+ * never fail the operation it records.
7372
+ */
7373
+ /** Which management domain the operation belongs to. */
7374
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7375
+ /** The kind of management operation performed. */
7376
+ var OpsLogOpSchema = _enum([
7377
+ "prune",
7378
+ "manual-delete",
7379
+ "rescan",
7380
+ "retention-run"
7381
+ ]);
7382
+ /** Why the operation ran. */
7383
+ var OpsLogReasonSchema = _enum([
7384
+ "retention",
7385
+ "quota",
7386
+ "manual",
7387
+ "operator"
7388
+ ]);
7389
+ /** One audit row, shared verbatim by both domains. */
7390
+ var OpsLogEntrySchema = object({
7391
+ /** Unique row id. */
7392
+ id: string(),
7393
+ /** Epoch ms the operation completed. */
7394
+ at: number(),
7395
+ domain: OpsLogDomainSchema,
7396
+ op: OpsLogOpSchema,
7397
+ reason: OpsLogReasonSchema,
7398
+ /** The camera the op targeted; null for a cluster/global op. */
7399
+ deviceId: number().nullable(),
7400
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7401
+ nodeId: string(),
7402
+ /** Buckets / rows deleted (op-specific unit). */
7403
+ itemsAffected: number(),
7404
+ /** Bytes reclaimed by the op (0 when not measurable). */
7405
+ bytesReclaimed: number(),
7406
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7407
+ detail: string().nullable(),
7408
+ /** Who/what triggered the op. */
7409
+ actor: string()
7410
+ });
7411
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7412
+ var OpsLogQueryInputSchema = object({
7413
+ /** Restrict to a single camera; omit for every row. */
7414
+ deviceId: number().optional(),
7415
+ /** Max rows returned, newest-first. */
7416
+ limit: number().int().min(1).max(1e3).optional()
7417
+ });
7418
+ /**
7363
7419
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7364
7420
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7365
7421
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14823,9 +14879,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14823
14879
  * `package` backs the package-drop detector — a package zone is a
14824
14880
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14825
14881
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14826
- * The orchestrator provider that writes this stage lands in a later
14827
- * slice; until then the mirror carries only `{motion, detection}` and
14828
- * consumers read `package` as absent (treat as `[]`).
14882
+ * The orchestrator provider writes this stage as a first-class slice
14883
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14884
+ * package}` shape, so consumers read the current package rules directly
14885
+ * off `device.state.zoneRules.value.package`.
14829
14886
  */
14830
14887
  runtimeState: object({
14831
14888
  motion: array(ZoneRuleSchema).readonly(),
@@ -19142,6 +19199,26 @@ var TrackCascadeCountsSchema = object({
19142
19199
  /** Per-track CLIP search vectors removed (best-effort). */
19143
19200
  embeddings: number().int()
19144
19201
  });
19202
+ /** Event-store footprint for one camera. */
19203
+ var EventStoreDeviceFootprintSchema = object({
19204
+ deviceId: number(),
19205
+ /** Persisted event rows (motion + object + audio) for the camera. */
19206
+ rows: number().int(),
19207
+ /** Event-owned media bytes on disk for the camera. */
19208
+ bytes: number().int()
19209
+ });
19210
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19211
+ var EventStoreFootprintSchema = object({
19212
+ totalRows: number().int(),
19213
+ totalBytes: number().int(),
19214
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19215
+ });
19216
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19217
+ var EventPruneCountsSchema = object({
19218
+ motion: number().int(),
19219
+ object: number().int(),
19220
+ audio: number().int()
19221
+ });
19145
19222
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19146
19223
  deviceId: number(),
19147
19224
  trackId: string()
@@ -19205,6 +19282,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19205
19282
  }), {
19206
19283
  kind: "mutation",
19207
19284
  auth: "admin"
19285
+ }), method(object({}), EventStoreFootprintSchema, {
19286
+ kind: "query",
19287
+ auth: "admin"
19288
+ }), method(object({
19289
+ olderThanMs: number(),
19290
+ reason: OpsLogReasonSchema.optional()
19291
+ }), EventPruneCountsSchema, {
19292
+ kind: "mutation",
19293
+ auth: "admin"
19294
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19295
+ kind: "mutation",
19296
+ auth: "admin"
19297
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19298
+ kind: "query",
19299
+ auth: "admin"
19208
19300
  }), method(object({
19209
19301
  eventId: string(),
19210
19302
  kind: MediaFileKindEnum.optional()
@@ -22438,13 +22530,29 @@ method(object({
22438
22530
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22439
22531
  kind: "mutation",
22440
22532
  auth: "admin"
22441
- }), method(object({ deviceId: number() }), object({
22533
+ }), method(object({
22534
+ deviceId: number(),
22535
+ reason: OpsLogReasonSchema.optional()
22536
+ }), object({
22442
22537
  floorMs: number().nullable(),
22443
22538
  deletedBuckets: number().int(),
22444
22539
  reclaimedBytes: number().int()
22445
22540
  }), {
22446
22541
  kind: "mutation",
22447
22542
  auth: "admin"
22543
+ }), method(object({
22544
+ deviceId: number(),
22545
+ fromMs: number().optional(),
22546
+ toMs: number().optional()
22547
+ }), object({
22548
+ deletedBuckets: number().int(),
22549
+ reclaimedBytes: number().int()
22550
+ }), {
22551
+ kind: "mutation",
22552
+ auth: "admin"
22553
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22554
+ kind: "query",
22555
+ auth: "admin"
22448
22556
  });
22449
22557
  /**
22450
22558
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25566,6 +25674,12 @@ Object.freeze({
25566
25674
  addonId: null,
25567
25675
  access: "delete"
25568
25676
  },
25677
+ "pipelineAnalytics.deleteDeviceEvents": {
25678
+ capName: "pipeline-analytics",
25679
+ capScope: "device",
25680
+ addonId: null,
25681
+ access: "delete"
25682
+ },
25569
25683
  "pipelineAnalytics.deleteTracks": {
25570
25684
  capName: "pipeline-analytics",
25571
25685
  capScope: "device",
@@ -25596,6 +25710,12 @@ Object.freeze({
25596
25710
  addonId: null,
25597
25711
  access: "view"
25598
25712
  },
25713
+ "pipelineAnalytics.getEventStoreFootprint": {
25714
+ capName: "pipeline-analytics",
25715
+ capScope: "device",
25716
+ addonId: null,
25717
+ access: "view"
25718
+ },
25599
25719
  "pipelineAnalytics.getKeyEvents": {
25600
25720
  capName: "pipeline-analytics",
25601
25721
  capScope: "device",
@@ -25638,6 +25758,12 @@ Object.freeze({
25638
25758
  addonId: null,
25639
25759
  access: "view"
25640
25760
  },
25761
+ "pipelineAnalytics.listOpsLog": {
25762
+ capName: "pipeline-analytics",
25763
+ capScope: "device",
25764
+ addonId: null,
25765
+ access: "view"
25766
+ },
25641
25767
  "pipelineAnalytics.listRecentTracks": {
25642
25768
  capName: "pipeline-analytics",
25643
25769
  capScope: "device",
@@ -25650,6 +25776,12 @@ Object.freeze({
25650
25776
  addonId: null,
25651
25777
  access: "view"
25652
25778
  },
25779
+ "pipelineAnalytics.pruneEvents": {
25780
+ capName: "pipeline-analytics",
25781
+ capScope: "device",
25782
+ addonId: null,
25783
+ access: "create"
25784
+ },
25653
25785
  "pipelineAnalytics.pruneEventsBefore": {
25654
25786
  capName: "pipeline-analytics",
25655
25787
  capScope: "device",
@@ -26412,6 +26544,12 @@ Object.freeze({
26412
26544
  addonId: null,
26413
26545
  access: "create"
26414
26546
  },
26547
+ "recording.deleteFootprint": {
26548
+ capName: "recording",
26549
+ capScope: "system",
26550
+ addonId: null,
26551
+ access: "delete"
26552
+ },
26415
26553
  "recording.getAvailability": {
26416
26554
  capName: "recording",
26417
26555
  capScope: "system",
@@ -26442,6 +26580,12 @@ Object.freeze({
26442
26580
  addonId: null,
26443
26581
  access: "view"
26444
26582
  },
26583
+ "recording.listOpsLog": {
26584
+ capName: "recording",
26585
+ capScope: "system",
26586
+ addonId: null,
26587
+ access: "view"
26588
+ },
26445
26589
  "recording.locateSegment": {
26446
26590
  capName: "recording",
26447
26591
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-ecowitt",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "Ecowitt weather-station device-provider addon for CamStack — wraps the @apocaliss92/nodewitt local-poll / push client",
5
5
  "keywords": [
6
6
  "camstack",