@camstack/addon-ai 0.1.5 → 0.1.7
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 +336 -5
- package/dist/addon.mjs +336 -5
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -43,7 +43,7 @@ let node_fs_promises = require("node:fs/promises");
|
|
|
43
43
|
node_fs_promises = __toESM(node_fs_promises);
|
|
44
44
|
let node_child_process = require("node:child_process");
|
|
45
45
|
let node_net = require("node:net");
|
|
46
|
-
//#region ../types/dist/event-category-
|
|
46
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
47
47
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
48
48
|
EventCategory["SystemBoot"] = "system.boot";
|
|
49
49
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -196,6 +196,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
196
196
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
197
197
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
198
198
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
199
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
200
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
201
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
202
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
203
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
199
204
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
200
205
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
201
206
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -485,6 +490,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
485
490
|
*/
|
|
486
491
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
487
492
|
/**
|
|
493
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
494
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
495
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
496
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
497
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
498
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
499
|
+
* this bus topic drives notifier rules + live UI. See
|
|
500
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
501
|
+
*/
|
|
502
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
503
|
+
/**
|
|
504
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
505
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
506
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
507
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
508
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
509
|
+
*/
|
|
510
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
511
|
+
/**
|
|
488
512
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
489
513
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
490
514
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5223,6 +5247,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5223
5247
|
};
|
|
5224
5248
|
return inst;
|
|
5225
5249
|
}
|
|
5250
|
+
//#endregion
|
|
5251
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5252
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5253
|
+
var ZodIssueCode = {
|
|
5254
|
+
invalid_type: "invalid_type",
|
|
5255
|
+
too_big: "too_big",
|
|
5256
|
+
too_small: "too_small",
|
|
5257
|
+
invalid_format: "invalid_format",
|
|
5258
|
+
not_multiple_of: "not_multiple_of",
|
|
5259
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5260
|
+
invalid_union: "invalid_union",
|
|
5261
|
+
invalid_key: "invalid_key",
|
|
5262
|
+
invalid_element: "invalid_element",
|
|
5263
|
+
invalid_value: "invalid_value",
|
|
5264
|
+
custom: "custom"
|
|
5265
|
+
};
|
|
5266
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5267
|
+
var ZodFirstPartyTypeKind;
|
|
5268
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5226
5269
|
Object.fromEntries([
|
|
5227
5270
|
{
|
|
5228
5271
|
id: "overview",
|
|
@@ -7329,6 +7372,62 @@ var RecordingConfigSchema = object({
|
|
|
7329
7372
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7330
7373
|
});
|
|
7331
7374
|
/**
|
|
7375
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7376
|
+
* recordings and events management surfaces.
|
|
7377
|
+
*
|
|
7378
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7379
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7380
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7381
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7382
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7383
|
+
* never fail the operation it records.
|
|
7384
|
+
*/
|
|
7385
|
+
/** Which management domain the operation belongs to. */
|
|
7386
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7387
|
+
/** The kind of management operation performed. */
|
|
7388
|
+
var OpsLogOpSchema = _enum([
|
|
7389
|
+
"prune",
|
|
7390
|
+
"manual-delete",
|
|
7391
|
+
"rescan",
|
|
7392
|
+
"retention-run"
|
|
7393
|
+
]);
|
|
7394
|
+
/** Why the operation ran. */
|
|
7395
|
+
var OpsLogReasonSchema = _enum([
|
|
7396
|
+
"retention",
|
|
7397
|
+
"quota",
|
|
7398
|
+
"manual",
|
|
7399
|
+
"operator"
|
|
7400
|
+
]);
|
|
7401
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7402
|
+
var OpsLogEntrySchema = object({
|
|
7403
|
+
/** Unique row id. */
|
|
7404
|
+
id: string(),
|
|
7405
|
+
/** Epoch ms the operation completed. */
|
|
7406
|
+
at: number(),
|
|
7407
|
+
domain: OpsLogDomainSchema,
|
|
7408
|
+
op: OpsLogOpSchema,
|
|
7409
|
+
reason: OpsLogReasonSchema,
|
|
7410
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7411
|
+
deviceId: number().nullable(),
|
|
7412
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7413
|
+
nodeId: string(),
|
|
7414
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7415
|
+
itemsAffected: number(),
|
|
7416
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7417
|
+
bytesReclaimed: number(),
|
|
7418
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7419
|
+
detail: string().nullable(),
|
|
7420
|
+
/** Who/what triggered the op. */
|
|
7421
|
+
actor: string()
|
|
7422
|
+
});
|
|
7423
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7424
|
+
var OpsLogQueryInputSchema = object({
|
|
7425
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7426
|
+
deviceId: number().optional(),
|
|
7427
|
+
/** Max rows returned, newest-first. */
|
|
7428
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7429
|
+
});
|
|
7430
|
+
/**
|
|
7332
7431
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7333
7432
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7334
7433
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -12608,7 +12707,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12608
12707
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12609
12708
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12610
12709
|
*/
|
|
12611
|
-
var ZoneRuleStageEnum = _enum([
|
|
12710
|
+
var ZoneRuleStageEnum = _enum([
|
|
12711
|
+
"motion",
|
|
12712
|
+
"detection",
|
|
12713
|
+
"package"
|
|
12714
|
+
]);
|
|
12612
12715
|
DeviceType.Camera, method(object({
|
|
12613
12716
|
deviceId: number(),
|
|
12614
12717
|
stage: ZoneRuleStageEnum
|
|
@@ -12621,7 +12724,8 @@ DeviceType.Camera, method(object({
|
|
|
12621
12724
|
auth: "admin"
|
|
12622
12725
|
}), object({
|
|
12623
12726
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12624
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12727
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12728
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12625
12729
|
});
|
|
12626
12730
|
var ProviderStatusSchema = object({
|
|
12627
12731
|
connected: boolean(),
|
|
@@ -15849,6 +15953,7 @@ var EventKindIconSchema = _enum([
|
|
|
15849
15953
|
"smoke",
|
|
15850
15954
|
"water",
|
|
15851
15955
|
"button",
|
|
15956
|
+
"package",
|
|
15852
15957
|
"generic"
|
|
15853
15958
|
]);
|
|
15854
15959
|
var EventKindCategorySchema = _enum([
|
|
@@ -15856,7 +15961,8 @@ var EventKindCategorySchema = _enum([
|
|
|
15856
15961
|
"audio",
|
|
15857
15962
|
"detection",
|
|
15858
15963
|
"sensor",
|
|
15859
|
-
"custom"
|
|
15964
|
+
"custom",
|
|
15965
|
+
"package"
|
|
15860
15966
|
]);
|
|
15861
15967
|
var EventKindDescriptorSchema = object({
|
|
15862
15968
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -16197,6 +16303,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
16197
16303
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
16198
16304
|
embeddings: number().int()
|
|
16199
16305
|
});
|
|
16306
|
+
/** Event-store footprint for one camera. */
|
|
16307
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
16308
|
+
deviceId: number(),
|
|
16309
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
16310
|
+
rows: number().int(),
|
|
16311
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
16312
|
+
bytes: number().int()
|
|
16313
|
+
});
|
|
16314
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
16315
|
+
var EventStoreFootprintSchema = object({
|
|
16316
|
+
totalRows: number().int(),
|
|
16317
|
+
totalBytes: number().int(),
|
|
16318
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
16319
|
+
});
|
|
16320
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
16321
|
+
var EventPruneCountsSchema = object({
|
|
16322
|
+
motion: number().int(),
|
|
16323
|
+
object: number().int(),
|
|
16324
|
+
audio: number().int()
|
|
16325
|
+
});
|
|
16200
16326
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
16201
16327
|
deviceId: number(),
|
|
16202
16328
|
trackId: string()
|
|
@@ -16260,6 +16386,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16260
16386
|
}), {
|
|
16261
16387
|
kind: "mutation",
|
|
16262
16388
|
auth: "admin"
|
|
16389
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
16390
|
+
kind: "query",
|
|
16391
|
+
auth: "admin"
|
|
16392
|
+
}), method(object({
|
|
16393
|
+
olderThanMs: number(),
|
|
16394
|
+
reason: OpsLogReasonSchema.optional()
|
|
16395
|
+
}), EventPruneCountsSchema, {
|
|
16396
|
+
kind: "mutation",
|
|
16397
|
+
auth: "admin"
|
|
16398
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
16399
|
+
kind: "mutation",
|
|
16400
|
+
auth: "admin"
|
|
16401
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
16402
|
+
kind: "query",
|
|
16403
|
+
auth: "admin"
|
|
16263
16404
|
}), method(object({
|
|
16264
16405
|
eventId: string(),
|
|
16265
16406
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19493,13 +19634,131 @@ method(object({
|
|
|
19493
19634
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
19494
19635
|
kind: "mutation",
|
|
19495
19636
|
auth: "admin"
|
|
19496
|
-
}), method(object({
|
|
19637
|
+
}), method(object({
|
|
19638
|
+
deviceId: number(),
|
|
19639
|
+
reason: OpsLogReasonSchema.optional()
|
|
19640
|
+
}), object({
|
|
19497
19641
|
floorMs: number().nullable(),
|
|
19498
19642
|
deletedBuckets: number().int(),
|
|
19499
19643
|
reclaimedBytes: number().int()
|
|
19500
19644
|
}), {
|
|
19501
19645
|
kind: "mutation",
|
|
19502
19646
|
auth: "admin"
|
|
19647
|
+
}), method(object({
|
|
19648
|
+
deviceId: number(),
|
|
19649
|
+
fromMs: number().optional(),
|
|
19650
|
+
toMs: number().optional()
|
|
19651
|
+
}), object({
|
|
19652
|
+
deletedBuckets: number().int(),
|
|
19653
|
+
reclaimedBytes: number().int()
|
|
19654
|
+
}), {
|
|
19655
|
+
kind: "mutation",
|
|
19656
|
+
auth: "admin"
|
|
19657
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19658
|
+
kind: "query",
|
|
19659
|
+
auth: "admin"
|
|
19660
|
+
});
|
|
19661
|
+
/**
|
|
19662
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19663
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19664
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19665
|
+
* delete-after-download.
|
|
19666
|
+
*
|
|
19667
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19668
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19669
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19670
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19671
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19672
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19673
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19674
|
+
*/
|
|
19675
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19676
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19677
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19678
|
+
var ExportTimelapseSchema = object({
|
|
19679
|
+
everyMs: number().int().positive(),
|
|
19680
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19681
|
+
});
|
|
19682
|
+
/**
|
|
19683
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19684
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19685
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19686
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19687
|
+
*/
|
|
19688
|
+
var ExportOptionsSchema = object({
|
|
19689
|
+
speed: ExportSpeedSchema.optional(),
|
|
19690
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19691
|
+
includeAudio: boolean(),
|
|
19692
|
+
maxLifeMs: number().int().positive(),
|
|
19693
|
+
deleteAfterDownload: boolean(),
|
|
19694
|
+
title: string().max(200).optional()
|
|
19695
|
+
}).superRefine((v, ctx) => {
|
|
19696
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19697
|
+
code: ZodIssueCode.custom,
|
|
19698
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19699
|
+
path: ["timelapse"]
|
|
19700
|
+
});
|
|
19701
|
+
});
|
|
19702
|
+
var ExportStateSchema = _enum([
|
|
19703
|
+
"queued",
|
|
19704
|
+
"rendering",
|
|
19705
|
+
"ready",
|
|
19706
|
+
"failed",
|
|
19707
|
+
"expired",
|
|
19708
|
+
"deleted"
|
|
19709
|
+
]);
|
|
19710
|
+
/** One export job / history row. */
|
|
19711
|
+
var ExportRecordSchema = object({
|
|
19712
|
+
id: string(),
|
|
19713
|
+
deviceId: number(),
|
|
19714
|
+
profile: string(),
|
|
19715
|
+
fromMs: number(),
|
|
19716
|
+
toMs: number(),
|
|
19717
|
+
options: ExportOptionsSchema,
|
|
19718
|
+
state: ExportStateSchema,
|
|
19719
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19720
|
+
progressPct: number().nullable(),
|
|
19721
|
+
/** File size once ready; null before. */
|
|
19722
|
+
fileBytes: number().nullable(),
|
|
19723
|
+
expiresAt: number(),
|
|
19724
|
+
deleteAfterDownload: boolean(),
|
|
19725
|
+
/** Epoch of the first complete download; null until then. */
|
|
19726
|
+
downloadedAt: number().nullable(),
|
|
19727
|
+
createdAt: number(),
|
|
19728
|
+
/** User id/name that requested the export. */
|
|
19729
|
+
createdBy: string(),
|
|
19730
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19731
|
+
error: string().nullable()
|
|
19732
|
+
});
|
|
19733
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19734
|
+
var ExportDownloadSchema = object({
|
|
19735
|
+
url: string(),
|
|
19736
|
+
endpoints: array(string())
|
|
19737
|
+
});
|
|
19738
|
+
method(object({
|
|
19739
|
+
deviceId: number(),
|
|
19740
|
+
profile: string(),
|
|
19741
|
+
fromMs: number(),
|
|
19742
|
+
toMs: number(),
|
|
19743
|
+
options: ExportOptionsSchema
|
|
19744
|
+
}), ExportRecordSchema, {
|
|
19745
|
+
kind: "mutation",
|
|
19746
|
+
auth: "protected"
|
|
19747
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19748
|
+
kind: "query",
|
|
19749
|
+
auth: "protected"
|
|
19750
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19751
|
+
kind: "query",
|
|
19752
|
+
auth: "protected"
|
|
19753
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19754
|
+
kind: "mutation",
|
|
19755
|
+
auth: "protected"
|
|
19756
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19757
|
+
kind: "mutation",
|
|
19758
|
+
auth: "protected"
|
|
19759
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19760
|
+
kind: "query",
|
|
19761
|
+
auth: "protected"
|
|
19503
19762
|
});
|
|
19504
19763
|
/**
|
|
19505
19764
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -22519,6 +22778,12 @@ Object.freeze({
|
|
|
22519
22778
|
addonId: null,
|
|
22520
22779
|
access: "delete"
|
|
22521
22780
|
},
|
|
22781
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
22782
|
+
capName: "pipeline-analytics",
|
|
22783
|
+
capScope: "device",
|
|
22784
|
+
addonId: null,
|
|
22785
|
+
access: "delete"
|
|
22786
|
+
},
|
|
22522
22787
|
"pipelineAnalytics.deleteTracks": {
|
|
22523
22788
|
capName: "pipeline-analytics",
|
|
22524
22789
|
capScope: "device",
|
|
@@ -22549,6 +22814,12 @@ Object.freeze({
|
|
|
22549
22814
|
addonId: null,
|
|
22550
22815
|
access: "view"
|
|
22551
22816
|
},
|
|
22817
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
22818
|
+
capName: "pipeline-analytics",
|
|
22819
|
+
capScope: "device",
|
|
22820
|
+
addonId: null,
|
|
22821
|
+
access: "view"
|
|
22822
|
+
},
|
|
22552
22823
|
"pipelineAnalytics.getKeyEvents": {
|
|
22553
22824
|
capName: "pipeline-analytics",
|
|
22554
22825
|
capScope: "device",
|
|
@@ -22591,6 +22862,12 @@ Object.freeze({
|
|
|
22591
22862
|
addonId: null,
|
|
22592
22863
|
access: "view"
|
|
22593
22864
|
},
|
|
22865
|
+
"pipelineAnalytics.listOpsLog": {
|
|
22866
|
+
capName: "pipeline-analytics",
|
|
22867
|
+
capScope: "device",
|
|
22868
|
+
addonId: null,
|
|
22869
|
+
access: "view"
|
|
22870
|
+
},
|
|
22594
22871
|
"pipelineAnalytics.listRecentTracks": {
|
|
22595
22872
|
capName: "pipeline-analytics",
|
|
22596
22873
|
capScope: "device",
|
|
@@ -22603,6 +22880,12 @@ Object.freeze({
|
|
|
22603
22880
|
addonId: null,
|
|
22604
22881
|
access: "view"
|
|
22605
22882
|
},
|
|
22883
|
+
"pipelineAnalytics.pruneEvents": {
|
|
22884
|
+
capName: "pipeline-analytics",
|
|
22885
|
+
capScope: "device",
|
|
22886
|
+
addonId: null,
|
|
22887
|
+
access: "create"
|
|
22888
|
+
},
|
|
22606
22889
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
22607
22890
|
capName: "pipeline-analytics",
|
|
22608
22891
|
capScope: "device",
|
|
@@ -23365,6 +23648,12 @@ Object.freeze({
|
|
|
23365
23648
|
addonId: null,
|
|
23366
23649
|
access: "create"
|
|
23367
23650
|
},
|
|
23651
|
+
"recording.deleteFootprint": {
|
|
23652
|
+
capName: "recording",
|
|
23653
|
+
capScope: "system",
|
|
23654
|
+
addonId: null,
|
|
23655
|
+
access: "delete"
|
|
23656
|
+
},
|
|
23368
23657
|
"recording.getAvailability": {
|
|
23369
23658
|
capName: "recording",
|
|
23370
23659
|
capScope: "system",
|
|
@@ -23395,6 +23684,12 @@ Object.freeze({
|
|
|
23395
23684
|
addonId: null,
|
|
23396
23685
|
access: "view"
|
|
23397
23686
|
},
|
|
23687
|
+
"recording.listOpsLog": {
|
|
23688
|
+
capName: "recording",
|
|
23689
|
+
capScope: "system",
|
|
23690
|
+
addonId: null,
|
|
23691
|
+
access: "view"
|
|
23692
|
+
},
|
|
23398
23693
|
"recording.locateSegment": {
|
|
23399
23694
|
capName: "recording",
|
|
23400
23695
|
capScope: "system",
|
|
@@ -23425,6 +23720,42 @@ Object.freeze({
|
|
|
23425
23720
|
addonId: null,
|
|
23426
23721
|
access: "create"
|
|
23427
23722
|
},
|
|
23723
|
+
"recordingExport.cancelExport": {
|
|
23724
|
+
capName: "recordingExport",
|
|
23725
|
+
capScope: "system",
|
|
23726
|
+
addonId: null,
|
|
23727
|
+
access: "create"
|
|
23728
|
+
},
|
|
23729
|
+
"recordingExport.createExport": {
|
|
23730
|
+
capName: "recordingExport",
|
|
23731
|
+
capScope: "system",
|
|
23732
|
+
addonId: null,
|
|
23733
|
+
access: "create"
|
|
23734
|
+
},
|
|
23735
|
+
"recordingExport.deleteExport": {
|
|
23736
|
+
capName: "recordingExport",
|
|
23737
|
+
capScope: "system",
|
|
23738
|
+
addonId: null,
|
|
23739
|
+
access: "delete"
|
|
23740
|
+
},
|
|
23741
|
+
"recordingExport.getDownloadUrl": {
|
|
23742
|
+
capName: "recordingExport",
|
|
23743
|
+
capScope: "system",
|
|
23744
|
+
addonId: null,
|
|
23745
|
+
access: "view"
|
|
23746
|
+
},
|
|
23747
|
+
"recordingExport.getExport": {
|
|
23748
|
+
capName: "recordingExport",
|
|
23749
|
+
capScope: "system",
|
|
23750
|
+
addonId: null,
|
|
23751
|
+
access: "view"
|
|
23752
|
+
},
|
|
23753
|
+
"recordingExport.listExports": {
|
|
23754
|
+
capName: "recordingExport",
|
|
23755
|
+
capScope: "system",
|
|
23756
|
+
addonId: null,
|
|
23757
|
+
access: "view"
|
|
23758
|
+
},
|
|
23428
23759
|
"sceneMonitor.captureReference": {
|
|
23429
23760
|
capName: "scene-monitor",
|
|
23430
23761
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { createReadStream } from "node:fs";
|
|
|
5
5
|
import * as fsp from "node:fs/promises";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import { createServer } from "node:net";
|
|
8
|
-
//#region ../types/dist/event-category-
|
|
8
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
9
9
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
10
10
|
EventCategory["SystemBoot"] = "system.boot";
|
|
11
11
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -158,6 +158,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
158
158
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
159
159
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
160
160
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
161
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
162
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
163
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
164
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
165
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
161
166
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
162
167
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
163
168
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -447,6 +452,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
447
452
|
*/
|
|
448
453
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
449
454
|
/**
|
|
455
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
456
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
457
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
458
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
459
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
460
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
461
|
+
* this bus topic drives notifier rules + live UI. See
|
|
462
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
463
|
+
*/
|
|
464
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
465
|
+
/**
|
|
466
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
467
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
468
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
469
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
470
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
471
|
+
*/
|
|
472
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
473
|
+
/**
|
|
450
474
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
451
475
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
452
476
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5185,6 +5209,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5185
5209
|
};
|
|
5186
5210
|
return inst;
|
|
5187
5211
|
}
|
|
5212
|
+
//#endregion
|
|
5213
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5214
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5215
|
+
var ZodIssueCode = {
|
|
5216
|
+
invalid_type: "invalid_type",
|
|
5217
|
+
too_big: "too_big",
|
|
5218
|
+
too_small: "too_small",
|
|
5219
|
+
invalid_format: "invalid_format",
|
|
5220
|
+
not_multiple_of: "not_multiple_of",
|
|
5221
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5222
|
+
invalid_union: "invalid_union",
|
|
5223
|
+
invalid_key: "invalid_key",
|
|
5224
|
+
invalid_element: "invalid_element",
|
|
5225
|
+
invalid_value: "invalid_value",
|
|
5226
|
+
custom: "custom"
|
|
5227
|
+
};
|
|
5228
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5229
|
+
var ZodFirstPartyTypeKind;
|
|
5230
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5188
5231
|
Object.fromEntries([
|
|
5189
5232
|
{
|
|
5190
5233
|
id: "overview",
|
|
@@ -7291,6 +7334,62 @@ var RecordingConfigSchema = object({
|
|
|
7291
7334
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7292
7335
|
});
|
|
7293
7336
|
/**
|
|
7337
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7338
|
+
* recordings and events management surfaces.
|
|
7339
|
+
*
|
|
7340
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7341
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7342
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7343
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7344
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7345
|
+
* never fail the operation it records.
|
|
7346
|
+
*/
|
|
7347
|
+
/** Which management domain the operation belongs to. */
|
|
7348
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7349
|
+
/** The kind of management operation performed. */
|
|
7350
|
+
var OpsLogOpSchema = _enum([
|
|
7351
|
+
"prune",
|
|
7352
|
+
"manual-delete",
|
|
7353
|
+
"rescan",
|
|
7354
|
+
"retention-run"
|
|
7355
|
+
]);
|
|
7356
|
+
/** Why the operation ran. */
|
|
7357
|
+
var OpsLogReasonSchema = _enum([
|
|
7358
|
+
"retention",
|
|
7359
|
+
"quota",
|
|
7360
|
+
"manual",
|
|
7361
|
+
"operator"
|
|
7362
|
+
]);
|
|
7363
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7364
|
+
var OpsLogEntrySchema = object({
|
|
7365
|
+
/** Unique row id. */
|
|
7366
|
+
id: string(),
|
|
7367
|
+
/** Epoch ms the operation completed. */
|
|
7368
|
+
at: number(),
|
|
7369
|
+
domain: OpsLogDomainSchema,
|
|
7370
|
+
op: OpsLogOpSchema,
|
|
7371
|
+
reason: OpsLogReasonSchema,
|
|
7372
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7373
|
+
deviceId: number().nullable(),
|
|
7374
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7375
|
+
nodeId: string(),
|
|
7376
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7377
|
+
itemsAffected: number(),
|
|
7378
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7379
|
+
bytesReclaimed: number(),
|
|
7380
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7381
|
+
detail: string().nullable(),
|
|
7382
|
+
/** Who/what triggered the op. */
|
|
7383
|
+
actor: string()
|
|
7384
|
+
});
|
|
7385
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7386
|
+
var OpsLogQueryInputSchema = object({
|
|
7387
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7388
|
+
deviceId: number().optional(),
|
|
7389
|
+
/** Max rows returned, newest-first. */
|
|
7390
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7391
|
+
});
|
|
7392
|
+
/**
|
|
7294
7393
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7295
7394
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7296
7395
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -12570,7 +12669,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12570
12669
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12571
12670
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12572
12671
|
*/
|
|
12573
|
-
var ZoneRuleStageEnum = _enum([
|
|
12672
|
+
var ZoneRuleStageEnum = _enum([
|
|
12673
|
+
"motion",
|
|
12674
|
+
"detection",
|
|
12675
|
+
"package"
|
|
12676
|
+
]);
|
|
12574
12677
|
DeviceType.Camera, method(object({
|
|
12575
12678
|
deviceId: number(),
|
|
12576
12679
|
stage: ZoneRuleStageEnum
|
|
@@ -12583,7 +12686,8 @@ DeviceType.Camera, method(object({
|
|
|
12583
12686
|
auth: "admin"
|
|
12584
12687
|
}), object({
|
|
12585
12688
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12586
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12689
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12690
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12587
12691
|
});
|
|
12588
12692
|
var ProviderStatusSchema = object({
|
|
12589
12693
|
connected: boolean(),
|
|
@@ -15811,6 +15915,7 @@ var EventKindIconSchema = _enum([
|
|
|
15811
15915
|
"smoke",
|
|
15812
15916
|
"water",
|
|
15813
15917
|
"button",
|
|
15918
|
+
"package",
|
|
15814
15919
|
"generic"
|
|
15815
15920
|
]);
|
|
15816
15921
|
var EventKindCategorySchema = _enum([
|
|
@@ -15818,7 +15923,8 @@ var EventKindCategorySchema = _enum([
|
|
|
15818
15923
|
"audio",
|
|
15819
15924
|
"detection",
|
|
15820
15925
|
"sensor",
|
|
15821
|
-
"custom"
|
|
15926
|
+
"custom",
|
|
15927
|
+
"package"
|
|
15822
15928
|
]);
|
|
15823
15929
|
var EventKindDescriptorSchema = object({
|
|
15824
15930
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -16159,6 +16265,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
16159
16265
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
16160
16266
|
embeddings: number().int()
|
|
16161
16267
|
});
|
|
16268
|
+
/** Event-store footprint for one camera. */
|
|
16269
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
16270
|
+
deviceId: number(),
|
|
16271
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
16272
|
+
rows: number().int(),
|
|
16273
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
16274
|
+
bytes: number().int()
|
|
16275
|
+
});
|
|
16276
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
16277
|
+
var EventStoreFootprintSchema = object({
|
|
16278
|
+
totalRows: number().int(),
|
|
16279
|
+
totalBytes: number().int(),
|
|
16280
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
16281
|
+
});
|
|
16282
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
16283
|
+
var EventPruneCountsSchema = object({
|
|
16284
|
+
motion: number().int(),
|
|
16285
|
+
object: number().int(),
|
|
16286
|
+
audio: number().int()
|
|
16287
|
+
});
|
|
16162
16288
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
16163
16289
|
deviceId: number(),
|
|
16164
16290
|
trackId: string()
|
|
@@ -16222,6 +16348,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
16222
16348
|
}), {
|
|
16223
16349
|
kind: "mutation",
|
|
16224
16350
|
auth: "admin"
|
|
16351
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
16352
|
+
kind: "query",
|
|
16353
|
+
auth: "admin"
|
|
16354
|
+
}), method(object({
|
|
16355
|
+
olderThanMs: number(),
|
|
16356
|
+
reason: OpsLogReasonSchema.optional()
|
|
16357
|
+
}), EventPruneCountsSchema, {
|
|
16358
|
+
kind: "mutation",
|
|
16359
|
+
auth: "admin"
|
|
16360
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
16361
|
+
kind: "mutation",
|
|
16362
|
+
auth: "admin"
|
|
16363
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
16364
|
+
kind: "query",
|
|
16365
|
+
auth: "admin"
|
|
16225
16366
|
}), method(object({
|
|
16226
16367
|
eventId: string(),
|
|
16227
16368
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19455,13 +19596,131 @@ method(object({
|
|
|
19455
19596
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
19456
19597
|
kind: "mutation",
|
|
19457
19598
|
auth: "admin"
|
|
19458
|
-
}), method(object({
|
|
19599
|
+
}), method(object({
|
|
19600
|
+
deviceId: number(),
|
|
19601
|
+
reason: OpsLogReasonSchema.optional()
|
|
19602
|
+
}), object({
|
|
19459
19603
|
floorMs: number().nullable(),
|
|
19460
19604
|
deletedBuckets: number().int(),
|
|
19461
19605
|
reclaimedBytes: number().int()
|
|
19462
19606
|
}), {
|
|
19463
19607
|
kind: "mutation",
|
|
19464
19608
|
auth: "admin"
|
|
19609
|
+
}), method(object({
|
|
19610
|
+
deviceId: number(),
|
|
19611
|
+
fromMs: number().optional(),
|
|
19612
|
+
toMs: number().optional()
|
|
19613
|
+
}), object({
|
|
19614
|
+
deletedBuckets: number().int(),
|
|
19615
|
+
reclaimedBytes: number().int()
|
|
19616
|
+
}), {
|
|
19617
|
+
kind: "mutation",
|
|
19618
|
+
auth: "admin"
|
|
19619
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19620
|
+
kind: "query",
|
|
19621
|
+
auth: "admin"
|
|
19622
|
+
});
|
|
19623
|
+
/**
|
|
19624
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19625
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19626
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19627
|
+
* delete-after-download.
|
|
19628
|
+
*
|
|
19629
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19630
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19631
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19632
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19633
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19634
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19635
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19636
|
+
*/
|
|
19637
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19638
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19639
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19640
|
+
var ExportTimelapseSchema = object({
|
|
19641
|
+
everyMs: number().int().positive(),
|
|
19642
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19643
|
+
});
|
|
19644
|
+
/**
|
|
19645
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19646
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19647
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19648
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19649
|
+
*/
|
|
19650
|
+
var ExportOptionsSchema = object({
|
|
19651
|
+
speed: ExportSpeedSchema.optional(),
|
|
19652
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19653
|
+
includeAudio: boolean(),
|
|
19654
|
+
maxLifeMs: number().int().positive(),
|
|
19655
|
+
deleteAfterDownload: boolean(),
|
|
19656
|
+
title: string().max(200).optional()
|
|
19657
|
+
}).superRefine((v, ctx) => {
|
|
19658
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19659
|
+
code: ZodIssueCode.custom,
|
|
19660
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19661
|
+
path: ["timelapse"]
|
|
19662
|
+
});
|
|
19663
|
+
});
|
|
19664
|
+
var ExportStateSchema = _enum([
|
|
19665
|
+
"queued",
|
|
19666
|
+
"rendering",
|
|
19667
|
+
"ready",
|
|
19668
|
+
"failed",
|
|
19669
|
+
"expired",
|
|
19670
|
+
"deleted"
|
|
19671
|
+
]);
|
|
19672
|
+
/** One export job / history row. */
|
|
19673
|
+
var ExportRecordSchema = object({
|
|
19674
|
+
id: string(),
|
|
19675
|
+
deviceId: number(),
|
|
19676
|
+
profile: string(),
|
|
19677
|
+
fromMs: number(),
|
|
19678
|
+
toMs: number(),
|
|
19679
|
+
options: ExportOptionsSchema,
|
|
19680
|
+
state: ExportStateSchema,
|
|
19681
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19682
|
+
progressPct: number().nullable(),
|
|
19683
|
+
/** File size once ready; null before. */
|
|
19684
|
+
fileBytes: number().nullable(),
|
|
19685
|
+
expiresAt: number(),
|
|
19686
|
+
deleteAfterDownload: boolean(),
|
|
19687
|
+
/** Epoch of the first complete download; null until then. */
|
|
19688
|
+
downloadedAt: number().nullable(),
|
|
19689
|
+
createdAt: number(),
|
|
19690
|
+
/** User id/name that requested the export. */
|
|
19691
|
+
createdBy: string(),
|
|
19692
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19693
|
+
error: string().nullable()
|
|
19694
|
+
});
|
|
19695
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19696
|
+
var ExportDownloadSchema = object({
|
|
19697
|
+
url: string(),
|
|
19698
|
+
endpoints: array(string())
|
|
19699
|
+
});
|
|
19700
|
+
method(object({
|
|
19701
|
+
deviceId: number(),
|
|
19702
|
+
profile: string(),
|
|
19703
|
+
fromMs: number(),
|
|
19704
|
+
toMs: number(),
|
|
19705
|
+
options: ExportOptionsSchema
|
|
19706
|
+
}), ExportRecordSchema, {
|
|
19707
|
+
kind: "mutation",
|
|
19708
|
+
auth: "protected"
|
|
19709
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19710
|
+
kind: "query",
|
|
19711
|
+
auth: "protected"
|
|
19712
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19713
|
+
kind: "query",
|
|
19714
|
+
auth: "protected"
|
|
19715
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19716
|
+
kind: "mutation",
|
|
19717
|
+
auth: "protected"
|
|
19718
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19719
|
+
kind: "mutation",
|
|
19720
|
+
auth: "protected"
|
|
19721
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19722
|
+
kind: "query",
|
|
19723
|
+
auth: "protected"
|
|
19465
19724
|
});
|
|
19466
19725
|
/**
|
|
19467
19726
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -22481,6 +22740,12 @@ Object.freeze({
|
|
|
22481
22740
|
addonId: null,
|
|
22482
22741
|
access: "delete"
|
|
22483
22742
|
},
|
|
22743
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
22744
|
+
capName: "pipeline-analytics",
|
|
22745
|
+
capScope: "device",
|
|
22746
|
+
addonId: null,
|
|
22747
|
+
access: "delete"
|
|
22748
|
+
},
|
|
22484
22749
|
"pipelineAnalytics.deleteTracks": {
|
|
22485
22750
|
capName: "pipeline-analytics",
|
|
22486
22751
|
capScope: "device",
|
|
@@ -22511,6 +22776,12 @@ Object.freeze({
|
|
|
22511
22776
|
addonId: null,
|
|
22512
22777
|
access: "view"
|
|
22513
22778
|
},
|
|
22779
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
22780
|
+
capName: "pipeline-analytics",
|
|
22781
|
+
capScope: "device",
|
|
22782
|
+
addonId: null,
|
|
22783
|
+
access: "view"
|
|
22784
|
+
},
|
|
22514
22785
|
"pipelineAnalytics.getKeyEvents": {
|
|
22515
22786
|
capName: "pipeline-analytics",
|
|
22516
22787
|
capScope: "device",
|
|
@@ -22553,6 +22824,12 @@ Object.freeze({
|
|
|
22553
22824
|
addonId: null,
|
|
22554
22825
|
access: "view"
|
|
22555
22826
|
},
|
|
22827
|
+
"pipelineAnalytics.listOpsLog": {
|
|
22828
|
+
capName: "pipeline-analytics",
|
|
22829
|
+
capScope: "device",
|
|
22830
|
+
addonId: null,
|
|
22831
|
+
access: "view"
|
|
22832
|
+
},
|
|
22556
22833
|
"pipelineAnalytics.listRecentTracks": {
|
|
22557
22834
|
capName: "pipeline-analytics",
|
|
22558
22835
|
capScope: "device",
|
|
@@ -22565,6 +22842,12 @@ Object.freeze({
|
|
|
22565
22842
|
addonId: null,
|
|
22566
22843
|
access: "view"
|
|
22567
22844
|
},
|
|
22845
|
+
"pipelineAnalytics.pruneEvents": {
|
|
22846
|
+
capName: "pipeline-analytics",
|
|
22847
|
+
capScope: "device",
|
|
22848
|
+
addonId: null,
|
|
22849
|
+
access: "create"
|
|
22850
|
+
},
|
|
22568
22851
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
22569
22852
|
capName: "pipeline-analytics",
|
|
22570
22853
|
capScope: "device",
|
|
@@ -23327,6 +23610,12 @@ Object.freeze({
|
|
|
23327
23610
|
addonId: null,
|
|
23328
23611
|
access: "create"
|
|
23329
23612
|
},
|
|
23613
|
+
"recording.deleteFootprint": {
|
|
23614
|
+
capName: "recording",
|
|
23615
|
+
capScope: "system",
|
|
23616
|
+
addonId: null,
|
|
23617
|
+
access: "delete"
|
|
23618
|
+
},
|
|
23330
23619
|
"recording.getAvailability": {
|
|
23331
23620
|
capName: "recording",
|
|
23332
23621
|
capScope: "system",
|
|
@@ -23357,6 +23646,12 @@ Object.freeze({
|
|
|
23357
23646
|
addonId: null,
|
|
23358
23647
|
access: "view"
|
|
23359
23648
|
},
|
|
23649
|
+
"recording.listOpsLog": {
|
|
23650
|
+
capName: "recording",
|
|
23651
|
+
capScope: "system",
|
|
23652
|
+
addonId: null,
|
|
23653
|
+
access: "view"
|
|
23654
|
+
},
|
|
23360
23655
|
"recording.locateSegment": {
|
|
23361
23656
|
capName: "recording",
|
|
23362
23657
|
capScope: "system",
|
|
@@ -23387,6 +23682,42 @@ Object.freeze({
|
|
|
23387
23682
|
addonId: null,
|
|
23388
23683
|
access: "create"
|
|
23389
23684
|
},
|
|
23685
|
+
"recordingExport.cancelExport": {
|
|
23686
|
+
capName: "recordingExport",
|
|
23687
|
+
capScope: "system",
|
|
23688
|
+
addonId: null,
|
|
23689
|
+
access: "create"
|
|
23690
|
+
},
|
|
23691
|
+
"recordingExport.createExport": {
|
|
23692
|
+
capName: "recordingExport",
|
|
23693
|
+
capScope: "system",
|
|
23694
|
+
addonId: null,
|
|
23695
|
+
access: "create"
|
|
23696
|
+
},
|
|
23697
|
+
"recordingExport.deleteExport": {
|
|
23698
|
+
capName: "recordingExport",
|
|
23699
|
+
capScope: "system",
|
|
23700
|
+
addonId: null,
|
|
23701
|
+
access: "delete"
|
|
23702
|
+
},
|
|
23703
|
+
"recordingExport.getDownloadUrl": {
|
|
23704
|
+
capName: "recordingExport",
|
|
23705
|
+
capScope: "system",
|
|
23706
|
+
addonId: null,
|
|
23707
|
+
access: "view"
|
|
23708
|
+
},
|
|
23709
|
+
"recordingExport.getExport": {
|
|
23710
|
+
capName: "recordingExport",
|
|
23711
|
+
capScope: "system",
|
|
23712
|
+
addonId: null,
|
|
23713
|
+
access: "view"
|
|
23714
|
+
},
|
|
23715
|
+
"recordingExport.listExports": {
|
|
23716
|
+
capName: "recordingExport",
|
|
23717
|
+
capScope: "system",
|
|
23718
|
+
addonId: null,
|
|
23719
|
+
access: "view"
|
|
23720
|
+
},
|
|
23390
23721
|
"sceneMonitor.captureReference": {
|
|
23391
23722
|
capName: "scene-monitor",
|
|
23392
23723
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "AI addon for CamStack — the `llm` collection provider (cloud, LAN, and camstack-managed local llama.cpp profiles) plus the per-node `llm-runtime` managed executor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|