@camstack/addon-provider-homeassistant 1.1.30 → 1.1.32
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
|
@@ -7463,6 +7463,62 @@ var RecordingConfigSchema = object({
|
|
|
7463
7463
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7464
7464
|
});
|
|
7465
7465
|
/**
|
|
7466
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7467
|
+
* recordings and events management surfaces.
|
|
7468
|
+
*
|
|
7469
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7470
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7471
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7472
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7473
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7474
|
+
* never fail the operation it records.
|
|
7475
|
+
*/
|
|
7476
|
+
/** Which management domain the operation belongs to. */
|
|
7477
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7478
|
+
/** The kind of management operation performed. */
|
|
7479
|
+
var OpsLogOpSchema = _enum([
|
|
7480
|
+
"prune",
|
|
7481
|
+
"manual-delete",
|
|
7482
|
+
"rescan",
|
|
7483
|
+
"retention-run"
|
|
7484
|
+
]);
|
|
7485
|
+
/** Why the operation ran. */
|
|
7486
|
+
var OpsLogReasonSchema = _enum([
|
|
7487
|
+
"retention",
|
|
7488
|
+
"quota",
|
|
7489
|
+
"manual",
|
|
7490
|
+
"operator"
|
|
7491
|
+
]);
|
|
7492
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7493
|
+
var OpsLogEntrySchema = object({
|
|
7494
|
+
/** Unique row id. */
|
|
7495
|
+
id: string(),
|
|
7496
|
+
/** Epoch ms the operation completed. */
|
|
7497
|
+
at: number(),
|
|
7498
|
+
domain: OpsLogDomainSchema,
|
|
7499
|
+
op: OpsLogOpSchema,
|
|
7500
|
+
reason: OpsLogReasonSchema,
|
|
7501
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7502
|
+
deviceId: number().nullable(),
|
|
7503
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7504
|
+
nodeId: string(),
|
|
7505
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7506
|
+
itemsAffected: number(),
|
|
7507
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7508
|
+
bytesReclaimed: number(),
|
|
7509
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7510
|
+
detail: string().nullable(),
|
|
7511
|
+
/** Who/what triggered the op. */
|
|
7512
|
+
actor: string()
|
|
7513
|
+
});
|
|
7514
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7515
|
+
var OpsLogQueryInputSchema = object({
|
|
7516
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7517
|
+
deviceId: number().optional(),
|
|
7518
|
+
/** Max rows returned, newest-first. */
|
|
7519
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7520
|
+
});
|
|
7521
|
+
/**
|
|
7466
7522
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7467
7523
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7468
7524
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7706,6 +7762,160 @@ var EncodeProfileSchema = object({
|
|
|
7706
7762
|
*/
|
|
7707
7763
|
outputArgs: array(string()).optional()
|
|
7708
7764
|
});
|
|
7765
|
+
var COCO_TO_MACRO = {
|
|
7766
|
+
mapping: {
|
|
7767
|
+
person: "person",
|
|
7768
|
+
bicycle: "vehicle",
|
|
7769
|
+
car: "vehicle",
|
|
7770
|
+
motorcycle: "vehicle",
|
|
7771
|
+
airplane: "vehicle",
|
|
7772
|
+
bus: "vehicle",
|
|
7773
|
+
train: "vehicle",
|
|
7774
|
+
truck: "vehicle",
|
|
7775
|
+
boat: "vehicle",
|
|
7776
|
+
bird: "animal",
|
|
7777
|
+
cat: "animal",
|
|
7778
|
+
dog: "animal",
|
|
7779
|
+
horse: "animal",
|
|
7780
|
+
sheep: "animal",
|
|
7781
|
+
cow: "animal",
|
|
7782
|
+
elephant: "animal",
|
|
7783
|
+
bear: "animal",
|
|
7784
|
+
zebra: "animal",
|
|
7785
|
+
giraffe: "animal",
|
|
7786
|
+
suitcase: "package",
|
|
7787
|
+
backpack: "package",
|
|
7788
|
+
handbag: "package"
|
|
7789
|
+
},
|
|
7790
|
+
preserveOriginal: false
|
|
7791
|
+
};
|
|
7792
|
+
var AUDIO_MACRO_LABELS = [
|
|
7793
|
+
{
|
|
7794
|
+
id: "speech",
|
|
7795
|
+
name: "Speech",
|
|
7796
|
+
icon: "🗣️"
|
|
7797
|
+
},
|
|
7798
|
+
{
|
|
7799
|
+
id: "scream",
|
|
7800
|
+
name: "Scream / Shout",
|
|
7801
|
+
icon: "😱"
|
|
7802
|
+
},
|
|
7803
|
+
{
|
|
7804
|
+
id: "crying",
|
|
7805
|
+
name: "Crying / Baby",
|
|
7806
|
+
icon: "😢"
|
|
7807
|
+
},
|
|
7808
|
+
{
|
|
7809
|
+
id: "laughter",
|
|
7810
|
+
name: "Laughter",
|
|
7811
|
+
icon: "😂"
|
|
7812
|
+
},
|
|
7813
|
+
{
|
|
7814
|
+
id: "music",
|
|
7815
|
+
name: "Music",
|
|
7816
|
+
icon: "🎵"
|
|
7817
|
+
},
|
|
7818
|
+
{
|
|
7819
|
+
id: "dog",
|
|
7820
|
+
name: "Dog",
|
|
7821
|
+
icon: "🐕"
|
|
7822
|
+
},
|
|
7823
|
+
{
|
|
7824
|
+
id: "cat",
|
|
7825
|
+
name: "Cat",
|
|
7826
|
+
icon: "🐈"
|
|
7827
|
+
},
|
|
7828
|
+
{
|
|
7829
|
+
id: "bird",
|
|
7830
|
+
name: "Bird",
|
|
7831
|
+
icon: "🐦"
|
|
7832
|
+
},
|
|
7833
|
+
{
|
|
7834
|
+
id: "animal",
|
|
7835
|
+
name: "Animal (other)",
|
|
7836
|
+
icon: "🐾"
|
|
7837
|
+
},
|
|
7838
|
+
{
|
|
7839
|
+
id: "alarm",
|
|
7840
|
+
name: "Alarm / Siren",
|
|
7841
|
+
icon: "🚨"
|
|
7842
|
+
},
|
|
7843
|
+
{
|
|
7844
|
+
id: "doorbell",
|
|
7845
|
+
name: "Doorbell / Knock",
|
|
7846
|
+
icon: "🔔"
|
|
7847
|
+
},
|
|
7848
|
+
{
|
|
7849
|
+
id: "glass_breaking",
|
|
7850
|
+
name: "Glass Breaking",
|
|
7851
|
+
icon: "💥"
|
|
7852
|
+
},
|
|
7853
|
+
{
|
|
7854
|
+
id: "gunshot",
|
|
7855
|
+
name: "Gunshot / Explosion",
|
|
7856
|
+
icon: "💣"
|
|
7857
|
+
},
|
|
7858
|
+
{
|
|
7859
|
+
id: "vehicle",
|
|
7860
|
+
name: "Vehicle",
|
|
7861
|
+
icon: "🚗"
|
|
7862
|
+
},
|
|
7863
|
+
{
|
|
7864
|
+
id: "siren",
|
|
7865
|
+
name: "Emergency Siren",
|
|
7866
|
+
icon: "🚑"
|
|
7867
|
+
},
|
|
7868
|
+
{
|
|
7869
|
+
id: "fire",
|
|
7870
|
+
name: "Fire / Smoke",
|
|
7871
|
+
icon: "🔥"
|
|
7872
|
+
},
|
|
7873
|
+
{
|
|
7874
|
+
id: "water",
|
|
7875
|
+
name: "Water",
|
|
7876
|
+
icon: "💧"
|
|
7877
|
+
},
|
|
7878
|
+
{
|
|
7879
|
+
id: "wind",
|
|
7880
|
+
name: "Wind / Weather",
|
|
7881
|
+
icon: "🌬️"
|
|
7882
|
+
},
|
|
7883
|
+
{
|
|
7884
|
+
id: "door",
|
|
7885
|
+
name: "Door",
|
|
7886
|
+
icon: "🚪"
|
|
7887
|
+
},
|
|
7888
|
+
{
|
|
7889
|
+
id: "footsteps",
|
|
7890
|
+
name: "Footsteps",
|
|
7891
|
+
icon: "👣"
|
|
7892
|
+
},
|
|
7893
|
+
{
|
|
7894
|
+
id: "crowd",
|
|
7895
|
+
name: "Crowd / Chatter",
|
|
7896
|
+
icon: "👥"
|
|
7897
|
+
},
|
|
7898
|
+
{
|
|
7899
|
+
id: "telephone",
|
|
7900
|
+
name: "Telephone",
|
|
7901
|
+
icon: "📞"
|
|
7902
|
+
},
|
|
7903
|
+
{
|
|
7904
|
+
id: "engine",
|
|
7905
|
+
name: "Engine / Motor",
|
|
7906
|
+
icon: "⚙️"
|
|
7907
|
+
},
|
|
7908
|
+
{
|
|
7909
|
+
id: "tools",
|
|
7910
|
+
name: "Tools / Construction",
|
|
7911
|
+
icon: "🔨"
|
|
7912
|
+
},
|
|
7913
|
+
{
|
|
7914
|
+
id: "silence",
|
|
7915
|
+
name: "Silence",
|
|
7916
|
+
icon: "🤫"
|
|
7917
|
+
}
|
|
7918
|
+
];
|
|
7709
7919
|
var YAMNET_TO_MACRO = {
|
|
7710
7920
|
mapping: {
|
|
7711
7921
|
Speech: "speech",
|
|
@@ -7972,6 +8182,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
7972
8182
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7973
8183
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7974
8184
|
/**
|
|
8185
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8186
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8187
|
+
* icon }`.
|
|
8188
|
+
*
|
|
8189
|
+
* This dictionary folds together what used to be scattered across four
|
|
8190
|
+
* copies:
|
|
8191
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8192
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8193
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8194
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8195
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8196
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8197
|
+
*
|
|
8198
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8199
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8200
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8201
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8202
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8203
|
+
*
|
|
8204
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8205
|
+
*/
|
|
8206
|
+
var TAXONOMY_COLORS = {
|
|
8207
|
+
motion: "#f59e0b",
|
|
8208
|
+
audio: "#06b6d4",
|
|
8209
|
+
person: "#22c55e",
|
|
8210
|
+
vehicle: "#3b82f6",
|
|
8211
|
+
animal: "#f97316",
|
|
8212
|
+
package: "#a855f7",
|
|
8213
|
+
sensor: "#8b5cf6",
|
|
8214
|
+
control: "#10b981",
|
|
8215
|
+
genericDetection: "#64748b"
|
|
8216
|
+
};
|
|
8217
|
+
var DETECTION_SUB_COLORS = {
|
|
8218
|
+
car: "#f59e0b",
|
|
8219
|
+
truck: "#d97706",
|
|
8220
|
+
bus: "#b45309",
|
|
8221
|
+
motorcycle: "#eab308",
|
|
8222
|
+
bicycle: "#ca8a04",
|
|
8223
|
+
airplane: "#60a5fa",
|
|
8224
|
+
boat: "#2563eb",
|
|
8225
|
+
train: "#1d4ed8",
|
|
8226
|
+
bird: "#14b8a6",
|
|
8227
|
+
dog: "#84cc16",
|
|
8228
|
+
cat: "#f97316",
|
|
8229
|
+
horse: "#a16207",
|
|
8230
|
+
sheep: "#a3a3a3",
|
|
8231
|
+
cow: "#78716c",
|
|
8232
|
+
elephant: "#6b7280",
|
|
8233
|
+
bear: "#7c2d12",
|
|
8234
|
+
zebra: "#404040",
|
|
8235
|
+
giraffe: "#d4a373"
|
|
8236
|
+
};
|
|
8237
|
+
function titleCase(id) {
|
|
8238
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8239
|
+
}
|
|
8240
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8241
|
+
function macro(kind, category, color, iconId, label) {
|
|
8242
|
+
entries.set(kind, {
|
|
8243
|
+
kind,
|
|
8244
|
+
parentKind: null,
|
|
8245
|
+
level: "macro",
|
|
8246
|
+
category,
|
|
8247
|
+
color,
|
|
8248
|
+
iconId,
|
|
8249
|
+
labelKey: `eventKind.${kind}`,
|
|
8250
|
+
label
|
|
8251
|
+
});
|
|
8252
|
+
}
|
|
8253
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8254
|
+
entries.set(kind, {
|
|
8255
|
+
kind,
|
|
8256
|
+
parentKind,
|
|
8257
|
+
level: "sub",
|
|
8258
|
+
category,
|
|
8259
|
+
color,
|
|
8260
|
+
iconId,
|
|
8261
|
+
labelKey: `eventKind.${kind}`,
|
|
8262
|
+
label
|
|
8263
|
+
});
|
|
8264
|
+
}
|
|
8265
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8266
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8267
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8268
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8269
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8270
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8271
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8272
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8273
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8274
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8275
|
+
if (entries.has(cocoClass)) continue;
|
|
8276
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8277
|
+
}
|
|
8278
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8279
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8280
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8281
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8282
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8283
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8284
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8285
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8286
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8287
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8288
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8289
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8290
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8291
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8292
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8293
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8294
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8295
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8296
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8297
|
+
const kind = `audio-${l.id}`;
|
|
8298
|
+
if (entries.has(kind)) continue;
|
|
8299
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8300
|
+
}
|
|
8301
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8302
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8303
|
+
/**
|
|
7975
8304
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7976
8305
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
7977
8306
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15164,9 +15493,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15164
15493
|
* `package` backs the package-drop detector — a package zone is a
|
|
15165
15494
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15166
15495
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15167
|
-
* The orchestrator provider
|
|
15168
|
-
*
|
|
15169
|
-
* consumers read
|
|
15496
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15497
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15498
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15499
|
+
* off `device.state.zoneRules.value.package`.
|
|
15170
15500
|
*/
|
|
15171
15501
|
runtimeState: object({
|
|
15172
15502
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19240,17 +19570,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19240
19570
|
"audio",
|
|
19241
19571
|
"detection",
|
|
19242
19572
|
"sensor",
|
|
19573
|
+
"control",
|
|
19243
19574
|
"custom",
|
|
19244
19575
|
"package"
|
|
19245
19576
|
]);
|
|
19577
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19578
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19246
19579
|
var EventKindDescriptorSchema = object({
|
|
19247
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19580
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19248
19581
|
kind: string(),
|
|
19582
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19583
|
+
labelKey: string(),
|
|
19584
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19249
19585
|
label: string(),
|
|
19250
19586
|
/** Hex color for timeline/legend rendering. */
|
|
19251
19587
|
color: string(),
|
|
19588
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19589
|
+
iconId: string(),
|
|
19590
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19252
19591
|
icon: EventKindIconSchema,
|
|
19253
19592
|
category: EventKindCategorySchema,
|
|
19593
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19594
|
+
parentKind: string().nullable(),
|
|
19595
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19596
|
+
level: EventKindLevelSchema,
|
|
19254
19597
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19255
19598
|
* itself; for sensor kinds the LINKED source device. */
|
|
19256
19599
|
source: object({
|
|
@@ -19323,11 +19666,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19323
19666
|
firstAt: number(),
|
|
19324
19667
|
lastAt: number()
|
|
19325
19668
|
});
|
|
19669
|
+
/**
|
|
19670
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19671
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19672
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19673
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19674
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19675
|
+
*/
|
|
19676
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19326
19677
|
var TrackSchema = object({
|
|
19327
19678
|
trackId: string(),
|
|
19328
19679
|
deviceId: number(),
|
|
19329
19680
|
className: string(),
|
|
19330
19681
|
label: string().optional(),
|
|
19682
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19683
|
+
source: TrackSourceSchema.optional(),
|
|
19331
19684
|
firstSeen: number(),
|
|
19332
19685
|
lastSeen: number(),
|
|
19333
19686
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19582,6 +19935,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19582
19935
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19583
19936
|
embeddings: number().int()
|
|
19584
19937
|
});
|
|
19938
|
+
/** Event-store footprint for one camera. */
|
|
19939
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19940
|
+
deviceId: number(),
|
|
19941
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19942
|
+
rows: number().int(),
|
|
19943
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19944
|
+
bytes: number().int()
|
|
19945
|
+
});
|
|
19946
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19947
|
+
var EventStoreFootprintSchema = object({
|
|
19948
|
+
totalRows: number().int(),
|
|
19949
|
+
totalBytes: number().int(),
|
|
19950
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19951
|
+
});
|
|
19952
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19953
|
+
var EventPruneCountsSchema = object({
|
|
19954
|
+
motion: number().int(),
|
|
19955
|
+
object: number().int(),
|
|
19956
|
+
audio: number().int()
|
|
19957
|
+
});
|
|
19585
19958
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19586
19959
|
deviceId: number(),
|
|
19587
19960
|
trackId: string()
|
|
@@ -19645,6 +20018,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19645
20018
|
}), {
|
|
19646
20019
|
kind: "mutation",
|
|
19647
20020
|
auth: "admin"
|
|
20021
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
20022
|
+
kind: "query",
|
|
20023
|
+
auth: "admin"
|
|
20024
|
+
}), method(object({
|
|
20025
|
+
olderThanMs: number(),
|
|
20026
|
+
reason: OpsLogReasonSchema.optional()
|
|
20027
|
+
}), EventPruneCountsSchema, {
|
|
20028
|
+
kind: "mutation",
|
|
20029
|
+
auth: "admin"
|
|
20030
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
20031
|
+
kind: "mutation",
|
|
20032
|
+
auth: "admin"
|
|
20033
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
20034
|
+
kind: "query",
|
|
20035
|
+
auth: "admin"
|
|
19648
20036
|
}), method(object({
|
|
19649
20037
|
eventId: string(),
|
|
19650
20038
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19669,6 +20057,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19669
20057
|
eventId: string(),
|
|
19670
20058
|
timestamp: number()
|
|
19671
20059
|
});
|
|
20060
|
+
/**
|
|
20061
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
20062
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
20063
|
+
* caps into per-camera event-kind descriptors.
|
|
20064
|
+
*
|
|
20065
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
20066
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
20067
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
20068
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
20069
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
20070
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
20071
|
+
* eventful cap is missing.
|
|
20072
|
+
*/
|
|
20073
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
20074
|
+
var LEGACY_ICON = {
|
|
20075
|
+
motion: "motion",
|
|
20076
|
+
audio: "audio",
|
|
20077
|
+
person: "person",
|
|
20078
|
+
vehicle: "vehicle",
|
|
20079
|
+
animal: "animal",
|
|
20080
|
+
package: "package",
|
|
20081
|
+
door: "door",
|
|
20082
|
+
pir: "pir",
|
|
20083
|
+
smoke: "smoke",
|
|
20084
|
+
water: "water",
|
|
20085
|
+
button: "button",
|
|
20086
|
+
generic: "generic",
|
|
20087
|
+
gas: "smoke",
|
|
20088
|
+
vibration: "generic",
|
|
20089
|
+
tamper: "generic",
|
|
20090
|
+
presence: "person",
|
|
20091
|
+
lock: "generic",
|
|
20092
|
+
siren: "generic",
|
|
20093
|
+
switch: "generic",
|
|
20094
|
+
doorbell: "button"
|
|
20095
|
+
};
|
|
20096
|
+
function legacyIcon(iconId) {
|
|
20097
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
20098
|
+
}
|
|
20099
|
+
/**
|
|
20100
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
20101
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
20102
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
20103
|
+
*/
|
|
20104
|
+
var CAP_TO_KIND = {
|
|
20105
|
+
contact: "contact",
|
|
20106
|
+
motion: "motion-sensor",
|
|
20107
|
+
smoke: "smoke",
|
|
20108
|
+
flood: "flood",
|
|
20109
|
+
gas: "gas",
|
|
20110
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
20111
|
+
vibration: "vibration",
|
|
20112
|
+
tamper: "tamper",
|
|
20113
|
+
presence: "presence",
|
|
20114
|
+
"enum-sensor": "enum-sensor",
|
|
20115
|
+
"event-emitter": "device-event",
|
|
20116
|
+
"lock-control": "lock",
|
|
20117
|
+
switch: "switch",
|
|
20118
|
+
button: "button",
|
|
20119
|
+
doorbell: "doorbell"
|
|
20120
|
+
};
|
|
20121
|
+
function buildDescriptor(capName, kind) {
|
|
20122
|
+
const t = EVENT_TAXONOMY[kind];
|
|
20123
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
20124
|
+
return {
|
|
20125
|
+
...t,
|
|
20126
|
+
icon: legacyIcon(t.iconId)
|
|
20127
|
+
};
|
|
20128
|
+
}
|
|
20129
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19672
20130
|
var CameraPipelineConfigSchema = object({
|
|
19673
20131
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19674
20132
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22967,13 +23425,29 @@ method(object({
|
|
|
22967
23425
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22968
23426
|
kind: "mutation",
|
|
22969
23427
|
auth: "admin"
|
|
22970
|
-
}), method(object({
|
|
23428
|
+
}), method(object({
|
|
23429
|
+
deviceId: number(),
|
|
23430
|
+
reason: OpsLogReasonSchema.optional()
|
|
23431
|
+
}), object({
|
|
22971
23432
|
floorMs: number().nullable(),
|
|
22972
23433
|
deletedBuckets: number().int(),
|
|
22973
23434
|
reclaimedBytes: number().int()
|
|
22974
23435
|
}), {
|
|
22975
23436
|
kind: "mutation",
|
|
22976
23437
|
auth: "admin"
|
|
23438
|
+
}), method(object({
|
|
23439
|
+
deviceId: number(),
|
|
23440
|
+
fromMs: number().optional(),
|
|
23441
|
+
toMs: number().optional()
|
|
23442
|
+
}), object({
|
|
23443
|
+
deletedBuckets: number().int(),
|
|
23444
|
+
reclaimedBytes: number().int()
|
|
23445
|
+
}), {
|
|
23446
|
+
kind: "mutation",
|
|
23447
|
+
auth: "admin"
|
|
23448
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23449
|
+
kind: "query",
|
|
23450
|
+
auth: "admin"
|
|
22977
23451
|
});
|
|
22978
23452
|
/**
|
|
22979
23453
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26095,6 +26569,12 @@ Object.freeze({
|
|
|
26095
26569
|
addonId: null,
|
|
26096
26570
|
access: "delete"
|
|
26097
26571
|
},
|
|
26572
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26573
|
+
capName: "pipeline-analytics",
|
|
26574
|
+
capScope: "device",
|
|
26575
|
+
addonId: null,
|
|
26576
|
+
access: "delete"
|
|
26577
|
+
},
|
|
26098
26578
|
"pipelineAnalytics.deleteTracks": {
|
|
26099
26579
|
capName: "pipeline-analytics",
|
|
26100
26580
|
capScope: "device",
|
|
@@ -26125,6 +26605,12 @@ Object.freeze({
|
|
|
26125
26605
|
addonId: null,
|
|
26126
26606
|
access: "view"
|
|
26127
26607
|
},
|
|
26608
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26609
|
+
capName: "pipeline-analytics",
|
|
26610
|
+
capScope: "device",
|
|
26611
|
+
addonId: null,
|
|
26612
|
+
access: "view"
|
|
26613
|
+
},
|
|
26128
26614
|
"pipelineAnalytics.getKeyEvents": {
|
|
26129
26615
|
capName: "pipeline-analytics",
|
|
26130
26616
|
capScope: "device",
|
|
@@ -26167,6 +26653,12 @@ Object.freeze({
|
|
|
26167
26653
|
addonId: null,
|
|
26168
26654
|
access: "view"
|
|
26169
26655
|
},
|
|
26656
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26657
|
+
capName: "pipeline-analytics",
|
|
26658
|
+
capScope: "device",
|
|
26659
|
+
addonId: null,
|
|
26660
|
+
access: "view"
|
|
26661
|
+
},
|
|
26170
26662
|
"pipelineAnalytics.listRecentTracks": {
|
|
26171
26663
|
capName: "pipeline-analytics",
|
|
26172
26664
|
capScope: "device",
|
|
@@ -26179,6 +26671,12 @@ Object.freeze({
|
|
|
26179
26671
|
addonId: null,
|
|
26180
26672
|
access: "view"
|
|
26181
26673
|
},
|
|
26674
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26675
|
+
capName: "pipeline-analytics",
|
|
26676
|
+
capScope: "device",
|
|
26677
|
+
addonId: null,
|
|
26678
|
+
access: "create"
|
|
26679
|
+
},
|
|
26182
26680
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26183
26681
|
capName: "pipeline-analytics",
|
|
26184
26682
|
capScope: "device",
|
|
@@ -26941,6 +27439,12 @@ Object.freeze({
|
|
|
26941
27439
|
addonId: null,
|
|
26942
27440
|
access: "create"
|
|
26943
27441
|
},
|
|
27442
|
+
"recording.deleteFootprint": {
|
|
27443
|
+
capName: "recording",
|
|
27444
|
+
capScope: "system",
|
|
27445
|
+
addonId: null,
|
|
27446
|
+
access: "delete"
|
|
27447
|
+
},
|
|
26944
27448
|
"recording.getAvailability": {
|
|
26945
27449
|
capName: "recording",
|
|
26946
27450
|
capScope: "system",
|
|
@@ -26971,6 +27475,12 @@ Object.freeze({
|
|
|
26971
27475
|
addonId: null,
|
|
26972
27476
|
access: "view"
|
|
26973
27477
|
},
|
|
27478
|
+
"recording.listOpsLog": {
|
|
27479
|
+
capName: "recording",
|
|
27480
|
+
capScope: "system",
|
|
27481
|
+
addonId: null,
|
|
27482
|
+
access: "view"
|
|
27483
|
+
},
|
|
26974
27484
|
"recording.locateSegment": {
|
|
26975
27485
|
capName: "recording",
|
|
26976
27486
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -7462,6 +7462,62 @@ var RecordingConfigSchema = object({
|
|
|
7462
7462
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7463
7463
|
});
|
|
7464
7464
|
/**
|
|
7465
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7466
|
+
* recordings and events management surfaces.
|
|
7467
|
+
*
|
|
7468
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7469
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7470
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7471
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7472
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7473
|
+
* never fail the operation it records.
|
|
7474
|
+
*/
|
|
7475
|
+
/** Which management domain the operation belongs to. */
|
|
7476
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7477
|
+
/** The kind of management operation performed. */
|
|
7478
|
+
var OpsLogOpSchema = _enum([
|
|
7479
|
+
"prune",
|
|
7480
|
+
"manual-delete",
|
|
7481
|
+
"rescan",
|
|
7482
|
+
"retention-run"
|
|
7483
|
+
]);
|
|
7484
|
+
/** Why the operation ran. */
|
|
7485
|
+
var OpsLogReasonSchema = _enum([
|
|
7486
|
+
"retention",
|
|
7487
|
+
"quota",
|
|
7488
|
+
"manual",
|
|
7489
|
+
"operator"
|
|
7490
|
+
]);
|
|
7491
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7492
|
+
var OpsLogEntrySchema = object({
|
|
7493
|
+
/** Unique row id. */
|
|
7494
|
+
id: string(),
|
|
7495
|
+
/** Epoch ms the operation completed. */
|
|
7496
|
+
at: number(),
|
|
7497
|
+
domain: OpsLogDomainSchema,
|
|
7498
|
+
op: OpsLogOpSchema,
|
|
7499
|
+
reason: OpsLogReasonSchema,
|
|
7500
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7501
|
+
deviceId: number().nullable(),
|
|
7502
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7503
|
+
nodeId: string(),
|
|
7504
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7505
|
+
itemsAffected: number(),
|
|
7506
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7507
|
+
bytesReclaimed: number(),
|
|
7508
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7509
|
+
detail: string().nullable(),
|
|
7510
|
+
/** Who/what triggered the op. */
|
|
7511
|
+
actor: string()
|
|
7512
|
+
});
|
|
7513
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7514
|
+
var OpsLogQueryInputSchema = object({
|
|
7515
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7516
|
+
deviceId: number().optional(),
|
|
7517
|
+
/** Max rows returned, newest-first. */
|
|
7518
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7519
|
+
});
|
|
7520
|
+
/**
|
|
7465
7521
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7466
7522
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7467
7523
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7705,6 +7761,160 @@ var EncodeProfileSchema = object({
|
|
|
7705
7761
|
*/
|
|
7706
7762
|
outputArgs: array(string()).optional()
|
|
7707
7763
|
});
|
|
7764
|
+
var COCO_TO_MACRO = {
|
|
7765
|
+
mapping: {
|
|
7766
|
+
person: "person",
|
|
7767
|
+
bicycle: "vehicle",
|
|
7768
|
+
car: "vehicle",
|
|
7769
|
+
motorcycle: "vehicle",
|
|
7770
|
+
airplane: "vehicle",
|
|
7771
|
+
bus: "vehicle",
|
|
7772
|
+
train: "vehicle",
|
|
7773
|
+
truck: "vehicle",
|
|
7774
|
+
boat: "vehicle",
|
|
7775
|
+
bird: "animal",
|
|
7776
|
+
cat: "animal",
|
|
7777
|
+
dog: "animal",
|
|
7778
|
+
horse: "animal",
|
|
7779
|
+
sheep: "animal",
|
|
7780
|
+
cow: "animal",
|
|
7781
|
+
elephant: "animal",
|
|
7782
|
+
bear: "animal",
|
|
7783
|
+
zebra: "animal",
|
|
7784
|
+
giraffe: "animal",
|
|
7785
|
+
suitcase: "package",
|
|
7786
|
+
backpack: "package",
|
|
7787
|
+
handbag: "package"
|
|
7788
|
+
},
|
|
7789
|
+
preserveOriginal: false
|
|
7790
|
+
};
|
|
7791
|
+
var AUDIO_MACRO_LABELS = [
|
|
7792
|
+
{
|
|
7793
|
+
id: "speech",
|
|
7794
|
+
name: "Speech",
|
|
7795
|
+
icon: "🗣️"
|
|
7796
|
+
},
|
|
7797
|
+
{
|
|
7798
|
+
id: "scream",
|
|
7799
|
+
name: "Scream / Shout",
|
|
7800
|
+
icon: "😱"
|
|
7801
|
+
},
|
|
7802
|
+
{
|
|
7803
|
+
id: "crying",
|
|
7804
|
+
name: "Crying / Baby",
|
|
7805
|
+
icon: "😢"
|
|
7806
|
+
},
|
|
7807
|
+
{
|
|
7808
|
+
id: "laughter",
|
|
7809
|
+
name: "Laughter",
|
|
7810
|
+
icon: "😂"
|
|
7811
|
+
},
|
|
7812
|
+
{
|
|
7813
|
+
id: "music",
|
|
7814
|
+
name: "Music",
|
|
7815
|
+
icon: "🎵"
|
|
7816
|
+
},
|
|
7817
|
+
{
|
|
7818
|
+
id: "dog",
|
|
7819
|
+
name: "Dog",
|
|
7820
|
+
icon: "🐕"
|
|
7821
|
+
},
|
|
7822
|
+
{
|
|
7823
|
+
id: "cat",
|
|
7824
|
+
name: "Cat",
|
|
7825
|
+
icon: "🐈"
|
|
7826
|
+
},
|
|
7827
|
+
{
|
|
7828
|
+
id: "bird",
|
|
7829
|
+
name: "Bird",
|
|
7830
|
+
icon: "🐦"
|
|
7831
|
+
},
|
|
7832
|
+
{
|
|
7833
|
+
id: "animal",
|
|
7834
|
+
name: "Animal (other)",
|
|
7835
|
+
icon: "🐾"
|
|
7836
|
+
},
|
|
7837
|
+
{
|
|
7838
|
+
id: "alarm",
|
|
7839
|
+
name: "Alarm / Siren",
|
|
7840
|
+
icon: "🚨"
|
|
7841
|
+
},
|
|
7842
|
+
{
|
|
7843
|
+
id: "doorbell",
|
|
7844
|
+
name: "Doorbell / Knock",
|
|
7845
|
+
icon: "🔔"
|
|
7846
|
+
},
|
|
7847
|
+
{
|
|
7848
|
+
id: "glass_breaking",
|
|
7849
|
+
name: "Glass Breaking",
|
|
7850
|
+
icon: "💥"
|
|
7851
|
+
},
|
|
7852
|
+
{
|
|
7853
|
+
id: "gunshot",
|
|
7854
|
+
name: "Gunshot / Explosion",
|
|
7855
|
+
icon: "💣"
|
|
7856
|
+
},
|
|
7857
|
+
{
|
|
7858
|
+
id: "vehicle",
|
|
7859
|
+
name: "Vehicle",
|
|
7860
|
+
icon: "🚗"
|
|
7861
|
+
},
|
|
7862
|
+
{
|
|
7863
|
+
id: "siren",
|
|
7864
|
+
name: "Emergency Siren",
|
|
7865
|
+
icon: "🚑"
|
|
7866
|
+
},
|
|
7867
|
+
{
|
|
7868
|
+
id: "fire",
|
|
7869
|
+
name: "Fire / Smoke",
|
|
7870
|
+
icon: "🔥"
|
|
7871
|
+
},
|
|
7872
|
+
{
|
|
7873
|
+
id: "water",
|
|
7874
|
+
name: "Water",
|
|
7875
|
+
icon: "💧"
|
|
7876
|
+
},
|
|
7877
|
+
{
|
|
7878
|
+
id: "wind",
|
|
7879
|
+
name: "Wind / Weather",
|
|
7880
|
+
icon: "🌬️"
|
|
7881
|
+
},
|
|
7882
|
+
{
|
|
7883
|
+
id: "door",
|
|
7884
|
+
name: "Door",
|
|
7885
|
+
icon: "🚪"
|
|
7886
|
+
},
|
|
7887
|
+
{
|
|
7888
|
+
id: "footsteps",
|
|
7889
|
+
name: "Footsteps",
|
|
7890
|
+
icon: "👣"
|
|
7891
|
+
},
|
|
7892
|
+
{
|
|
7893
|
+
id: "crowd",
|
|
7894
|
+
name: "Crowd / Chatter",
|
|
7895
|
+
icon: "👥"
|
|
7896
|
+
},
|
|
7897
|
+
{
|
|
7898
|
+
id: "telephone",
|
|
7899
|
+
name: "Telephone",
|
|
7900
|
+
icon: "📞"
|
|
7901
|
+
},
|
|
7902
|
+
{
|
|
7903
|
+
id: "engine",
|
|
7904
|
+
name: "Engine / Motor",
|
|
7905
|
+
icon: "⚙️"
|
|
7906
|
+
},
|
|
7907
|
+
{
|
|
7908
|
+
id: "tools",
|
|
7909
|
+
name: "Tools / Construction",
|
|
7910
|
+
icon: "🔨"
|
|
7911
|
+
},
|
|
7912
|
+
{
|
|
7913
|
+
id: "silence",
|
|
7914
|
+
name: "Silence",
|
|
7915
|
+
icon: "🤫"
|
|
7916
|
+
}
|
|
7917
|
+
];
|
|
7708
7918
|
var YAMNET_TO_MACRO = {
|
|
7709
7919
|
mapping: {
|
|
7710
7920
|
Speech: "speech",
|
|
@@ -7971,6 +8181,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
7971
8181
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7972
8182
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7973
8183
|
/**
|
|
8184
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8185
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8186
|
+
* icon }`.
|
|
8187
|
+
*
|
|
8188
|
+
* This dictionary folds together what used to be scattered across four
|
|
8189
|
+
* copies:
|
|
8190
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8191
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8192
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8193
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8194
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8195
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8196
|
+
*
|
|
8197
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8198
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8199
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8200
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8201
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8202
|
+
*
|
|
8203
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8204
|
+
*/
|
|
8205
|
+
var TAXONOMY_COLORS = {
|
|
8206
|
+
motion: "#f59e0b",
|
|
8207
|
+
audio: "#06b6d4",
|
|
8208
|
+
person: "#22c55e",
|
|
8209
|
+
vehicle: "#3b82f6",
|
|
8210
|
+
animal: "#f97316",
|
|
8211
|
+
package: "#a855f7",
|
|
8212
|
+
sensor: "#8b5cf6",
|
|
8213
|
+
control: "#10b981",
|
|
8214
|
+
genericDetection: "#64748b"
|
|
8215
|
+
};
|
|
8216
|
+
var DETECTION_SUB_COLORS = {
|
|
8217
|
+
car: "#f59e0b",
|
|
8218
|
+
truck: "#d97706",
|
|
8219
|
+
bus: "#b45309",
|
|
8220
|
+
motorcycle: "#eab308",
|
|
8221
|
+
bicycle: "#ca8a04",
|
|
8222
|
+
airplane: "#60a5fa",
|
|
8223
|
+
boat: "#2563eb",
|
|
8224
|
+
train: "#1d4ed8",
|
|
8225
|
+
bird: "#14b8a6",
|
|
8226
|
+
dog: "#84cc16",
|
|
8227
|
+
cat: "#f97316",
|
|
8228
|
+
horse: "#a16207",
|
|
8229
|
+
sheep: "#a3a3a3",
|
|
8230
|
+
cow: "#78716c",
|
|
8231
|
+
elephant: "#6b7280",
|
|
8232
|
+
bear: "#7c2d12",
|
|
8233
|
+
zebra: "#404040",
|
|
8234
|
+
giraffe: "#d4a373"
|
|
8235
|
+
};
|
|
8236
|
+
function titleCase(id) {
|
|
8237
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8238
|
+
}
|
|
8239
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8240
|
+
function macro(kind, category, color, iconId, label) {
|
|
8241
|
+
entries.set(kind, {
|
|
8242
|
+
kind,
|
|
8243
|
+
parentKind: null,
|
|
8244
|
+
level: "macro",
|
|
8245
|
+
category,
|
|
8246
|
+
color,
|
|
8247
|
+
iconId,
|
|
8248
|
+
labelKey: `eventKind.${kind}`,
|
|
8249
|
+
label
|
|
8250
|
+
});
|
|
8251
|
+
}
|
|
8252
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8253
|
+
entries.set(kind, {
|
|
8254
|
+
kind,
|
|
8255
|
+
parentKind,
|
|
8256
|
+
level: "sub",
|
|
8257
|
+
category,
|
|
8258
|
+
color,
|
|
8259
|
+
iconId,
|
|
8260
|
+
labelKey: `eventKind.${kind}`,
|
|
8261
|
+
label
|
|
8262
|
+
});
|
|
8263
|
+
}
|
|
8264
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8265
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8266
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8267
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8268
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8269
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8270
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8271
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8272
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8273
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8274
|
+
if (entries.has(cocoClass)) continue;
|
|
8275
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8276
|
+
}
|
|
8277
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8278
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8279
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8280
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8281
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8282
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8283
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8284
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8285
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8286
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8287
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8288
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8289
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8290
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8291
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8292
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8293
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8294
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8295
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8296
|
+
const kind = `audio-${l.id}`;
|
|
8297
|
+
if (entries.has(kind)) continue;
|
|
8298
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8299
|
+
}
|
|
8300
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8301
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8302
|
+
/**
|
|
7974
8303
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7975
8304
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
7976
8305
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15163,9 +15492,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15163
15492
|
* `package` backs the package-drop detector — a package zone is a
|
|
15164
15493
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15165
15494
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15166
|
-
* The orchestrator provider
|
|
15167
|
-
*
|
|
15168
|
-
* consumers read
|
|
15495
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15496
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15497
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15498
|
+
* off `device.state.zoneRules.value.package`.
|
|
15169
15499
|
*/
|
|
15170
15500
|
runtimeState: object({
|
|
15171
15501
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19239,17 +19569,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19239
19569
|
"audio",
|
|
19240
19570
|
"detection",
|
|
19241
19571
|
"sensor",
|
|
19572
|
+
"control",
|
|
19242
19573
|
"custom",
|
|
19243
19574
|
"package"
|
|
19244
19575
|
]);
|
|
19576
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19577
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19245
19578
|
var EventKindDescriptorSchema = object({
|
|
19246
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19579
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19247
19580
|
kind: string(),
|
|
19581
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19582
|
+
labelKey: string(),
|
|
19583
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19248
19584
|
label: string(),
|
|
19249
19585
|
/** Hex color for timeline/legend rendering. */
|
|
19250
19586
|
color: string(),
|
|
19587
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19588
|
+
iconId: string(),
|
|
19589
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19251
19590
|
icon: EventKindIconSchema,
|
|
19252
19591
|
category: EventKindCategorySchema,
|
|
19592
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19593
|
+
parentKind: string().nullable(),
|
|
19594
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19595
|
+
level: EventKindLevelSchema,
|
|
19253
19596
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19254
19597
|
* itself; for sensor kinds the LINKED source device. */
|
|
19255
19598
|
source: object({
|
|
@@ -19322,11 +19665,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19322
19665
|
firstAt: number(),
|
|
19323
19666
|
lastAt: number()
|
|
19324
19667
|
});
|
|
19668
|
+
/**
|
|
19669
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19670
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19671
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19672
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19673
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19674
|
+
*/
|
|
19675
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19325
19676
|
var TrackSchema = object({
|
|
19326
19677
|
trackId: string(),
|
|
19327
19678
|
deviceId: number(),
|
|
19328
19679
|
className: string(),
|
|
19329
19680
|
label: string().optional(),
|
|
19681
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19682
|
+
source: TrackSourceSchema.optional(),
|
|
19330
19683
|
firstSeen: number(),
|
|
19331
19684
|
lastSeen: number(),
|
|
19332
19685
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19581,6 +19934,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19581
19934
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19582
19935
|
embeddings: number().int()
|
|
19583
19936
|
});
|
|
19937
|
+
/** Event-store footprint for one camera. */
|
|
19938
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19939
|
+
deviceId: number(),
|
|
19940
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19941
|
+
rows: number().int(),
|
|
19942
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19943
|
+
bytes: number().int()
|
|
19944
|
+
});
|
|
19945
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19946
|
+
var EventStoreFootprintSchema = object({
|
|
19947
|
+
totalRows: number().int(),
|
|
19948
|
+
totalBytes: number().int(),
|
|
19949
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19950
|
+
});
|
|
19951
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19952
|
+
var EventPruneCountsSchema = object({
|
|
19953
|
+
motion: number().int(),
|
|
19954
|
+
object: number().int(),
|
|
19955
|
+
audio: number().int()
|
|
19956
|
+
});
|
|
19584
19957
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19585
19958
|
deviceId: number(),
|
|
19586
19959
|
trackId: string()
|
|
@@ -19644,6 +20017,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19644
20017
|
}), {
|
|
19645
20018
|
kind: "mutation",
|
|
19646
20019
|
auth: "admin"
|
|
20020
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
20021
|
+
kind: "query",
|
|
20022
|
+
auth: "admin"
|
|
20023
|
+
}), method(object({
|
|
20024
|
+
olderThanMs: number(),
|
|
20025
|
+
reason: OpsLogReasonSchema.optional()
|
|
20026
|
+
}), EventPruneCountsSchema, {
|
|
20027
|
+
kind: "mutation",
|
|
20028
|
+
auth: "admin"
|
|
20029
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
20030
|
+
kind: "mutation",
|
|
20031
|
+
auth: "admin"
|
|
20032
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
20033
|
+
kind: "query",
|
|
20034
|
+
auth: "admin"
|
|
19647
20035
|
}), method(object({
|
|
19648
20036
|
eventId: string(),
|
|
19649
20037
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19668,6 +20056,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19668
20056
|
eventId: string(),
|
|
19669
20057
|
timestamp: number()
|
|
19670
20058
|
});
|
|
20059
|
+
/**
|
|
20060
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
20061
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
20062
|
+
* caps into per-camera event-kind descriptors.
|
|
20063
|
+
*
|
|
20064
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
20065
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
20066
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
20067
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
20068
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
20069
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
20070
|
+
* eventful cap is missing.
|
|
20071
|
+
*/
|
|
20072
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
20073
|
+
var LEGACY_ICON = {
|
|
20074
|
+
motion: "motion",
|
|
20075
|
+
audio: "audio",
|
|
20076
|
+
person: "person",
|
|
20077
|
+
vehicle: "vehicle",
|
|
20078
|
+
animal: "animal",
|
|
20079
|
+
package: "package",
|
|
20080
|
+
door: "door",
|
|
20081
|
+
pir: "pir",
|
|
20082
|
+
smoke: "smoke",
|
|
20083
|
+
water: "water",
|
|
20084
|
+
button: "button",
|
|
20085
|
+
generic: "generic",
|
|
20086
|
+
gas: "smoke",
|
|
20087
|
+
vibration: "generic",
|
|
20088
|
+
tamper: "generic",
|
|
20089
|
+
presence: "person",
|
|
20090
|
+
lock: "generic",
|
|
20091
|
+
siren: "generic",
|
|
20092
|
+
switch: "generic",
|
|
20093
|
+
doorbell: "button"
|
|
20094
|
+
};
|
|
20095
|
+
function legacyIcon(iconId) {
|
|
20096
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
20097
|
+
}
|
|
20098
|
+
/**
|
|
20099
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
20100
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
20101
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
20102
|
+
*/
|
|
20103
|
+
var CAP_TO_KIND = {
|
|
20104
|
+
contact: "contact",
|
|
20105
|
+
motion: "motion-sensor",
|
|
20106
|
+
smoke: "smoke",
|
|
20107
|
+
flood: "flood",
|
|
20108
|
+
gas: "gas",
|
|
20109
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
20110
|
+
vibration: "vibration",
|
|
20111
|
+
tamper: "tamper",
|
|
20112
|
+
presence: "presence",
|
|
20113
|
+
"enum-sensor": "enum-sensor",
|
|
20114
|
+
"event-emitter": "device-event",
|
|
20115
|
+
"lock-control": "lock",
|
|
20116
|
+
switch: "switch",
|
|
20117
|
+
button: "button",
|
|
20118
|
+
doorbell: "doorbell"
|
|
20119
|
+
};
|
|
20120
|
+
function buildDescriptor(capName, kind) {
|
|
20121
|
+
const t = EVENT_TAXONOMY[kind];
|
|
20122
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
20123
|
+
return {
|
|
20124
|
+
...t,
|
|
20125
|
+
icon: legacyIcon(t.iconId)
|
|
20126
|
+
};
|
|
20127
|
+
}
|
|
20128
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19671
20129
|
var CameraPipelineConfigSchema = object({
|
|
19672
20130
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19673
20131
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22966,13 +23424,29 @@ method(object({
|
|
|
22966
23424
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22967
23425
|
kind: "mutation",
|
|
22968
23426
|
auth: "admin"
|
|
22969
|
-
}), method(object({
|
|
23427
|
+
}), method(object({
|
|
23428
|
+
deviceId: number(),
|
|
23429
|
+
reason: OpsLogReasonSchema.optional()
|
|
23430
|
+
}), object({
|
|
22970
23431
|
floorMs: number().nullable(),
|
|
22971
23432
|
deletedBuckets: number().int(),
|
|
22972
23433
|
reclaimedBytes: number().int()
|
|
22973
23434
|
}), {
|
|
22974
23435
|
kind: "mutation",
|
|
22975
23436
|
auth: "admin"
|
|
23437
|
+
}), method(object({
|
|
23438
|
+
deviceId: number(),
|
|
23439
|
+
fromMs: number().optional(),
|
|
23440
|
+
toMs: number().optional()
|
|
23441
|
+
}), object({
|
|
23442
|
+
deletedBuckets: number().int(),
|
|
23443
|
+
reclaimedBytes: number().int()
|
|
23444
|
+
}), {
|
|
23445
|
+
kind: "mutation",
|
|
23446
|
+
auth: "admin"
|
|
23447
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23448
|
+
kind: "query",
|
|
23449
|
+
auth: "admin"
|
|
22976
23450
|
});
|
|
22977
23451
|
/**
|
|
22978
23452
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26094,6 +26568,12 @@ Object.freeze({
|
|
|
26094
26568
|
addonId: null,
|
|
26095
26569
|
access: "delete"
|
|
26096
26570
|
},
|
|
26571
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26572
|
+
capName: "pipeline-analytics",
|
|
26573
|
+
capScope: "device",
|
|
26574
|
+
addonId: null,
|
|
26575
|
+
access: "delete"
|
|
26576
|
+
},
|
|
26097
26577
|
"pipelineAnalytics.deleteTracks": {
|
|
26098
26578
|
capName: "pipeline-analytics",
|
|
26099
26579
|
capScope: "device",
|
|
@@ -26124,6 +26604,12 @@ Object.freeze({
|
|
|
26124
26604
|
addonId: null,
|
|
26125
26605
|
access: "view"
|
|
26126
26606
|
},
|
|
26607
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26608
|
+
capName: "pipeline-analytics",
|
|
26609
|
+
capScope: "device",
|
|
26610
|
+
addonId: null,
|
|
26611
|
+
access: "view"
|
|
26612
|
+
},
|
|
26127
26613
|
"pipelineAnalytics.getKeyEvents": {
|
|
26128
26614
|
capName: "pipeline-analytics",
|
|
26129
26615
|
capScope: "device",
|
|
@@ -26166,6 +26652,12 @@ Object.freeze({
|
|
|
26166
26652
|
addonId: null,
|
|
26167
26653
|
access: "view"
|
|
26168
26654
|
},
|
|
26655
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26656
|
+
capName: "pipeline-analytics",
|
|
26657
|
+
capScope: "device",
|
|
26658
|
+
addonId: null,
|
|
26659
|
+
access: "view"
|
|
26660
|
+
},
|
|
26169
26661
|
"pipelineAnalytics.listRecentTracks": {
|
|
26170
26662
|
capName: "pipeline-analytics",
|
|
26171
26663
|
capScope: "device",
|
|
@@ -26178,6 +26670,12 @@ Object.freeze({
|
|
|
26178
26670
|
addonId: null,
|
|
26179
26671
|
access: "view"
|
|
26180
26672
|
},
|
|
26673
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26674
|
+
capName: "pipeline-analytics",
|
|
26675
|
+
capScope: "device",
|
|
26676
|
+
addonId: null,
|
|
26677
|
+
access: "create"
|
|
26678
|
+
},
|
|
26181
26679
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26182
26680
|
capName: "pipeline-analytics",
|
|
26183
26681
|
capScope: "device",
|
|
@@ -26940,6 +27438,12 @@ Object.freeze({
|
|
|
26940
27438
|
addonId: null,
|
|
26941
27439
|
access: "create"
|
|
26942
27440
|
},
|
|
27441
|
+
"recording.deleteFootprint": {
|
|
27442
|
+
capName: "recording",
|
|
27443
|
+
capScope: "system",
|
|
27444
|
+
addonId: null,
|
|
27445
|
+
access: "delete"
|
|
27446
|
+
},
|
|
26943
27447
|
"recording.getAvailability": {
|
|
26944
27448
|
capName: "recording",
|
|
26945
27449
|
capScope: "system",
|
|
@@ -26970,6 +27474,12 @@ Object.freeze({
|
|
|
26970
27474
|
addonId: null,
|
|
26971
27475
|
access: "view"
|
|
26972
27476
|
},
|
|
27477
|
+
"recording.listOpsLog": {
|
|
27478
|
+
capName: "recording",
|
|
27479
|
+
capScope: "system",
|
|
27480
|
+
addonId: null,
|
|
27481
|
+
access: "view"
|
|
27482
|
+
},
|
|
26973
27483
|
"recording.locateSegment": {
|
|
26974
27484
|
capName: "recording",
|
|
26975
27485
|
capScope: "system",
|