@camstack/addon-provider-reolink 1.1.28 → 1.1.30
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 +515 -5
- package/dist/addon.mjs +515 -5
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7558,6 +7558,62 @@ var RecordingConfigSchema = object({
|
|
|
7558
7558
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7559
7559
|
});
|
|
7560
7560
|
/**
|
|
7561
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7562
|
+
* recordings and events management surfaces.
|
|
7563
|
+
*
|
|
7564
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7565
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7566
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7567
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7568
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7569
|
+
* never fail the operation it records.
|
|
7570
|
+
*/
|
|
7571
|
+
/** Which management domain the operation belongs to. */
|
|
7572
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7573
|
+
/** The kind of management operation performed. */
|
|
7574
|
+
var OpsLogOpSchema = _enum([
|
|
7575
|
+
"prune",
|
|
7576
|
+
"manual-delete",
|
|
7577
|
+
"rescan",
|
|
7578
|
+
"retention-run"
|
|
7579
|
+
]);
|
|
7580
|
+
/** Why the operation ran. */
|
|
7581
|
+
var OpsLogReasonSchema = _enum([
|
|
7582
|
+
"retention",
|
|
7583
|
+
"quota",
|
|
7584
|
+
"manual",
|
|
7585
|
+
"operator"
|
|
7586
|
+
]);
|
|
7587
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7588
|
+
var OpsLogEntrySchema = object({
|
|
7589
|
+
/** Unique row id. */
|
|
7590
|
+
id: string(),
|
|
7591
|
+
/** Epoch ms the operation completed. */
|
|
7592
|
+
at: number(),
|
|
7593
|
+
domain: OpsLogDomainSchema,
|
|
7594
|
+
op: OpsLogOpSchema,
|
|
7595
|
+
reason: OpsLogReasonSchema,
|
|
7596
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7597
|
+
deviceId: number().nullable(),
|
|
7598
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7599
|
+
nodeId: string(),
|
|
7600
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7601
|
+
itemsAffected: number(),
|
|
7602
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7603
|
+
bytesReclaimed: number(),
|
|
7604
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7605
|
+
detail: string().nullable(),
|
|
7606
|
+
/** Who/what triggered the op. */
|
|
7607
|
+
actor: string()
|
|
7608
|
+
});
|
|
7609
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7610
|
+
var OpsLogQueryInputSchema = object({
|
|
7611
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7612
|
+
deviceId: number().optional(),
|
|
7613
|
+
/** Max rows returned, newest-first. */
|
|
7614
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7615
|
+
});
|
|
7616
|
+
/**
|
|
7561
7617
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7562
7618
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7563
7619
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7801,6 +7857,160 @@ var EncodeProfileSchema = object({
|
|
|
7801
7857
|
*/
|
|
7802
7858
|
outputArgs: array(string()).optional()
|
|
7803
7859
|
});
|
|
7860
|
+
var COCO_TO_MACRO = {
|
|
7861
|
+
mapping: {
|
|
7862
|
+
person: "person",
|
|
7863
|
+
bicycle: "vehicle",
|
|
7864
|
+
car: "vehicle",
|
|
7865
|
+
motorcycle: "vehicle",
|
|
7866
|
+
airplane: "vehicle",
|
|
7867
|
+
bus: "vehicle",
|
|
7868
|
+
train: "vehicle",
|
|
7869
|
+
truck: "vehicle",
|
|
7870
|
+
boat: "vehicle",
|
|
7871
|
+
bird: "animal",
|
|
7872
|
+
cat: "animal",
|
|
7873
|
+
dog: "animal",
|
|
7874
|
+
horse: "animal",
|
|
7875
|
+
sheep: "animal",
|
|
7876
|
+
cow: "animal",
|
|
7877
|
+
elephant: "animal",
|
|
7878
|
+
bear: "animal",
|
|
7879
|
+
zebra: "animal",
|
|
7880
|
+
giraffe: "animal",
|
|
7881
|
+
suitcase: "package",
|
|
7882
|
+
backpack: "package",
|
|
7883
|
+
handbag: "package"
|
|
7884
|
+
},
|
|
7885
|
+
preserveOriginal: false
|
|
7886
|
+
};
|
|
7887
|
+
var AUDIO_MACRO_LABELS = [
|
|
7888
|
+
{
|
|
7889
|
+
id: "speech",
|
|
7890
|
+
name: "Speech",
|
|
7891
|
+
icon: "🗣️"
|
|
7892
|
+
},
|
|
7893
|
+
{
|
|
7894
|
+
id: "scream",
|
|
7895
|
+
name: "Scream / Shout",
|
|
7896
|
+
icon: "😱"
|
|
7897
|
+
},
|
|
7898
|
+
{
|
|
7899
|
+
id: "crying",
|
|
7900
|
+
name: "Crying / Baby",
|
|
7901
|
+
icon: "😢"
|
|
7902
|
+
},
|
|
7903
|
+
{
|
|
7904
|
+
id: "laughter",
|
|
7905
|
+
name: "Laughter",
|
|
7906
|
+
icon: "😂"
|
|
7907
|
+
},
|
|
7908
|
+
{
|
|
7909
|
+
id: "music",
|
|
7910
|
+
name: "Music",
|
|
7911
|
+
icon: "🎵"
|
|
7912
|
+
},
|
|
7913
|
+
{
|
|
7914
|
+
id: "dog",
|
|
7915
|
+
name: "Dog",
|
|
7916
|
+
icon: "🐕"
|
|
7917
|
+
},
|
|
7918
|
+
{
|
|
7919
|
+
id: "cat",
|
|
7920
|
+
name: "Cat",
|
|
7921
|
+
icon: "🐈"
|
|
7922
|
+
},
|
|
7923
|
+
{
|
|
7924
|
+
id: "bird",
|
|
7925
|
+
name: "Bird",
|
|
7926
|
+
icon: "🐦"
|
|
7927
|
+
},
|
|
7928
|
+
{
|
|
7929
|
+
id: "animal",
|
|
7930
|
+
name: "Animal (other)",
|
|
7931
|
+
icon: "🐾"
|
|
7932
|
+
},
|
|
7933
|
+
{
|
|
7934
|
+
id: "alarm",
|
|
7935
|
+
name: "Alarm / Siren",
|
|
7936
|
+
icon: "🚨"
|
|
7937
|
+
},
|
|
7938
|
+
{
|
|
7939
|
+
id: "doorbell",
|
|
7940
|
+
name: "Doorbell / Knock",
|
|
7941
|
+
icon: "🔔"
|
|
7942
|
+
},
|
|
7943
|
+
{
|
|
7944
|
+
id: "glass_breaking",
|
|
7945
|
+
name: "Glass Breaking",
|
|
7946
|
+
icon: "💥"
|
|
7947
|
+
},
|
|
7948
|
+
{
|
|
7949
|
+
id: "gunshot",
|
|
7950
|
+
name: "Gunshot / Explosion",
|
|
7951
|
+
icon: "💣"
|
|
7952
|
+
},
|
|
7953
|
+
{
|
|
7954
|
+
id: "vehicle",
|
|
7955
|
+
name: "Vehicle",
|
|
7956
|
+
icon: "🚗"
|
|
7957
|
+
},
|
|
7958
|
+
{
|
|
7959
|
+
id: "siren",
|
|
7960
|
+
name: "Emergency Siren",
|
|
7961
|
+
icon: "🚑"
|
|
7962
|
+
},
|
|
7963
|
+
{
|
|
7964
|
+
id: "fire",
|
|
7965
|
+
name: "Fire / Smoke",
|
|
7966
|
+
icon: "🔥"
|
|
7967
|
+
},
|
|
7968
|
+
{
|
|
7969
|
+
id: "water",
|
|
7970
|
+
name: "Water",
|
|
7971
|
+
icon: "💧"
|
|
7972
|
+
},
|
|
7973
|
+
{
|
|
7974
|
+
id: "wind",
|
|
7975
|
+
name: "Wind / Weather",
|
|
7976
|
+
icon: "🌬️"
|
|
7977
|
+
},
|
|
7978
|
+
{
|
|
7979
|
+
id: "door",
|
|
7980
|
+
name: "Door",
|
|
7981
|
+
icon: "🚪"
|
|
7982
|
+
},
|
|
7983
|
+
{
|
|
7984
|
+
id: "footsteps",
|
|
7985
|
+
name: "Footsteps",
|
|
7986
|
+
icon: "👣"
|
|
7987
|
+
},
|
|
7988
|
+
{
|
|
7989
|
+
id: "crowd",
|
|
7990
|
+
name: "Crowd / Chatter",
|
|
7991
|
+
icon: "👥"
|
|
7992
|
+
},
|
|
7993
|
+
{
|
|
7994
|
+
id: "telephone",
|
|
7995
|
+
name: "Telephone",
|
|
7996
|
+
icon: "📞"
|
|
7997
|
+
},
|
|
7998
|
+
{
|
|
7999
|
+
id: "engine",
|
|
8000
|
+
name: "Engine / Motor",
|
|
8001
|
+
icon: "⚙️"
|
|
8002
|
+
},
|
|
8003
|
+
{
|
|
8004
|
+
id: "tools",
|
|
8005
|
+
name: "Tools / Construction",
|
|
8006
|
+
icon: "🔨"
|
|
8007
|
+
},
|
|
8008
|
+
{
|
|
8009
|
+
id: "silence",
|
|
8010
|
+
name: "Silence",
|
|
8011
|
+
icon: "🤫"
|
|
8012
|
+
}
|
|
8013
|
+
];
|
|
7804
8014
|
var YAMNET_TO_MACRO = {
|
|
7805
8015
|
mapping: {
|
|
7806
8016
|
Speech: "speech",
|
|
@@ -8067,6 +8277,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8067
8277
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8068
8278
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8069
8279
|
/**
|
|
8280
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8281
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8282
|
+
* icon }`.
|
|
8283
|
+
*
|
|
8284
|
+
* This dictionary folds together what used to be scattered across four
|
|
8285
|
+
* copies:
|
|
8286
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8287
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8288
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8289
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8290
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8291
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8292
|
+
*
|
|
8293
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8294
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8295
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8296
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8297
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8298
|
+
*
|
|
8299
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8300
|
+
*/
|
|
8301
|
+
var TAXONOMY_COLORS = {
|
|
8302
|
+
motion: "#f59e0b",
|
|
8303
|
+
audio: "#06b6d4",
|
|
8304
|
+
person: "#22c55e",
|
|
8305
|
+
vehicle: "#3b82f6",
|
|
8306
|
+
animal: "#f97316",
|
|
8307
|
+
package: "#a855f7",
|
|
8308
|
+
sensor: "#8b5cf6",
|
|
8309
|
+
control: "#10b981",
|
|
8310
|
+
genericDetection: "#64748b"
|
|
8311
|
+
};
|
|
8312
|
+
var DETECTION_SUB_COLORS = {
|
|
8313
|
+
car: "#f59e0b",
|
|
8314
|
+
truck: "#d97706",
|
|
8315
|
+
bus: "#b45309",
|
|
8316
|
+
motorcycle: "#eab308",
|
|
8317
|
+
bicycle: "#ca8a04",
|
|
8318
|
+
airplane: "#60a5fa",
|
|
8319
|
+
boat: "#2563eb",
|
|
8320
|
+
train: "#1d4ed8",
|
|
8321
|
+
bird: "#14b8a6",
|
|
8322
|
+
dog: "#84cc16",
|
|
8323
|
+
cat: "#f97316",
|
|
8324
|
+
horse: "#a16207",
|
|
8325
|
+
sheep: "#a3a3a3",
|
|
8326
|
+
cow: "#78716c",
|
|
8327
|
+
elephant: "#6b7280",
|
|
8328
|
+
bear: "#7c2d12",
|
|
8329
|
+
zebra: "#404040",
|
|
8330
|
+
giraffe: "#d4a373"
|
|
8331
|
+
};
|
|
8332
|
+
function titleCase(id) {
|
|
8333
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8334
|
+
}
|
|
8335
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8336
|
+
function macro(kind, category, color, iconId, label) {
|
|
8337
|
+
entries.set(kind, {
|
|
8338
|
+
kind,
|
|
8339
|
+
parentKind: null,
|
|
8340
|
+
level: "macro",
|
|
8341
|
+
category,
|
|
8342
|
+
color,
|
|
8343
|
+
iconId,
|
|
8344
|
+
labelKey: `eventKind.${kind}`,
|
|
8345
|
+
label
|
|
8346
|
+
});
|
|
8347
|
+
}
|
|
8348
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8349
|
+
entries.set(kind, {
|
|
8350
|
+
kind,
|
|
8351
|
+
parentKind,
|
|
8352
|
+
level: "sub",
|
|
8353
|
+
category,
|
|
8354
|
+
color,
|
|
8355
|
+
iconId,
|
|
8356
|
+
labelKey: `eventKind.${kind}`,
|
|
8357
|
+
label
|
|
8358
|
+
});
|
|
8359
|
+
}
|
|
8360
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8361
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8362
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8363
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8364
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8365
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8366
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8367
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8368
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8369
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8370
|
+
if (entries.has(cocoClass)) continue;
|
|
8371
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8372
|
+
}
|
|
8373
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8374
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8375
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8376
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8377
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8378
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8379
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8380
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8381
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8382
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8383
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8384
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8385
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8386
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8387
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8388
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8389
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8390
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8391
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8392
|
+
const kind = `audio-${l.id}`;
|
|
8393
|
+
if (entries.has(kind)) continue;
|
|
8394
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8395
|
+
}
|
|
8396
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8397
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8398
|
+
/**
|
|
8070
8399
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8071
8400
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8072
8401
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15060,9 +15389,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15060
15389
|
* `package` backs the package-drop detector — a package zone is a
|
|
15061
15390
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15062
15391
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15063
|
-
* The orchestrator provider
|
|
15064
|
-
*
|
|
15065
|
-
* consumers read
|
|
15392
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15393
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15394
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15395
|
+
* off `device.state.zoneRules.value.package`.
|
|
15066
15396
|
*/
|
|
15067
15397
|
runtimeState: object({
|
|
15068
15398
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19049,17 +19379,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19049
19379
|
"audio",
|
|
19050
19380
|
"detection",
|
|
19051
19381
|
"sensor",
|
|
19382
|
+
"control",
|
|
19052
19383
|
"custom",
|
|
19053
19384
|
"package"
|
|
19054
19385
|
]);
|
|
19386
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19387
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19055
19388
|
var EventKindDescriptorSchema = object({
|
|
19056
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19389
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19057
19390
|
kind: string(),
|
|
19391
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19392
|
+
labelKey: string(),
|
|
19393
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19058
19394
|
label: string(),
|
|
19059
19395
|
/** Hex color for timeline/legend rendering. */
|
|
19060
19396
|
color: string(),
|
|
19397
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19398
|
+
iconId: string(),
|
|
19399
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19061
19400
|
icon: EventKindIconSchema,
|
|
19062
19401
|
category: EventKindCategorySchema,
|
|
19402
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19403
|
+
parentKind: string().nullable(),
|
|
19404
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19405
|
+
level: EventKindLevelSchema,
|
|
19063
19406
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19064
19407
|
* itself; for sensor kinds the LINKED source device. */
|
|
19065
19408
|
source: object({
|
|
@@ -19132,11 +19475,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19132
19475
|
firstAt: number(),
|
|
19133
19476
|
lastAt: number()
|
|
19134
19477
|
});
|
|
19478
|
+
/**
|
|
19479
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19480
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19481
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19482
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19483
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19484
|
+
*/
|
|
19485
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19135
19486
|
var TrackSchema = object({
|
|
19136
19487
|
trackId: string(),
|
|
19137
19488
|
deviceId: number(),
|
|
19138
19489
|
className: string(),
|
|
19139
19490
|
label: string().optional(),
|
|
19491
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19492
|
+
source: TrackSourceSchema.optional(),
|
|
19140
19493
|
firstSeen: number(),
|
|
19141
19494
|
lastSeen: number(),
|
|
19142
19495
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19391,6 +19744,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19391
19744
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19392
19745
|
embeddings: number().int()
|
|
19393
19746
|
});
|
|
19747
|
+
/** Event-store footprint for one camera. */
|
|
19748
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19749
|
+
deviceId: number(),
|
|
19750
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19751
|
+
rows: number().int(),
|
|
19752
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19753
|
+
bytes: number().int()
|
|
19754
|
+
});
|
|
19755
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19756
|
+
var EventStoreFootprintSchema = object({
|
|
19757
|
+
totalRows: number().int(),
|
|
19758
|
+
totalBytes: number().int(),
|
|
19759
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19760
|
+
});
|
|
19761
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19762
|
+
var EventPruneCountsSchema = object({
|
|
19763
|
+
motion: number().int(),
|
|
19764
|
+
object: number().int(),
|
|
19765
|
+
audio: number().int()
|
|
19766
|
+
});
|
|
19394
19767
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19395
19768
|
deviceId: number(),
|
|
19396
19769
|
trackId: string()
|
|
@@ -19454,6 +19827,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19454
19827
|
}), {
|
|
19455
19828
|
kind: "mutation",
|
|
19456
19829
|
auth: "admin"
|
|
19830
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19831
|
+
kind: "query",
|
|
19832
|
+
auth: "admin"
|
|
19833
|
+
}), method(object({
|
|
19834
|
+
olderThanMs: number(),
|
|
19835
|
+
reason: OpsLogReasonSchema.optional()
|
|
19836
|
+
}), EventPruneCountsSchema, {
|
|
19837
|
+
kind: "mutation",
|
|
19838
|
+
auth: "admin"
|
|
19839
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19840
|
+
kind: "mutation",
|
|
19841
|
+
auth: "admin"
|
|
19842
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19843
|
+
kind: "query",
|
|
19844
|
+
auth: "admin"
|
|
19457
19845
|
}), method(object({
|
|
19458
19846
|
eventId: string(),
|
|
19459
19847
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19478,6 +19866,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19478
19866
|
eventId: string(),
|
|
19479
19867
|
timestamp: number()
|
|
19480
19868
|
});
|
|
19869
|
+
/**
|
|
19870
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19871
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19872
|
+
* caps into per-camera event-kind descriptors.
|
|
19873
|
+
*
|
|
19874
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19875
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19876
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19877
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19878
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19879
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19880
|
+
* eventful cap is missing.
|
|
19881
|
+
*/
|
|
19882
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19883
|
+
var LEGACY_ICON = {
|
|
19884
|
+
motion: "motion",
|
|
19885
|
+
audio: "audio",
|
|
19886
|
+
person: "person",
|
|
19887
|
+
vehicle: "vehicle",
|
|
19888
|
+
animal: "animal",
|
|
19889
|
+
package: "package",
|
|
19890
|
+
door: "door",
|
|
19891
|
+
pir: "pir",
|
|
19892
|
+
smoke: "smoke",
|
|
19893
|
+
water: "water",
|
|
19894
|
+
button: "button",
|
|
19895
|
+
generic: "generic",
|
|
19896
|
+
gas: "smoke",
|
|
19897
|
+
vibration: "generic",
|
|
19898
|
+
tamper: "generic",
|
|
19899
|
+
presence: "person",
|
|
19900
|
+
lock: "generic",
|
|
19901
|
+
siren: "generic",
|
|
19902
|
+
switch: "generic",
|
|
19903
|
+
doorbell: "button"
|
|
19904
|
+
};
|
|
19905
|
+
function legacyIcon(iconId) {
|
|
19906
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19907
|
+
}
|
|
19908
|
+
/**
|
|
19909
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19910
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19911
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19912
|
+
*/
|
|
19913
|
+
var CAP_TO_KIND = {
|
|
19914
|
+
contact: "contact",
|
|
19915
|
+
motion: "motion-sensor",
|
|
19916
|
+
smoke: "smoke",
|
|
19917
|
+
flood: "flood",
|
|
19918
|
+
gas: "gas",
|
|
19919
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19920
|
+
vibration: "vibration",
|
|
19921
|
+
tamper: "tamper",
|
|
19922
|
+
presence: "presence",
|
|
19923
|
+
"enum-sensor": "enum-sensor",
|
|
19924
|
+
"event-emitter": "device-event",
|
|
19925
|
+
"lock-control": "lock",
|
|
19926
|
+
switch: "switch",
|
|
19927
|
+
button: "button",
|
|
19928
|
+
doorbell: "doorbell"
|
|
19929
|
+
};
|
|
19930
|
+
function buildDescriptor(capName, kind) {
|
|
19931
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19932
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19933
|
+
return {
|
|
19934
|
+
...t,
|
|
19935
|
+
icon: legacyIcon(t.iconId)
|
|
19936
|
+
};
|
|
19937
|
+
}
|
|
19938
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19481
19939
|
var CameraPipelineConfigSchema = object({
|
|
19482
19940
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19483
19941
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22856,13 +23314,29 @@ method(object({
|
|
|
22856
23314
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22857
23315
|
kind: "mutation",
|
|
22858
23316
|
auth: "admin"
|
|
22859
|
-
}), method(object({
|
|
23317
|
+
}), method(object({
|
|
23318
|
+
deviceId: number(),
|
|
23319
|
+
reason: OpsLogReasonSchema.optional()
|
|
23320
|
+
}), object({
|
|
22860
23321
|
floorMs: number().nullable(),
|
|
22861
23322
|
deletedBuckets: number().int(),
|
|
22862
23323
|
reclaimedBytes: number().int()
|
|
22863
23324
|
}), {
|
|
22864
23325
|
kind: "mutation",
|
|
22865
23326
|
auth: "admin"
|
|
23327
|
+
}), method(object({
|
|
23328
|
+
deviceId: number(),
|
|
23329
|
+
fromMs: number().optional(),
|
|
23330
|
+
toMs: number().optional()
|
|
23331
|
+
}), object({
|
|
23332
|
+
deletedBuckets: number().int(),
|
|
23333
|
+
reclaimedBytes: number().int()
|
|
23334
|
+
}), {
|
|
23335
|
+
kind: "mutation",
|
|
23336
|
+
auth: "admin"
|
|
23337
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23338
|
+
kind: "query",
|
|
23339
|
+
auth: "admin"
|
|
22866
23340
|
});
|
|
22867
23341
|
/**
|
|
22868
23342
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26195,6 +26669,12 @@ Object.freeze({
|
|
|
26195
26669
|
addonId: null,
|
|
26196
26670
|
access: "delete"
|
|
26197
26671
|
},
|
|
26672
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26673
|
+
capName: "pipeline-analytics",
|
|
26674
|
+
capScope: "device",
|
|
26675
|
+
addonId: null,
|
|
26676
|
+
access: "delete"
|
|
26677
|
+
},
|
|
26198
26678
|
"pipelineAnalytics.deleteTracks": {
|
|
26199
26679
|
capName: "pipeline-analytics",
|
|
26200
26680
|
capScope: "device",
|
|
@@ -26225,6 +26705,12 @@ Object.freeze({
|
|
|
26225
26705
|
addonId: null,
|
|
26226
26706
|
access: "view"
|
|
26227
26707
|
},
|
|
26708
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26709
|
+
capName: "pipeline-analytics",
|
|
26710
|
+
capScope: "device",
|
|
26711
|
+
addonId: null,
|
|
26712
|
+
access: "view"
|
|
26713
|
+
},
|
|
26228
26714
|
"pipelineAnalytics.getKeyEvents": {
|
|
26229
26715
|
capName: "pipeline-analytics",
|
|
26230
26716
|
capScope: "device",
|
|
@@ -26267,6 +26753,12 @@ Object.freeze({
|
|
|
26267
26753
|
addonId: null,
|
|
26268
26754
|
access: "view"
|
|
26269
26755
|
},
|
|
26756
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26757
|
+
capName: "pipeline-analytics",
|
|
26758
|
+
capScope: "device",
|
|
26759
|
+
addonId: null,
|
|
26760
|
+
access: "view"
|
|
26761
|
+
},
|
|
26270
26762
|
"pipelineAnalytics.listRecentTracks": {
|
|
26271
26763
|
capName: "pipeline-analytics",
|
|
26272
26764
|
capScope: "device",
|
|
@@ -26279,6 +26771,12 @@ Object.freeze({
|
|
|
26279
26771
|
addonId: null,
|
|
26280
26772
|
access: "view"
|
|
26281
26773
|
},
|
|
26774
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26775
|
+
capName: "pipeline-analytics",
|
|
26776
|
+
capScope: "device",
|
|
26777
|
+
addonId: null,
|
|
26778
|
+
access: "create"
|
|
26779
|
+
},
|
|
26282
26780
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26283
26781
|
capName: "pipeline-analytics",
|
|
26284
26782
|
capScope: "device",
|
|
@@ -27041,6 +27539,12 @@ Object.freeze({
|
|
|
27041
27539
|
addonId: null,
|
|
27042
27540
|
access: "create"
|
|
27043
27541
|
},
|
|
27542
|
+
"recording.deleteFootprint": {
|
|
27543
|
+
capName: "recording",
|
|
27544
|
+
capScope: "system",
|
|
27545
|
+
addonId: null,
|
|
27546
|
+
access: "delete"
|
|
27547
|
+
},
|
|
27044
27548
|
"recording.getAvailability": {
|
|
27045
27549
|
capName: "recording",
|
|
27046
27550
|
capScope: "system",
|
|
@@ -27071,6 +27575,12 @@ Object.freeze({
|
|
|
27071
27575
|
addonId: null,
|
|
27072
27576
|
access: "view"
|
|
27073
27577
|
},
|
|
27578
|
+
"recording.listOpsLog": {
|
|
27579
|
+
capName: "recording",
|
|
27580
|
+
capScope: "system",
|
|
27581
|
+
addonId: null,
|
|
27582
|
+
access: "view"
|
|
27583
|
+
},
|
|
27074
27584
|
"recording.locateSegment": {
|
|
27075
27585
|
capName: "recording",
|
|
27076
27586
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -7553,6 +7553,62 @@ var RecordingConfigSchema = object({
|
|
|
7553
7553
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7554
7554
|
});
|
|
7555
7555
|
/**
|
|
7556
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7557
|
+
* recordings and events management surfaces.
|
|
7558
|
+
*
|
|
7559
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7560
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7561
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7562
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7563
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7564
|
+
* never fail the operation it records.
|
|
7565
|
+
*/
|
|
7566
|
+
/** Which management domain the operation belongs to. */
|
|
7567
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7568
|
+
/** The kind of management operation performed. */
|
|
7569
|
+
var OpsLogOpSchema = _enum([
|
|
7570
|
+
"prune",
|
|
7571
|
+
"manual-delete",
|
|
7572
|
+
"rescan",
|
|
7573
|
+
"retention-run"
|
|
7574
|
+
]);
|
|
7575
|
+
/** Why the operation ran. */
|
|
7576
|
+
var OpsLogReasonSchema = _enum([
|
|
7577
|
+
"retention",
|
|
7578
|
+
"quota",
|
|
7579
|
+
"manual",
|
|
7580
|
+
"operator"
|
|
7581
|
+
]);
|
|
7582
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7583
|
+
var OpsLogEntrySchema = object({
|
|
7584
|
+
/** Unique row id. */
|
|
7585
|
+
id: string(),
|
|
7586
|
+
/** Epoch ms the operation completed. */
|
|
7587
|
+
at: number(),
|
|
7588
|
+
domain: OpsLogDomainSchema,
|
|
7589
|
+
op: OpsLogOpSchema,
|
|
7590
|
+
reason: OpsLogReasonSchema,
|
|
7591
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7592
|
+
deviceId: number().nullable(),
|
|
7593
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7594
|
+
nodeId: string(),
|
|
7595
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7596
|
+
itemsAffected: number(),
|
|
7597
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7598
|
+
bytesReclaimed: number(),
|
|
7599
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7600
|
+
detail: string().nullable(),
|
|
7601
|
+
/** Who/what triggered the op. */
|
|
7602
|
+
actor: string()
|
|
7603
|
+
});
|
|
7604
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7605
|
+
var OpsLogQueryInputSchema = object({
|
|
7606
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7607
|
+
deviceId: number().optional(),
|
|
7608
|
+
/** Max rows returned, newest-first. */
|
|
7609
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7610
|
+
});
|
|
7611
|
+
/**
|
|
7556
7612
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7557
7613
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7558
7614
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7796,6 +7852,160 @@ var EncodeProfileSchema = object({
|
|
|
7796
7852
|
*/
|
|
7797
7853
|
outputArgs: array(string()).optional()
|
|
7798
7854
|
});
|
|
7855
|
+
var COCO_TO_MACRO = {
|
|
7856
|
+
mapping: {
|
|
7857
|
+
person: "person",
|
|
7858
|
+
bicycle: "vehicle",
|
|
7859
|
+
car: "vehicle",
|
|
7860
|
+
motorcycle: "vehicle",
|
|
7861
|
+
airplane: "vehicle",
|
|
7862
|
+
bus: "vehicle",
|
|
7863
|
+
train: "vehicle",
|
|
7864
|
+
truck: "vehicle",
|
|
7865
|
+
boat: "vehicle",
|
|
7866
|
+
bird: "animal",
|
|
7867
|
+
cat: "animal",
|
|
7868
|
+
dog: "animal",
|
|
7869
|
+
horse: "animal",
|
|
7870
|
+
sheep: "animal",
|
|
7871
|
+
cow: "animal",
|
|
7872
|
+
elephant: "animal",
|
|
7873
|
+
bear: "animal",
|
|
7874
|
+
zebra: "animal",
|
|
7875
|
+
giraffe: "animal",
|
|
7876
|
+
suitcase: "package",
|
|
7877
|
+
backpack: "package",
|
|
7878
|
+
handbag: "package"
|
|
7879
|
+
},
|
|
7880
|
+
preserveOriginal: false
|
|
7881
|
+
};
|
|
7882
|
+
var AUDIO_MACRO_LABELS = [
|
|
7883
|
+
{
|
|
7884
|
+
id: "speech",
|
|
7885
|
+
name: "Speech",
|
|
7886
|
+
icon: "🗣️"
|
|
7887
|
+
},
|
|
7888
|
+
{
|
|
7889
|
+
id: "scream",
|
|
7890
|
+
name: "Scream / Shout",
|
|
7891
|
+
icon: "😱"
|
|
7892
|
+
},
|
|
7893
|
+
{
|
|
7894
|
+
id: "crying",
|
|
7895
|
+
name: "Crying / Baby",
|
|
7896
|
+
icon: "😢"
|
|
7897
|
+
},
|
|
7898
|
+
{
|
|
7899
|
+
id: "laughter",
|
|
7900
|
+
name: "Laughter",
|
|
7901
|
+
icon: "😂"
|
|
7902
|
+
},
|
|
7903
|
+
{
|
|
7904
|
+
id: "music",
|
|
7905
|
+
name: "Music",
|
|
7906
|
+
icon: "🎵"
|
|
7907
|
+
},
|
|
7908
|
+
{
|
|
7909
|
+
id: "dog",
|
|
7910
|
+
name: "Dog",
|
|
7911
|
+
icon: "🐕"
|
|
7912
|
+
},
|
|
7913
|
+
{
|
|
7914
|
+
id: "cat",
|
|
7915
|
+
name: "Cat",
|
|
7916
|
+
icon: "🐈"
|
|
7917
|
+
},
|
|
7918
|
+
{
|
|
7919
|
+
id: "bird",
|
|
7920
|
+
name: "Bird",
|
|
7921
|
+
icon: "🐦"
|
|
7922
|
+
},
|
|
7923
|
+
{
|
|
7924
|
+
id: "animal",
|
|
7925
|
+
name: "Animal (other)",
|
|
7926
|
+
icon: "🐾"
|
|
7927
|
+
},
|
|
7928
|
+
{
|
|
7929
|
+
id: "alarm",
|
|
7930
|
+
name: "Alarm / Siren",
|
|
7931
|
+
icon: "🚨"
|
|
7932
|
+
},
|
|
7933
|
+
{
|
|
7934
|
+
id: "doorbell",
|
|
7935
|
+
name: "Doorbell / Knock",
|
|
7936
|
+
icon: "🔔"
|
|
7937
|
+
},
|
|
7938
|
+
{
|
|
7939
|
+
id: "glass_breaking",
|
|
7940
|
+
name: "Glass Breaking",
|
|
7941
|
+
icon: "💥"
|
|
7942
|
+
},
|
|
7943
|
+
{
|
|
7944
|
+
id: "gunshot",
|
|
7945
|
+
name: "Gunshot / Explosion",
|
|
7946
|
+
icon: "💣"
|
|
7947
|
+
},
|
|
7948
|
+
{
|
|
7949
|
+
id: "vehicle",
|
|
7950
|
+
name: "Vehicle",
|
|
7951
|
+
icon: "🚗"
|
|
7952
|
+
},
|
|
7953
|
+
{
|
|
7954
|
+
id: "siren",
|
|
7955
|
+
name: "Emergency Siren",
|
|
7956
|
+
icon: "🚑"
|
|
7957
|
+
},
|
|
7958
|
+
{
|
|
7959
|
+
id: "fire",
|
|
7960
|
+
name: "Fire / Smoke",
|
|
7961
|
+
icon: "🔥"
|
|
7962
|
+
},
|
|
7963
|
+
{
|
|
7964
|
+
id: "water",
|
|
7965
|
+
name: "Water",
|
|
7966
|
+
icon: "💧"
|
|
7967
|
+
},
|
|
7968
|
+
{
|
|
7969
|
+
id: "wind",
|
|
7970
|
+
name: "Wind / Weather",
|
|
7971
|
+
icon: "🌬️"
|
|
7972
|
+
},
|
|
7973
|
+
{
|
|
7974
|
+
id: "door",
|
|
7975
|
+
name: "Door",
|
|
7976
|
+
icon: "🚪"
|
|
7977
|
+
},
|
|
7978
|
+
{
|
|
7979
|
+
id: "footsteps",
|
|
7980
|
+
name: "Footsteps",
|
|
7981
|
+
icon: "👣"
|
|
7982
|
+
},
|
|
7983
|
+
{
|
|
7984
|
+
id: "crowd",
|
|
7985
|
+
name: "Crowd / Chatter",
|
|
7986
|
+
icon: "👥"
|
|
7987
|
+
},
|
|
7988
|
+
{
|
|
7989
|
+
id: "telephone",
|
|
7990
|
+
name: "Telephone",
|
|
7991
|
+
icon: "📞"
|
|
7992
|
+
},
|
|
7993
|
+
{
|
|
7994
|
+
id: "engine",
|
|
7995
|
+
name: "Engine / Motor",
|
|
7996
|
+
icon: "⚙️"
|
|
7997
|
+
},
|
|
7998
|
+
{
|
|
7999
|
+
id: "tools",
|
|
8000
|
+
name: "Tools / Construction",
|
|
8001
|
+
icon: "🔨"
|
|
8002
|
+
},
|
|
8003
|
+
{
|
|
8004
|
+
id: "silence",
|
|
8005
|
+
name: "Silence",
|
|
8006
|
+
icon: "🤫"
|
|
8007
|
+
}
|
|
8008
|
+
];
|
|
7799
8009
|
var YAMNET_TO_MACRO = {
|
|
7800
8010
|
mapping: {
|
|
7801
8011
|
Speech: "speech",
|
|
@@ -8062,6 +8272,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8062
8272
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8063
8273
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8064
8274
|
/**
|
|
8275
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8276
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8277
|
+
* icon }`.
|
|
8278
|
+
*
|
|
8279
|
+
* This dictionary folds together what used to be scattered across four
|
|
8280
|
+
* copies:
|
|
8281
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8282
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8283
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8284
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8285
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8286
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8287
|
+
*
|
|
8288
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8289
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8290
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8291
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8292
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8293
|
+
*
|
|
8294
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8295
|
+
*/
|
|
8296
|
+
var TAXONOMY_COLORS = {
|
|
8297
|
+
motion: "#f59e0b",
|
|
8298
|
+
audio: "#06b6d4",
|
|
8299
|
+
person: "#22c55e",
|
|
8300
|
+
vehicle: "#3b82f6",
|
|
8301
|
+
animal: "#f97316",
|
|
8302
|
+
package: "#a855f7",
|
|
8303
|
+
sensor: "#8b5cf6",
|
|
8304
|
+
control: "#10b981",
|
|
8305
|
+
genericDetection: "#64748b"
|
|
8306
|
+
};
|
|
8307
|
+
var DETECTION_SUB_COLORS = {
|
|
8308
|
+
car: "#f59e0b",
|
|
8309
|
+
truck: "#d97706",
|
|
8310
|
+
bus: "#b45309",
|
|
8311
|
+
motorcycle: "#eab308",
|
|
8312
|
+
bicycle: "#ca8a04",
|
|
8313
|
+
airplane: "#60a5fa",
|
|
8314
|
+
boat: "#2563eb",
|
|
8315
|
+
train: "#1d4ed8",
|
|
8316
|
+
bird: "#14b8a6",
|
|
8317
|
+
dog: "#84cc16",
|
|
8318
|
+
cat: "#f97316",
|
|
8319
|
+
horse: "#a16207",
|
|
8320
|
+
sheep: "#a3a3a3",
|
|
8321
|
+
cow: "#78716c",
|
|
8322
|
+
elephant: "#6b7280",
|
|
8323
|
+
bear: "#7c2d12",
|
|
8324
|
+
zebra: "#404040",
|
|
8325
|
+
giraffe: "#d4a373"
|
|
8326
|
+
};
|
|
8327
|
+
function titleCase(id) {
|
|
8328
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8329
|
+
}
|
|
8330
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8331
|
+
function macro(kind, category, color, iconId, label) {
|
|
8332
|
+
entries.set(kind, {
|
|
8333
|
+
kind,
|
|
8334
|
+
parentKind: null,
|
|
8335
|
+
level: "macro",
|
|
8336
|
+
category,
|
|
8337
|
+
color,
|
|
8338
|
+
iconId,
|
|
8339
|
+
labelKey: `eventKind.${kind}`,
|
|
8340
|
+
label
|
|
8341
|
+
});
|
|
8342
|
+
}
|
|
8343
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8344
|
+
entries.set(kind, {
|
|
8345
|
+
kind,
|
|
8346
|
+
parentKind,
|
|
8347
|
+
level: "sub",
|
|
8348
|
+
category,
|
|
8349
|
+
color,
|
|
8350
|
+
iconId,
|
|
8351
|
+
labelKey: `eventKind.${kind}`,
|
|
8352
|
+
label
|
|
8353
|
+
});
|
|
8354
|
+
}
|
|
8355
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8356
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8357
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8358
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8359
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8360
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8361
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8362
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8363
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8364
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8365
|
+
if (entries.has(cocoClass)) continue;
|
|
8366
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8367
|
+
}
|
|
8368
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8369
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8370
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8371
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8372
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8373
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8374
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8375
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8376
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8377
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8378
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8379
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8380
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8381
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8382
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8383
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8384
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8385
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8386
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8387
|
+
const kind = `audio-${l.id}`;
|
|
8388
|
+
if (entries.has(kind)) continue;
|
|
8389
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8390
|
+
}
|
|
8391
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8392
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8393
|
+
/**
|
|
8065
8394
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8066
8395
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8067
8396
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15055,9 +15384,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15055
15384
|
* `package` backs the package-drop detector — a package zone is a
|
|
15056
15385
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15057
15386
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15058
|
-
* The orchestrator provider
|
|
15059
|
-
*
|
|
15060
|
-
* consumers read
|
|
15387
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15388
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15389
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15390
|
+
* off `device.state.zoneRules.value.package`.
|
|
15061
15391
|
*/
|
|
15062
15392
|
runtimeState: object({
|
|
15063
15393
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19044,17 +19374,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19044
19374
|
"audio",
|
|
19045
19375
|
"detection",
|
|
19046
19376
|
"sensor",
|
|
19377
|
+
"control",
|
|
19047
19378
|
"custom",
|
|
19048
19379
|
"package"
|
|
19049
19380
|
]);
|
|
19381
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19382
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19050
19383
|
var EventKindDescriptorSchema = object({
|
|
19051
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19384
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19052
19385
|
kind: string(),
|
|
19386
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19387
|
+
labelKey: string(),
|
|
19388
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19053
19389
|
label: string(),
|
|
19054
19390
|
/** Hex color for timeline/legend rendering. */
|
|
19055
19391
|
color: string(),
|
|
19392
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19393
|
+
iconId: string(),
|
|
19394
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19056
19395
|
icon: EventKindIconSchema,
|
|
19057
19396
|
category: EventKindCategorySchema,
|
|
19397
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19398
|
+
parentKind: string().nullable(),
|
|
19399
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19400
|
+
level: EventKindLevelSchema,
|
|
19058
19401
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19059
19402
|
* itself; for sensor kinds the LINKED source device. */
|
|
19060
19403
|
source: object({
|
|
@@ -19127,11 +19470,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19127
19470
|
firstAt: number(),
|
|
19128
19471
|
lastAt: number()
|
|
19129
19472
|
});
|
|
19473
|
+
/**
|
|
19474
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19475
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19476
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19477
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19478
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19479
|
+
*/
|
|
19480
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19130
19481
|
var TrackSchema = object({
|
|
19131
19482
|
trackId: string(),
|
|
19132
19483
|
deviceId: number(),
|
|
19133
19484
|
className: string(),
|
|
19134
19485
|
label: string().optional(),
|
|
19486
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19487
|
+
source: TrackSourceSchema.optional(),
|
|
19135
19488
|
firstSeen: number(),
|
|
19136
19489
|
lastSeen: number(),
|
|
19137
19490
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19386,6 +19739,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19386
19739
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19387
19740
|
embeddings: number().int()
|
|
19388
19741
|
});
|
|
19742
|
+
/** Event-store footprint for one camera. */
|
|
19743
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19744
|
+
deviceId: number(),
|
|
19745
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19746
|
+
rows: number().int(),
|
|
19747
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19748
|
+
bytes: number().int()
|
|
19749
|
+
});
|
|
19750
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19751
|
+
var EventStoreFootprintSchema = object({
|
|
19752
|
+
totalRows: number().int(),
|
|
19753
|
+
totalBytes: number().int(),
|
|
19754
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19755
|
+
});
|
|
19756
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19757
|
+
var EventPruneCountsSchema = object({
|
|
19758
|
+
motion: number().int(),
|
|
19759
|
+
object: number().int(),
|
|
19760
|
+
audio: number().int()
|
|
19761
|
+
});
|
|
19389
19762
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19390
19763
|
deviceId: number(),
|
|
19391
19764
|
trackId: string()
|
|
@@ -19449,6 +19822,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19449
19822
|
}), {
|
|
19450
19823
|
kind: "mutation",
|
|
19451
19824
|
auth: "admin"
|
|
19825
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19826
|
+
kind: "query",
|
|
19827
|
+
auth: "admin"
|
|
19828
|
+
}), method(object({
|
|
19829
|
+
olderThanMs: number(),
|
|
19830
|
+
reason: OpsLogReasonSchema.optional()
|
|
19831
|
+
}), EventPruneCountsSchema, {
|
|
19832
|
+
kind: "mutation",
|
|
19833
|
+
auth: "admin"
|
|
19834
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19835
|
+
kind: "mutation",
|
|
19836
|
+
auth: "admin"
|
|
19837
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19838
|
+
kind: "query",
|
|
19839
|
+
auth: "admin"
|
|
19452
19840
|
}), method(object({
|
|
19453
19841
|
eventId: string(),
|
|
19454
19842
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19473,6 +19861,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19473
19861
|
eventId: string(),
|
|
19474
19862
|
timestamp: number()
|
|
19475
19863
|
});
|
|
19864
|
+
/**
|
|
19865
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19866
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19867
|
+
* caps into per-camera event-kind descriptors.
|
|
19868
|
+
*
|
|
19869
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19870
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19871
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19872
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19873
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19874
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19875
|
+
* eventful cap is missing.
|
|
19876
|
+
*/
|
|
19877
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19878
|
+
var LEGACY_ICON = {
|
|
19879
|
+
motion: "motion",
|
|
19880
|
+
audio: "audio",
|
|
19881
|
+
person: "person",
|
|
19882
|
+
vehicle: "vehicle",
|
|
19883
|
+
animal: "animal",
|
|
19884
|
+
package: "package",
|
|
19885
|
+
door: "door",
|
|
19886
|
+
pir: "pir",
|
|
19887
|
+
smoke: "smoke",
|
|
19888
|
+
water: "water",
|
|
19889
|
+
button: "button",
|
|
19890
|
+
generic: "generic",
|
|
19891
|
+
gas: "smoke",
|
|
19892
|
+
vibration: "generic",
|
|
19893
|
+
tamper: "generic",
|
|
19894
|
+
presence: "person",
|
|
19895
|
+
lock: "generic",
|
|
19896
|
+
siren: "generic",
|
|
19897
|
+
switch: "generic",
|
|
19898
|
+
doorbell: "button"
|
|
19899
|
+
};
|
|
19900
|
+
function legacyIcon(iconId) {
|
|
19901
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19902
|
+
}
|
|
19903
|
+
/**
|
|
19904
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19905
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19906
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19907
|
+
*/
|
|
19908
|
+
var CAP_TO_KIND = {
|
|
19909
|
+
contact: "contact",
|
|
19910
|
+
motion: "motion-sensor",
|
|
19911
|
+
smoke: "smoke",
|
|
19912
|
+
flood: "flood",
|
|
19913
|
+
gas: "gas",
|
|
19914
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19915
|
+
vibration: "vibration",
|
|
19916
|
+
tamper: "tamper",
|
|
19917
|
+
presence: "presence",
|
|
19918
|
+
"enum-sensor": "enum-sensor",
|
|
19919
|
+
"event-emitter": "device-event",
|
|
19920
|
+
"lock-control": "lock",
|
|
19921
|
+
switch: "switch",
|
|
19922
|
+
button: "button",
|
|
19923
|
+
doorbell: "doorbell"
|
|
19924
|
+
};
|
|
19925
|
+
function buildDescriptor(capName, kind) {
|
|
19926
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19927
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19928
|
+
return {
|
|
19929
|
+
...t,
|
|
19930
|
+
icon: legacyIcon(t.iconId)
|
|
19931
|
+
};
|
|
19932
|
+
}
|
|
19933
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19476
19934
|
var CameraPipelineConfigSchema = object({
|
|
19477
19935
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19478
19936
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22851,13 +23309,29 @@ method(object({
|
|
|
22851
23309
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22852
23310
|
kind: "mutation",
|
|
22853
23311
|
auth: "admin"
|
|
22854
|
-
}), method(object({
|
|
23312
|
+
}), method(object({
|
|
23313
|
+
deviceId: number(),
|
|
23314
|
+
reason: OpsLogReasonSchema.optional()
|
|
23315
|
+
}), object({
|
|
22855
23316
|
floorMs: number().nullable(),
|
|
22856
23317
|
deletedBuckets: number().int(),
|
|
22857
23318
|
reclaimedBytes: number().int()
|
|
22858
23319
|
}), {
|
|
22859
23320
|
kind: "mutation",
|
|
22860
23321
|
auth: "admin"
|
|
23322
|
+
}), method(object({
|
|
23323
|
+
deviceId: number(),
|
|
23324
|
+
fromMs: number().optional(),
|
|
23325
|
+
toMs: number().optional()
|
|
23326
|
+
}), object({
|
|
23327
|
+
deletedBuckets: number().int(),
|
|
23328
|
+
reclaimedBytes: number().int()
|
|
23329
|
+
}), {
|
|
23330
|
+
kind: "mutation",
|
|
23331
|
+
auth: "admin"
|
|
23332
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23333
|
+
kind: "query",
|
|
23334
|
+
auth: "admin"
|
|
22861
23335
|
});
|
|
22862
23336
|
/**
|
|
22863
23337
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26190,6 +26664,12 @@ Object.freeze({
|
|
|
26190
26664
|
addonId: null,
|
|
26191
26665
|
access: "delete"
|
|
26192
26666
|
},
|
|
26667
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26668
|
+
capName: "pipeline-analytics",
|
|
26669
|
+
capScope: "device",
|
|
26670
|
+
addonId: null,
|
|
26671
|
+
access: "delete"
|
|
26672
|
+
},
|
|
26193
26673
|
"pipelineAnalytics.deleteTracks": {
|
|
26194
26674
|
capName: "pipeline-analytics",
|
|
26195
26675
|
capScope: "device",
|
|
@@ -26220,6 +26700,12 @@ Object.freeze({
|
|
|
26220
26700
|
addonId: null,
|
|
26221
26701
|
access: "view"
|
|
26222
26702
|
},
|
|
26703
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26704
|
+
capName: "pipeline-analytics",
|
|
26705
|
+
capScope: "device",
|
|
26706
|
+
addonId: null,
|
|
26707
|
+
access: "view"
|
|
26708
|
+
},
|
|
26223
26709
|
"pipelineAnalytics.getKeyEvents": {
|
|
26224
26710
|
capName: "pipeline-analytics",
|
|
26225
26711
|
capScope: "device",
|
|
@@ -26262,6 +26748,12 @@ Object.freeze({
|
|
|
26262
26748
|
addonId: null,
|
|
26263
26749
|
access: "view"
|
|
26264
26750
|
},
|
|
26751
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26752
|
+
capName: "pipeline-analytics",
|
|
26753
|
+
capScope: "device",
|
|
26754
|
+
addonId: null,
|
|
26755
|
+
access: "view"
|
|
26756
|
+
},
|
|
26265
26757
|
"pipelineAnalytics.listRecentTracks": {
|
|
26266
26758
|
capName: "pipeline-analytics",
|
|
26267
26759
|
capScope: "device",
|
|
@@ -26274,6 +26766,12 @@ Object.freeze({
|
|
|
26274
26766
|
addonId: null,
|
|
26275
26767
|
access: "view"
|
|
26276
26768
|
},
|
|
26769
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26770
|
+
capName: "pipeline-analytics",
|
|
26771
|
+
capScope: "device",
|
|
26772
|
+
addonId: null,
|
|
26773
|
+
access: "create"
|
|
26774
|
+
},
|
|
26277
26775
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26278
26776
|
capName: "pipeline-analytics",
|
|
26279
26777
|
capScope: "device",
|
|
@@ -27036,6 +27534,12 @@ Object.freeze({
|
|
|
27036
27534
|
addonId: null,
|
|
27037
27535
|
access: "create"
|
|
27038
27536
|
},
|
|
27537
|
+
"recording.deleteFootprint": {
|
|
27538
|
+
capName: "recording",
|
|
27539
|
+
capScope: "system",
|
|
27540
|
+
addonId: null,
|
|
27541
|
+
access: "delete"
|
|
27542
|
+
},
|
|
27039
27543
|
"recording.getAvailability": {
|
|
27040
27544
|
capName: "recording",
|
|
27041
27545
|
capScope: "system",
|
|
@@ -27066,6 +27570,12 @@ Object.freeze({
|
|
|
27066
27570
|
addonId: null,
|
|
27067
27571
|
access: "view"
|
|
27068
27572
|
},
|
|
27573
|
+
"recording.listOpsLog": {
|
|
27574
|
+
capName: "recording",
|
|
27575
|
+
capScope: "system",
|
|
27576
|
+
addonId: null,
|
|
27577
|
+
access: "view"
|
|
27578
|
+
},
|
|
27069
27579
|
"recording.locateSegment": {
|
|
27070
27580
|
capName: "recording",
|
|
27071
27581
|
capScope: "system",
|