@camstack/addon-import-alexa 0.1.23 → 0.1.25
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
|
@@ -7514,6 +7514,62 @@ var RecordingConfigSchema = object({
|
|
|
7514
7514
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7515
7515
|
});
|
|
7516
7516
|
/**
|
|
7517
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7518
|
+
* recordings and events management surfaces.
|
|
7519
|
+
*
|
|
7520
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7521
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7522
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7523
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7524
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7525
|
+
* never fail the operation it records.
|
|
7526
|
+
*/
|
|
7527
|
+
/** Which management domain the operation belongs to. */
|
|
7528
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7529
|
+
/** The kind of management operation performed. */
|
|
7530
|
+
var OpsLogOpSchema = _enum([
|
|
7531
|
+
"prune",
|
|
7532
|
+
"manual-delete",
|
|
7533
|
+
"rescan",
|
|
7534
|
+
"retention-run"
|
|
7535
|
+
]);
|
|
7536
|
+
/** Why the operation ran. */
|
|
7537
|
+
var OpsLogReasonSchema = _enum([
|
|
7538
|
+
"retention",
|
|
7539
|
+
"quota",
|
|
7540
|
+
"manual",
|
|
7541
|
+
"operator"
|
|
7542
|
+
]);
|
|
7543
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7544
|
+
var OpsLogEntrySchema = object({
|
|
7545
|
+
/** Unique row id. */
|
|
7546
|
+
id: string(),
|
|
7547
|
+
/** Epoch ms the operation completed. */
|
|
7548
|
+
at: number(),
|
|
7549
|
+
domain: OpsLogDomainSchema,
|
|
7550
|
+
op: OpsLogOpSchema,
|
|
7551
|
+
reason: OpsLogReasonSchema,
|
|
7552
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7553
|
+
deviceId: number().nullable(),
|
|
7554
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7555
|
+
nodeId: string(),
|
|
7556
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7557
|
+
itemsAffected: number(),
|
|
7558
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7559
|
+
bytesReclaimed: number(),
|
|
7560
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7561
|
+
detail: string().nullable(),
|
|
7562
|
+
/** Who/what triggered the op. */
|
|
7563
|
+
actor: string()
|
|
7564
|
+
});
|
|
7565
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7566
|
+
var OpsLogQueryInputSchema = object({
|
|
7567
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7568
|
+
deviceId: number().optional(),
|
|
7569
|
+
/** Max rows returned, newest-first. */
|
|
7570
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7571
|
+
});
|
|
7572
|
+
/**
|
|
7517
7573
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7518
7574
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7519
7575
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7757,6 +7813,160 @@ var EncodeProfileSchema = object({
|
|
|
7757
7813
|
*/
|
|
7758
7814
|
outputArgs: array(string()).optional()
|
|
7759
7815
|
});
|
|
7816
|
+
var COCO_TO_MACRO = {
|
|
7817
|
+
mapping: {
|
|
7818
|
+
person: "person",
|
|
7819
|
+
bicycle: "vehicle",
|
|
7820
|
+
car: "vehicle",
|
|
7821
|
+
motorcycle: "vehicle",
|
|
7822
|
+
airplane: "vehicle",
|
|
7823
|
+
bus: "vehicle",
|
|
7824
|
+
train: "vehicle",
|
|
7825
|
+
truck: "vehicle",
|
|
7826
|
+
boat: "vehicle",
|
|
7827
|
+
bird: "animal",
|
|
7828
|
+
cat: "animal",
|
|
7829
|
+
dog: "animal",
|
|
7830
|
+
horse: "animal",
|
|
7831
|
+
sheep: "animal",
|
|
7832
|
+
cow: "animal",
|
|
7833
|
+
elephant: "animal",
|
|
7834
|
+
bear: "animal",
|
|
7835
|
+
zebra: "animal",
|
|
7836
|
+
giraffe: "animal",
|
|
7837
|
+
suitcase: "package",
|
|
7838
|
+
backpack: "package",
|
|
7839
|
+
handbag: "package"
|
|
7840
|
+
},
|
|
7841
|
+
preserveOriginal: false
|
|
7842
|
+
};
|
|
7843
|
+
var AUDIO_MACRO_LABELS = [
|
|
7844
|
+
{
|
|
7845
|
+
id: "speech",
|
|
7846
|
+
name: "Speech",
|
|
7847
|
+
icon: "🗣️"
|
|
7848
|
+
},
|
|
7849
|
+
{
|
|
7850
|
+
id: "scream",
|
|
7851
|
+
name: "Scream / Shout",
|
|
7852
|
+
icon: "😱"
|
|
7853
|
+
},
|
|
7854
|
+
{
|
|
7855
|
+
id: "crying",
|
|
7856
|
+
name: "Crying / Baby",
|
|
7857
|
+
icon: "😢"
|
|
7858
|
+
},
|
|
7859
|
+
{
|
|
7860
|
+
id: "laughter",
|
|
7861
|
+
name: "Laughter",
|
|
7862
|
+
icon: "😂"
|
|
7863
|
+
},
|
|
7864
|
+
{
|
|
7865
|
+
id: "music",
|
|
7866
|
+
name: "Music",
|
|
7867
|
+
icon: "🎵"
|
|
7868
|
+
},
|
|
7869
|
+
{
|
|
7870
|
+
id: "dog",
|
|
7871
|
+
name: "Dog",
|
|
7872
|
+
icon: "🐕"
|
|
7873
|
+
},
|
|
7874
|
+
{
|
|
7875
|
+
id: "cat",
|
|
7876
|
+
name: "Cat",
|
|
7877
|
+
icon: "🐈"
|
|
7878
|
+
},
|
|
7879
|
+
{
|
|
7880
|
+
id: "bird",
|
|
7881
|
+
name: "Bird",
|
|
7882
|
+
icon: "🐦"
|
|
7883
|
+
},
|
|
7884
|
+
{
|
|
7885
|
+
id: "animal",
|
|
7886
|
+
name: "Animal (other)",
|
|
7887
|
+
icon: "🐾"
|
|
7888
|
+
},
|
|
7889
|
+
{
|
|
7890
|
+
id: "alarm",
|
|
7891
|
+
name: "Alarm / Siren",
|
|
7892
|
+
icon: "🚨"
|
|
7893
|
+
},
|
|
7894
|
+
{
|
|
7895
|
+
id: "doorbell",
|
|
7896
|
+
name: "Doorbell / Knock",
|
|
7897
|
+
icon: "🔔"
|
|
7898
|
+
},
|
|
7899
|
+
{
|
|
7900
|
+
id: "glass_breaking",
|
|
7901
|
+
name: "Glass Breaking",
|
|
7902
|
+
icon: "💥"
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
id: "gunshot",
|
|
7906
|
+
name: "Gunshot / Explosion",
|
|
7907
|
+
icon: "💣"
|
|
7908
|
+
},
|
|
7909
|
+
{
|
|
7910
|
+
id: "vehicle",
|
|
7911
|
+
name: "Vehicle",
|
|
7912
|
+
icon: "🚗"
|
|
7913
|
+
},
|
|
7914
|
+
{
|
|
7915
|
+
id: "siren",
|
|
7916
|
+
name: "Emergency Siren",
|
|
7917
|
+
icon: "🚑"
|
|
7918
|
+
},
|
|
7919
|
+
{
|
|
7920
|
+
id: "fire",
|
|
7921
|
+
name: "Fire / Smoke",
|
|
7922
|
+
icon: "🔥"
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
id: "water",
|
|
7926
|
+
name: "Water",
|
|
7927
|
+
icon: "💧"
|
|
7928
|
+
},
|
|
7929
|
+
{
|
|
7930
|
+
id: "wind",
|
|
7931
|
+
name: "Wind / Weather",
|
|
7932
|
+
icon: "🌬️"
|
|
7933
|
+
},
|
|
7934
|
+
{
|
|
7935
|
+
id: "door",
|
|
7936
|
+
name: "Door",
|
|
7937
|
+
icon: "🚪"
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
id: "footsteps",
|
|
7941
|
+
name: "Footsteps",
|
|
7942
|
+
icon: "👣"
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
id: "crowd",
|
|
7946
|
+
name: "Crowd / Chatter",
|
|
7947
|
+
icon: "👥"
|
|
7948
|
+
},
|
|
7949
|
+
{
|
|
7950
|
+
id: "telephone",
|
|
7951
|
+
name: "Telephone",
|
|
7952
|
+
icon: "📞"
|
|
7953
|
+
},
|
|
7954
|
+
{
|
|
7955
|
+
id: "engine",
|
|
7956
|
+
name: "Engine / Motor",
|
|
7957
|
+
icon: "⚙️"
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
id: "tools",
|
|
7961
|
+
name: "Tools / Construction",
|
|
7962
|
+
icon: "🔨"
|
|
7963
|
+
},
|
|
7964
|
+
{
|
|
7965
|
+
id: "silence",
|
|
7966
|
+
name: "Silence",
|
|
7967
|
+
icon: "🤫"
|
|
7968
|
+
}
|
|
7969
|
+
];
|
|
7760
7970
|
var YAMNET_TO_MACRO = {
|
|
7761
7971
|
mapping: {
|
|
7762
7972
|
Speech: "speech",
|
|
@@ -8023,6 +8233,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8023
8233
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8024
8234
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8025
8235
|
/**
|
|
8236
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8237
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8238
|
+
* icon }`.
|
|
8239
|
+
*
|
|
8240
|
+
* This dictionary folds together what used to be scattered across four
|
|
8241
|
+
* copies:
|
|
8242
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8243
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8244
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8245
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8246
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8247
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8248
|
+
*
|
|
8249
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8250
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8251
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8252
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8253
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8254
|
+
*
|
|
8255
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8256
|
+
*/
|
|
8257
|
+
var TAXONOMY_COLORS = {
|
|
8258
|
+
motion: "#f59e0b",
|
|
8259
|
+
audio: "#06b6d4",
|
|
8260
|
+
person: "#22c55e",
|
|
8261
|
+
vehicle: "#3b82f6",
|
|
8262
|
+
animal: "#f97316",
|
|
8263
|
+
package: "#a855f7",
|
|
8264
|
+
sensor: "#8b5cf6",
|
|
8265
|
+
control: "#10b981",
|
|
8266
|
+
genericDetection: "#64748b"
|
|
8267
|
+
};
|
|
8268
|
+
var DETECTION_SUB_COLORS = {
|
|
8269
|
+
car: "#f59e0b",
|
|
8270
|
+
truck: "#d97706",
|
|
8271
|
+
bus: "#b45309",
|
|
8272
|
+
motorcycle: "#eab308",
|
|
8273
|
+
bicycle: "#ca8a04",
|
|
8274
|
+
airplane: "#60a5fa",
|
|
8275
|
+
boat: "#2563eb",
|
|
8276
|
+
train: "#1d4ed8",
|
|
8277
|
+
bird: "#14b8a6",
|
|
8278
|
+
dog: "#84cc16",
|
|
8279
|
+
cat: "#f97316",
|
|
8280
|
+
horse: "#a16207",
|
|
8281
|
+
sheep: "#a3a3a3",
|
|
8282
|
+
cow: "#78716c",
|
|
8283
|
+
elephant: "#6b7280",
|
|
8284
|
+
bear: "#7c2d12",
|
|
8285
|
+
zebra: "#404040",
|
|
8286
|
+
giraffe: "#d4a373"
|
|
8287
|
+
};
|
|
8288
|
+
function titleCase(id) {
|
|
8289
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8290
|
+
}
|
|
8291
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8292
|
+
function macro(kind, category, color, iconId, label) {
|
|
8293
|
+
entries.set(kind, {
|
|
8294
|
+
kind,
|
|
8295
|
+
parentKind: null,
|
|
8296
|
+
level: "macro",
|
|
8297
|
+
category,
|
|
8298
|
+
color,
|
|
8299
|
+
iconId,
|
|
8300
|
+
labelKey: `eventKind.${kind}`,
|
|
8301
|
+
label
|
|
8302
|
+
});
|
|
8303
|
+
}
|
|
8304
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8305
|
+
entries.set(kind, {
|
|
8306
|
+
kind,
|
|
8307
|
+
parentKind,
|
|
8308
|
+
level: "sub",
|
|
8309
|
+
category,
|
|
8310
|
+
color,
|
|
8311
|
+
iconId,
|
|
8312
|
+
labelKey: `eventKind.${kind}`,
|
|
8313
|
+
label
|
|
8314
|
+
});
|
|
8315
|
+
}
|
|
8316
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8317
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8318
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8319
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8320
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8321
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8322
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8323
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8324
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8325
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8326
|
+
if (entries.has(cocoClass)) continue;
|
|
8327
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8328
|
+
}
|
|
8329
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8330
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8331
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8332
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8333
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8334
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8335
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8336
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8337
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8338
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8339
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8340
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8341
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8342
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8343
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8344
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8345
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8346
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8347
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8348
|
+
const kind = `audio-${l.id}`;
|
|
8349
|
+
if (entries.has(kind)) continue;
|
|
8350
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8351
|
+
}
|
|
8352
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8353
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8354
|
+
/**
|
|
8026
8355
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8027
8356
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8028
8357
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -14977,9 +15306,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14977
15306
|
* `package` backs the package-drop detector — a package zone is a
|
|
14978
15307
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14979
15308
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14980
|
-
* The orchestrator provider
|
|
14981
|
-
*
|
|
14982
|
-
* consumers read
|
|
15309
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15310
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15311
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15312
|
+
* off `device.state.zoneRules.value.package`.
|
|
14983
15313
|
*/
|
|
14984
15314
|
runtimeState: object({
|
|
14985
15315
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19039,17 +19369,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19039
19369
|
"audio",
|
|
19040
19370
|
"detection",
|
|
19041
19371
|
"sensor",
|
|
19372
|
+
"control",
|
|
19042
19373
|
"custom",
|
|
19043
19374
|
"package"
|
|
19044
19375
|
]);
|
|
19376
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19377
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19045
19378
|
var EventKindDescriptorSchema = object({
|
|
19046
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19379
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19047
19380
|
kind: string(),
|
|
19381
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19382
|
+
labelKey: string(),
|
|
19383
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19048
19384
|
label: string(),
|
|
19049
19385
|
/** Hex color for timeline/legend rendering. */
|
|
19050
19386
|
color: string(),
|
|
19387
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19388
|
+
iconId: string(),
|
|
19389
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19051
19390
|
icon: EventKindIconSchema,
|
|
19052
19391
|
category: EventKindCategorySchema,
|
|
19392
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19393
|
+
parentKind: string().nullable(),
|
|
19394
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19395
|
+
level: EventKindLevelSchema,
|
|
19053
19396
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19054
19397
|
* itself; for sensor kinds the LINKED source device. */
|
|
19055
19398
|
source: object({
|
|
@@ -19122,11 +19465,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19122
19465
|
firstAt: number(),
|
|
19123
19466
|
lastAt: number()
|
|
19124
19467
|
});
|
|
19468
|
+
/**
|
|
19469
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19470
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19471
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19472
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19473
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19474
|
+
*/
|
|
19475
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19125
19476
|
var TrackSchema = object({
|
|
19126
19477
|
trackId: string(),
|
|
19127
19478
|
deviceId: number(),
|
|
19128
19479
|
className: string(),
|
|
19129
19480
|
label: string().optional(),
|
|
19481
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19482
|
+
source: TrackSourceSchema.optional(),
|
|
19130
19483
|
firstSeen: number(),
|
|
19131
19484
|
lastSeen: number(),
|
|
19132
19485
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19381,6 +19734,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19381
19734
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19382
19735
|
embeddings: number().int()
|
|
19383
19736
|
});
|
|
19737
|
+
/** Event-store footprint for one camera. */
|
|
19738
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19739
|
+
deviceId: number(),
|
|
19740
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19741
|
+
rows: number().int(),
|
|
19742
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19743
|
+
bytes: number().int()
|
|
19744
|
+
});
|
|
19745
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19746
|
+
var EventStoreFootprintSchema = object({
|
|
19747
|
+
totalRows: number().int(),
|
|
19748
|
+
totalBytes: number().int(),
|
|
19749
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19750
|
+
});
|
|
19751
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19752
|
+
var EventPruneCountsSchema = object({
|
|
19753
|
+
motion: number().int(),
|
|
19754
|
+
object: number().int(),
|
|
19755
|
+
audio: number().int()
|
|
19756
|
+
});
|
|
19384
19757
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19385
19758
|
deviceId: number(),
|
|
19386
19759
|
trackId: string()
|
|
@@ -19444,6 +19817,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19444
19817
|
}), {
|
|
19445
19818
|
kind: "mutation",
|
|
19446
19819
|
auth: "admin"
|
|
19820
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19821
|
+
kind: "query",
|
|
19822
|
+
auth: "admin"
|
|
19823
|
+
}), method(object({
|
|
19824
|
+
olderThanMs: number(),
|
|
19825
|
+
reason: OpsLogReasonSchema.optional()
|
|
19826
|
+
}), EventPruneCountsSchema, {
|
|
19827
|
+
kind: "mutation",
|
|
19828
|
+
auth: "admin"
|
|
19829
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19830
|
+
kind: "mutation",
|
|
19831
|
+
auth: "admin"
|
|
19832
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19833
|
+
kind: "query",
|
|
19834
|
+
auth: "admin"
|
|
19447
19835
|
}), method(object({
|
|
19448
19836
|
eventId: string(),
|
|
19449
19837
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19468,6 +19856,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19468
19856
|
eventId: string(),
|
|
19469
19857
|
timestamp: number()
|
|
19470
19858
|
});
|
|
19859
|
+
/**
|
|
19860
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19861
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19862
|
+
* caps into per-camera event-kind descriptors.
|
|
19863
|
+
*
|
|
19864
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19865
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19866
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19867
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19868
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19869
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19870
|
+
* eventful cap is missing.
|
|
19871
|
+
*/
|
|
19872
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19873
|
+
var LEGACY_ICON = {
|
|
19874
|
+
motion: "motion",
|
|
19875
|
+
audio: "audio",
|
|
19876
|
+
person: "person",
|
|
19877
|
+
vehicle: "vehicle",
|
|
19878
|
+
animal: "animal",
|
|
19879
|
+
package: "package",
|
|
19880
|
+
door: "door",
|
|
19881
|
+
pir: "pir",
|
|
19882
|
+
smoke: "smoke",
|
|
19883
|
+
water: "water",
|
|
19884
|
+
button: "button",
|
|
19885
|
+
generic: "generic",
|
|
19886
|
+
gas: "smoke",
|
|
19887
|
+
vibration: "generic",
|
|
19888
|
+
tamper: "generic",
|
|
19889
|
+
presence: "person",
|
|
19890
|
+
lock: "generic",
|
|
19891
|
+
siren: "generic",
|
|
19892
|
+
switch: "generic",
|
|
19893
|
+
doorbell: "button"
|
|
19894
|
+
};
|
|
19895
|
+
function legacyIcon(iconId) {
|
|
19896
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19897
|
+
}
|
|
19898
|
+
/**
|
|
19899
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19900
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19901
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19902
|
+
*/
|
|
19903
|
+
var CAP_TO_KIND = {
|
|
19904
|
+
contact: "contact",
|
|
19905
|
+
motion: "motion-sensor",
|
|
19906
|
+
smoke: "smoke",
|
|
19907
|
+
flood: "flood",
|
|
19908
|
+
gas: "gas",
|
|
19909
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19910
|
+
vibration: "vibration",
|
|
19911
|
+
tamper: "tamper",
|
|
19912
|
+
presence: "presence",
|
|
19913
|
+
"enum-sensor": "enum-sensor",
|
|
19914
|
+
"event-emitter": "device-event",
|
|
19915
|
+
"lock-control": "lock",
|
|
19916
|
+
switch: "switch",
|
|
19917
|
+
button: "button",
|
|
19918
|
+
doorbell: "doorbell"
|
|
19919
|
+
};
|
|
19920
|
+
function buildDescriptor(capName, kind) {
|
|
19921
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19922
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19923
|
+
return {
|
|
19924
|
+
...t,
|
|
19925
|
+
icon: legacyIcon(t.iconId)
|
|
19926
|
+
};
|
|
19927
|
+
}
|
|
19928
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19471
19929
|
var CameraPipelineConfigSchema = object({
|
|
19472
19930
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19473
19931
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22694,13 +23152,29 @@ method(object({
|
|
|
22694
23152
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22695
23153
|
kind: "mutation",
|
|
22696
23154
|
auth: "admin"
|
|
22697
|
-
}), method(object({
|
|
23155
|
+
}), method(object({
|
|
23156
|
+
deviceId: number(),
|
|
23157
|
+
reason: OpsLogReasonSchema.optional()
|
|
23158
|
+
}), object({
|
|
22698
23159
|
floorMs: number().nullable(),
|
|
22699
23160
|
deletedBuckets: number().int(),
|
|
22700
23161
|
reclaimedBytes: number().int()
|
|
22701
23162
|
}), {
|
|
22702
23163
|
kind: "mutation",
|
|
22703
23164
|
auth: "admin"
|
|
23165
|
+
}), method(object({
|
|
23166
|
+
deviceId: number(),
|
|
23167
|
+
fromMs: number().optional(),
|
|
23168
|
+
toMs: number().optional()
|
|
23169
|
+
}), object({
|
|
23170
|
+
deletedBuckets: number().int(),
|
|
23171
|
+
reclaimedBytes: number().int()
|
|
23172
|
+
}), {
|
|
23173
|
+
kind: "mutation",
|
|
23174
|
+
auth: "admin"
|
|
23175
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23176
|
+
kind: "query",
|
|
23177
|
+
auth: "admin"
|
|
22704
23178
|
});
|
|
22705
23179
|
/**
|
|
22706
23180
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -25822,6 +26296,12 @@ Object.freeze({
|
|
|
25822
26296
|
addonId: null,
|
|
25823
26297
|
access: "delete"
|
|
25824
26298
|
},
|
|
26299
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26300
|
+
capName: "pipeline-analytics",
|
|
26301
|
+
capScope: "device",
|
|
26302
|
+
addonId: null,
|
|
26303
|
+
access: "delete"
|
|
26304
|
+
},
|
|
25825
26305
|
"pipelineAnalytics.deleteTracks": {
|
|
25826
26306
|
capName: "pipeline-analytics",
|
|
25827
26307
|
capScope: "device",
|
|
@@ -25852,6 +26332,12 @@ Object.freeze({
|
|
|
25852
26332
|
addonId: null,
|
|
25853
26333
|
access: "view"
|
|
25854
26334
|
},
|
|
26335
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26336
|
+
capName: "pipeline-analytics",
|
|
26337
|
+
capScope: "device",
|
|
26338
|
+
addonId: null,
|
|
26339
|
+
access: "view"
|
|
26340
|
+
},
|
|
25855
26341
|
"pipelineAnalytics.getKeyEvents": {
|
|
25856
26342
|
capName: "pipeline-analytics",
|
|
25857
26343
|
capScope: "device",
|
|
@@ -25894,6 +26380,12 @@ Object.freeze({
|
|
|
25894
26380
|
addonId: null,
|
|
25895
26381
|
access: "view"
|
|
25896
26382
|
},
|
|
26383
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26384
|
+
capName: "pipeline-analytics",
|
|
26385
|
+
capScope: "device",
|
|
26386
|
+
addonId: null,
|
|
26387
|
+
access: "view"
|
|
26388
|
+
},
|
|
25897
26389
|
"pipelineAnalytics.listRecentTracks": {
|
|
25898
26390
|
capName: "pipeline-analytics",
|
|
25899
26391
|
capScope: "device",
|
|
@@ -25906,6 +26398,12 @@ Object.freeze({
|
|
|
25906
26398
|
addonId: null,
|
|
25907
26399
|
access: "view"
|
|
25908
26400
|
},
|
|
26401
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26402
|
+
capName: "pipeline-analytics",
|
|
26403
|
+
capScope: "device",
|
|
26404
|
+
addonId: null,
|
|
26405
|
+
access: "create"
|
|
26406
|
+
},
|
|
25909
26407
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25910
26408
|
capName: "pipeline-analytics",
|
|
25911
26409
|
capScope: "device",
|
|
@@ -26668,6 +27166,12 @@ Object.freeze({
|
|
|
26668
27166
|
addonId: null,
|
|
26669
27167
|
access: "create"
|
|
26670
27168
|
},
|
|
27169
|
+
"recording.deleteFootprint": {
|
|
27170
|
+
capName: "recording",
|
|
27171
|
+
capScope: "system",
|
|
27172
|
+
addonId: null,
|
|
27173
|
+
access: "delete"
|
|
27174
|
+
},
|
|
26671
27175
|
"recording.getAvailability": {
|
|
26672
27176
|
capName: "recording",
|
|
26673
27177
|
capScope: "system",
|
|
@@ -26698,6 +27202,12 @@ Object.freeze({
|
|
|
26698
27202
|
addonId: null,
|
|
26699
27203
|
access: "view"
|
|
26700
27204
|
},
|
|
27205
|
+
"recording.listOpsLog": {
|
|
27206
|
+
capName: "recording",
|
|
27207
|
+
capScope: "system",
|
|
27208
|
+
addonId: null,
|
|
27209
|
+
access: "view"
|
|
27210
|
+
},
|
|
26701
27211
|
"recording.locateSegment": {
|
|
26702
27212
|
capName: "recording",
|
|
26703
27213
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -7514,6 +7514,62 @@ var RecordingConfigSchema = object({
|
|
|
7514
7514
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7515
7515
|
});
|
|
7516
7516
|
/**
|
|
7517
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7518
|
+
* recordings and events management surfaces.
|
|
7519
|
+
*
|
|
7520
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7521
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7522
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7523
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7524
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7525
|
+
* never fail the operation it records.
|
|
7526
|
+
*/
|
|
7527
|
+
/** Which management domain the operation belongs to. */
|
|
7528
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7529
|
+
/** The kind of management operation performed. */
|
|
7530
|
+
var OpsLogOpSchema = _enum([
|
|
7531
|
+
"prune",
|
|
7532
|
+
"manual-delete",
|
|
7533
|
+
"rescan",
|
|
7534
|
+
"retention-run"
|
|
7535
|
+
]);
|
|
7536
|
+
/** Why the operation ran. */
|
|
7537
|
+
var OpsLogReasonSchema = _enum([
|
|
7538
|
+
"retention",
|
|
7539
|
+
"quota",
|
|
7540
|
+
"manual",
|
|
7541
|
+
"operator"
|
|
7542
|
+
]);
|
|
7543
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7544
|
+
var OpsLogEntrySchema = object({
|
|
7545
|
+
/** Unique row id. */
|
|
7546
|
+
id: string(),
|
|
7547
|
+
/** Epoch ms the operation completed. */
|
|
7548
|
+
at: number(),
|
|
7549
|
+
domain: OpsLogDomainSchema,
|
|
7550
|
+
op: OpsLogOpSchema,
|
|
7551
|
+
reason: OpsLogReasonSchema,
|
|
7552
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7553
|
+
deviceId: number().nullable(),
|
|
7554
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7555
|
+
nodeId: string(),
|
|
7556
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7557
|
+
itemsAffected: number(),
|
|
7558
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7559
|
+
bytesReclaimed: number(),
|
|
7560
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7561
|
+
detail: string().nullable(),
|
|
7562
|
+
/** Who/what triggered the op. */
|
|
7563
|
+
actor: string()
|
|
7564
|
+
});
|
|
7565
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7566
|
+
var OpsLogQueryInputSchema = object({
|
|
7567
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7568
|
+
deviceId: number().optional(),
|
|
7569
|
+
/** Max rows returned, newest-first. */
|
|
7570
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7571
|
+
});
|
|
7572
|
+
/**
|
|
7517
7573
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7518
7574
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7519
7575
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7757,6 +7813,160 @@ var EncodeProfileSchema = object({
|
|
|
7757
7813
|
*/
|
|
7758
7814
|
outputArgs: array(string()).optional()
|
|
7759
7815
|
});
|
|
7816
|
+
var COCO_TO_MACRO = {
|
|
7817
|
+
mapping: {
|
|
7818
|
+
person: "person",
|
|
7819
|
+
bicycle: "vehicle",
|
|
7820
|
+
car: "vehicle",
|
|
7821
|
+
motorcycle: "vehicle",
|
|
7822
|
+
airplane: "vehicle",
|
|
7823
|
+
bus: "vehicle",
|
|
7824
|
+
train: "vehicle",
|
|
7825
|
+
truck: "vehicle",
|
|
7826
|
+
boat: "vehicle",
|
|
7827
|
+
bird: "animal",
|
|
7828
|
+
cat: "animal",
|
|
7829
|
+
dog: "animal",
|
|
7830
|
+
horse: "animal",
|
|
7831
|
+
sheep: "animal",
|
|
7832
|
+
cow: "animal",
|
|
7833
|
+
elephant: "animal",
|
|
7834
|
+
bear: "animal",
|
|
7835
|
+
zebra: "animal",
|
|
7836
|
+
giraffe: "animal",
|
|
7837
|
+
suitcase: "package",
|
|
7838
|
+
backpack: "package",
|
|
7839
|
+
handbag: "package"
|
|
7840
|
+
},
|
|
7841
|
+
preserveOriginal: false
|
|
7842
|
+
};
|
|
7843
|
+
var AUDIO_MACRO_LABELS = [
|
|
7844
|
+
{
|
|
7845
|
+
id: "speech",
|
|
7846
|
+
name: "Speech",
|
|
7847
|
+
icon: "🗣️"
|
|
7848
|
+
},
|
|
7849
|
+
{
|
|
7850
|
+
id: "scream",
|
|
7851
|
+
name: "Scream / Shout",
|
|
7852
|
+
icon: "😱"
|
|
7853
|
+
},
|
|
7854
|
+
{
|
|
7855
|
+
id: "crying",
|
|
7856
|
+
name: "Crying / Baby",
|
|
7857
|
+
icon: "😢"
|
|
7858
|
+
},
|
|
7859
|
+
{
|
|
7860
|
+
id: "laughter",
|
|
7861
|
+
name: "Laughter",
|
|
7862
|
+
icon: "😂"
|
|
7863
|
+
},
|
|
7864
|
+
{
|
|
7865
|
+
id: "music",
|
|
7866
|
+
name: "Music",
|
|
7867
|
+
icon: "🎵"
|
|
7868
|
+
},
|
|
7869
|
+
{
|
|
7870
|
+
id: "dog",
|
|
7871
|
+
name: "Dog",
|
|
7872
|
+
icon: "🐕"
|
|
7873
|
+
},
|
|
7874
|
+
{
|
|
7875
|
+
id: "cat",
|
|
7876
|
+
name: "Cat",
|
|
7877
|
+
icon: "🐈"
|
|
7878
|
+
},
|
|
7879
|
+
{
|
|
7880
|
+
id: "bird",
|
|
7881
|
+
name: "Bird",
|
|
7882
|
+
icon: "🐦"
|
|
7883
|
+
},
|
|
7884
|
+
{
|
|
7885
|
+
id: "animal",
|
|
7886
|
+
name: "Animal (other)",
|
|
7887
|
+
icon: "🐾"
|
|
7888
|
+
},
|
|
7889
|
+
{
|
|
7890
|
+
id: "alarm",
|
|
7891
|
+
name: "Alarm / Siren",
|
|
7892
|
+
icon: "🚨"
|
|
7893
|
+
},
|
|
7894
|
+
{
|
|
7895
|
+
id: "doorbell",
|
|
7896
|
+
name: "Doorbell / Knock",
|
|
7897
|
+
icon: "🔔"
|
|
7898
|
+
},
|
|
7899
|
+
{
|
|
7900
|
+
id: "glass_breaking",
|
|
7901
|
+
name: "Glass Breaking",
|
|
7902
|
+
icon: "💥"
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
id: "gunshot",
|
|
7906
|
+
name: "Gunshot / Explosion",
|
|
7907
|
+
icon: "💣"
|
|
7908
|
+
},
|
|
7909
|
+
{
|
|
7910
|
+
id: "vehicle",
|
|
7911
|
+
name: "Vehicle",
|
|
7912
|
+
icon: "🚗"
|
|
7913
|
+
},
|
|
7914
|
+
{
|
|
7915
|
+
id: "siren",
|
|
7916
|
+
name: "Emergency Siren",
|
|
7917
|
+
icon: "🚑"
|
|
7918
|
+
},
|
|
7919
|
+
{
|
|
7920
|
+
id: "fire",
|
|
7921
|
+
name: "Fire / Smoke",
|
|
7922
|
+
icon: "🔥"
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
id: "water",
|
|
7926
|
+
name: "Water",
|
|
7927
|
+
icon: "💧"
|
|
7928
|
+
},
|
|
7929
|
+
{
|
|
7930
|
+
id: "wind",
|
|
7931
|
+
name: "Wind / Weather",
|
|
7932
|
+
icon: "🌬️"
|
|
7933
|
+
},
|
|
7934
|
+
{
|
|
7935
|
+
id: "door",
|
|
7936
|
+
name: "Door",
|
|
7937
|
+
icon: "🚪"
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
id: "footsteps",
|
|
7941
|
+
name: "Footsteps",
|
|
7942
|
+
icon: "👣"
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
id: "crowd",
|
|
7946
|
+
name: "Crowd / Chatter",
|
|
7947
|
+
icon: "👥"
|
|
7948
|
+
},
|
|
7949
|
+
{
|
|
7950
|
+
id: "telephone",
|
|
7951
|
+
name: "Telephone",
|
|
7952
|
+
icon: "📞"
|
|
7953
|
+
},
|
|
7954
|
+
{
|
|
7955
|
+
id: "engine",
|
|
7956
|
+
name: "Engine / Motor",
|
|
7957
|
+
icon: "⚙️"
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
id: "tools",
|
|
7961
|
+
name: "Tools / Construction",
|
|
7962
|
+
icon: "🔨"
|
|
7963
|
+
},
|
|
7964
|
+
{
|
|
7965
|
+
id: "silence",
|
|
7966
|
+
name: "Silence",
|
|
7967
|
+
icon: "🤫"
|
|
7968
|
+
}
|
|
7969
|
+
];
|
|
7760
7970
|
var YAMNET_TO_MACRO = {
|
|
7761
7971
|
mapping: {
|
|
7762
7972
|
Speech: "speech",
|
|
@@ -8023,6 +8233,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8023
8233
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8024
8234
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8025
8235
|
/**
|
|
8236
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8237
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8238
|
+
* icon }`.
|
|
8239
|
+
*
|
|
8240
|
+
* This dictionary folds together what used to be scattered across four
|
|
8241
|
+
* copies:
|
|
8242
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8243
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8244
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8245
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8246
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8247
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8248
|
+
*
|
|
8249
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8250
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8251
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8252
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8253
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8254
|
+
*
|
|
8255
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8256
|
+
*/
|
|
8257
|
+
var TAXONOMY_COLORS = {
|
|
8258
|
+
motion: "#f59e0b",
|
|
8259
|
+
audio: "#06b6d4",
|
|
8260
|
+
person: "#22c55e",
|
|
8261
|
+
vehicle: "#3b82f6",
|
|
8262
|
+
animal: "#f97316",
|
|
8263
|
+
package: "#a855f7",
|
|
8264
|
+
sensor: "#8b5cf6",
|
|
8265
|
+
control: "#10b981",
|
|
8266
|
+
genericDetection: "#64748b"
|
|
8267
|
+
};
|
|
8268
|
+
var DETECTION_SUB_COLORS = {
|
|
8269
|
+
car: "#f59e0b",
|
|
8270
|
+
truck: "#d97706",
|
|
8271
|
+
bus: "#b45309",
|
|
8272
|
+
motorcycle: "#eab308",
|
|
8273
|
+
bicycle: "#ca8a04",
|
|
8274
|
+
airplane: "#60a5fa",
|
|
8275
|
+
boat: "#2563eb",
|
|
8276
|
+
train: "#1d4ed8",
|
|
8277
|
+
bird: "#14b8a6",
|
|
8278
|
+
dog: "#84cc16",
|
|
8279
|
+
cat: "#f97316",
|
|
8280
|
+
horse: "#a16207",
|
|
8281
|
+
sheep: "#a3a3a3",
|
|
8282
|
+
cow: "#78716c",
|
|
8283
|
+
elephant: "#6b7280",
|
|
8284
|
+
bear: "#7c2d12",
|
|
8285
|
+
zebra: "#404040",
|
|
8286
|
+
giraffe: "#d4a373"
|
|
8287
|
+
};
|
|
8288
|
+
function titleCase(id) {
|
|
8289
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8290
|
+
}
|
|
8291
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8292
|
+
function macro(kind, category, color, iconId, label) {
|
|
8293
|
+
entries.set(kind, {
|
|
8294
|
+
kind,
|
|
8295
|
+
parentKind: null,
|
|
8296
|
+
level: "macro",
|
|
8297
|
+
category,
|
|
8298
|
+
color,
|
|
8299
|
+
iconId,
|
|
8300
|
+
labelKey: `eventKind.${kind}`,
|
|
8301
|
+
label
|
|
8302
|
+
});
|
|
8303
|
+
}
|
|
8304
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8305
|
+
entries.set(kind, {
|
|
8306
|
+
kind,
|
|
8307
|
+
parentKind,
|
|
8308
|
+
level: "sub",
|
|
8309
|
+
category,
|
|
8310
|
+
color,
|
|
8311
|
+
iconId,
|
|
8312
|
+
labelKey: `eventKind.${kind}`,
|
|
8313
|
+
label
|
|
8314
|
+
});
|
|
8315
|
+
}
|
|
8316
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8317
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8318
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8319
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8320
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8321
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8322
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8323
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8324
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8325
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8326
|
+
if (entries.has(cocoClass)) continue;
|
|
8327
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8328
|
+
}
|
|
8329
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8330
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8331
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8332
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8333
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8334
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8335
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8336
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8337
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8338
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8339
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8340
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8341
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8342
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8343
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8344
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8345
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8346
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8347
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8348
|
+
const kind = `audio-${l.id}`;
|
|
8349
|
+
if (entries.has(kind)) continue;
|
|
8350
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8351
|
+
}
|
|
8352
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8353
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8354
|
+
/**
|
|
8026
8355
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8027
8356
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8028
8357
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -14977,9 +15306,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14977
15306
|
* `package` backs the package-drop detector — a package zone is a
|
|
14978
15307
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14979
15308
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14980
|
-
* The orchestrator provider
|
|
14981
|
-
*
|
|
14982
|
-
* consumers read
|
|
15309
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15310
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15311
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15312
|
+
* off `device.state.zoneRules.value.package`.
|
|
14983
15313
|
*/
|
|
14984
15314
|
runtimeState: object({
|
|
14985
15315
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19039,17 +19369,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19039
19369
|
"audio",
|
|
19040
19370
|
"detection",
|
|
19041
19371
|
"sensor",
|
|
19372
|
+
"control",
|
|
19042
19373
|
"custom",
|
|
19043
19374
|
"package"
|
|
19044
19375
|
]);
|
|
19376
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19377
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19045
19378
|
var EventKindDescriptorSchema = object({
|
|
19046
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19379
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19047
19380
|
kind: string(),
|
|
19381
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19382
|
+
labelKey: string(),
|
|
19383
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19048
19384
|
label: string(),
|
|
19049
19385
|
/** Hex color for timeline/legend rendering. */
|
|
19050
19386
|
color: string(),
|
|
19387
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19388
|
+
iconId: string(),
|
|
19389
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19051
19390
|
icon: EventKindIconSchema,
|
|
19052
19391
|
category: EventKindCategorySchema,
|
|
19392
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19393
|
+
parentKind: string().nullable(),
|
|
19394
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19395
|
+
level: EventKindLevelSchema,
|
|
19053
19396
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19054
19397
|
* itself; for sensor kinds the LINKED source device. */
|
|
19055
19398
|
source: object({
|
|
@@ -19122,11 +19465,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19122
19465
|
firstAt: number(),
|
|
19123
19466
|
lastAt: number()
|
|
19124
19467
|
});
|
|
19468
|
+
/**
|
|
19469
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19470
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19471
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19472
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19473
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19474
|
+
*/
|
|
19475
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19125
19476
|
var TrackSchema = object({
|
|
19126
19477
|
trackId: string(),
|
|
19127
19478
|
deviceId: number(),
|
|
19128
19479
|
className: string(),
|
|
19129
19480
|
label: string().optional(),
|
|
19481
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19482
|
+
source: TrackSourceSchema.optional(),
|
|
19130
19483
|
firstSeen: number(),
|
|
19131
19484
|
lastSeen: number(),
|
|
19132
19485
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19381,6 +19734,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19381
19734
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19382
19735
|
embeddings: number().int()
|
|
19383
19736
|
});
|
|
19737
|
+
/** Event-store footprint for one camera. */
|
|
19738
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19739
|
+
deviceId: number(),
|
|
19740
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19741
|
+
rows: number().int(),
|
|
19742
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19743
|
+
bytes: number().int()
|
|
19744
|
+
});
|
|
19745
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19746
|
+
var EventStoreFootprintSchema = object({
|
|
19747
|
+
totalRows: number().int(),
|
|
19748
|
+
totalBytes: number().int(),
|
|
19749
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19750
|
+
});
|
|
19751
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19752
|
+
var EventPruneCountsSchema = object({
|
|
19753
|
+
motion: number().int(),
|
|
19754
|
+
object: number().int(),
|
|
19755
|
+
audio: number().int()
|
|
19756
|
+
});
|
|
19384
19757
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19385
19758
|
deviceId: number(),
|
|
19386
19759
|
trackId: string()
|
|
@@ -19444,6 +19817,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19444
19817
|
}), {
|
|
19445
19818
|
kind: "mutation",
|
|
19446
19819
|
auth: "admin"
|
|
19820
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19821
|
+
kind: "query",
|
|
19822
|
+
auth: "admin"
|
|
19823
|
+
}), method(object({
|
|
19824
|
+
olderThanMs: number(),
|
|
19825
|
+
reason: OpsLogReasonSchema.optional()
|
|
19826
|
+
}), EventPruneCountsSchema, {
|
|
19827
|
+
kind: "mutation",
|
|
19828
|
+
auth: "admin"
|
|
19829
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19830
|
+
kind: "mutation",
|
|
19831
|
+
auth: "admin"
|
|
19832
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19833
|
+
kind: "query",
|
|
19834
|
+
auth: "admin"
|
|
19447
19835
|
}), method(object({
|
|
19448
19836
|
eventId: string(),
|
|
19449
19837
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19468,6 +19856,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19468
19856
|
eventId: string(),
|
|
19469
19857
|
timestamp: number()
|
|
19470
19858
|
});
|
|
19859
|
+
/**
|
|
19860
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19861
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19862
|
+
* caps into per-camera event-kind descriptors.
|
|
19863
|
+
*
|
|
19864
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19865
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19866
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19867
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19868
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19869
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19870
|
+
* eventful cap is missing.
|
|
19871
|
+
*/
|
|
19872
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19873
|
+
var LEGACY_ICON = {
|
|
19874
|
+
motion: "motion",
|
|
19875
|
+
audio: "audio",
|
|
19876
|
+
person: "person",
|
|
19877
|
+
vehicle: "vehicle",
|
|
19878
|
+
animal: "animal",
|
|
19879
|
+
package: "package",
|
|
19880
|
+
door: "door",
|
|
19881
|
+
pir: "pir",
|
|
19882
|
+
smoke: "smoke",
|
|
19883
|
+
water: "water",
|
|
19884
|
+
button: "button",
|
|
19885
|
+
generic: "generic",
|
|
19886
|
+
gas: "smoke",
|
|
19887
|
+
vibration: "generic",
|
|
19888
|
+
tamper: "generic",
|
|
19889
|
+
presence: "person",
|
|
19890
|
+
lock: "generic",
|
|
19891
|
+
siren: "generic",
|
|
19892
|
+
switch: "generic",
|
|
19893
|
+
doorbell: "button"
|
|
19894
|
+
};
|
|
19895
|
+
function legacyIcon(iconId) {
|
|
19896
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19897
|
+
}
|
|
19898
|
+
/**
|
|
19899
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19900
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19901
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19902
|
+
*/
|
|
19903
|
+
var CAP_TO_KIND = {
|
|
19904
|
+
contact: "contact",
|
|
19905
|
+
motion: "motion-sensor",
|
|
19906
|
+
smoke: "smoke",
|
|
19907
|
+
flood: "flood",
|
|
19908
|
+
gas: "gas",
|
|
19909
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19910
|
+
vibration: "vibration",
|
|
19911
|
+
tamper: "tamper",
|
|
19912
|
+
presence: "presence",
|
|
19913
|
+
"enum-sensor": "enum-sensor",
|
|
19914
|
+
"event-emitter": "device-event",
|
|
19915
|
+
"lock-control": "lock",
|
|
19916
|
+
switch: "switch",
|
|
19917
|
+
button: "button",
|
|
19918
|
+
doorbell: "doorbell"
|
|
19919
|
+
};
|
|
19920
|
+
function buildDescriptor(capName, kind) {
|
|
19921
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19922
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19923
|
+
return {
|
|
19924
|
+
...t,
|
|
19925
|
+
icon: legacyIcon(t.iconId)
|
|
19926
|
+
};
|
|
19927
|
+
}
|
|
19928
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19471
19929
|
var CameraPipelineConfigSchema = object({
|
|
19472
19930
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19473
19931
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22694,13 +23152,29 @@ method(object({
|
|
|
22694
23152
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22695
23153
|
kind: "mutation",
|
|
22696
23154
|
auth: "admin"
|
|
22697
|
-
}), method(object({
|
|
23155
|
+
}), method(object({
|
|
23156
|
+
deviceId: number(),
|
|
23157
|
+
reason: OpsLogReasonSchema.optional()
|
|
23158
|
+
}), object({
|
|
22698
23159
|
floorMs: number().nullable(),
|
|
22699
23160
|
deletedBuckets: number().int(),
|
|
22700
23161
|
reclaimedBytes: number().int()
|
|
22701
23162
|
}), {
|
|
22702
23163
|
kind: "mutation",
|
|
22703
23164
|
auth: "admin"
|
|
23165
|
+
}), method(object({
|
|
23166
|
+
deviceId: number(),
|
|
23167
|
+
fromMs: number().optional(),
|
|
23168
|
+
toMs: number().optional()
|
|
23169
|
+
}), object({
|
|
23170
|
+
deletedBuckets: number().int(),
|
|
23171
|
+
reclaimedBytes: number().int()
|
|
23172
|
+
}), {
|
|
23173
|
+
kind: "mutation",
|
|
23174
|
+
auth: "admin"
|
|
23175
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23176
|
+
kind: "query",
|
|
23177
|
+
auth: "admin"
|
|
22704
23178
|
});
|
|
22705
23179
|
/**
|
|
22706
23180
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -25822,6 +26296,12 @@ Object.freeze({
|
|
|
25822
26296
|
addonId: null,
|
|
25823
26297
|
access: "delete"
|
|
25824
26298
|
},
|
|
26299
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26300
|
+
capName: "pipeline-analytics",
|
|
26301
|
+
capScope: "device",
|
|
26302
|
+
addonId: null,
|
|
26303
|
+
access: "delete"
|
|
26304
|
+
},
|
|
25825
26305
|
"pipelineAnalytics.deleteTracks": {
|
|
25826
26306
|
capName: "pipeline-analytics",
|
|
25827
26307
|
capScope: "device",
|
|
@@ -25852,6 +26332,12 @@ Object.freeze({
|
|
|
25852
26332
|
addonId: null,
|
|
25853
26333
|
access: "view"
|
|
25854
26334
|
},
|
|
26335
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26336
|
+
capName: "pipeline-analytics",
|
|
26337
|
+
capScope: "device",
|
|
26338
|
+
addonId: null,
|
|
26339
|
+
access: "view"
|
|
26340
|
+
},
|
|
25855
26341
|
"pipelineAnalytics.getKeyEvents": {
|
|
25856
26342
|
capName: "pipeline-analytics",
|
|
25857
26343
|
capScope: "device",
|
|
@@ -25894,6 +26380,12 @@ Object.freeze({
|
|
|
25894
26380
|
addonId: null,
|
|
25895
26381
|
access: "view"
|
|
25896
26382
|
},
|
|
26383
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26384
|
+
capName: "pipeline-analytics",
|
|
26385
|
+
capScope: "device",
|
|
26386
|
+
addonId: null,
|
|
26387
|
+
access: "view"
|
|
26388
|
+
},
|
|
25897
26389
|
"pipelineAnalytics.listRecentTracks": {
|
|
25898
26390
|
capName: "pipeline-analytics",
|
|
25899
26391
|
capScope: "device",
|
|
@@ -25906,6 +26398,12 @@ Object.freeze({
|
|
|
25906
26398
|
addonId: null,
|
|
25907
26399
|
access: "view"
|
|
25908
26400
|
},
|
|
26401
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26402
|
+
capName: "pipeline-analytics",
|
|
26403
|
+
capScope: "device",
|
|
26404
|
+
addonId: null,
|
|
26405
|
+
access: "create"
|
|
26406
|
+
},
|
|
25909
26407
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25910
26408
|
capName: "pipeline-analytics",
|
|
25911
26409
|
capScope: "device",
|
|
@@ -26668,6 +27166,12 @@ Object.freeze({
|
|
|
26668
27166
|
addonId: null,
|
|
26669
27167
|
access: "create"
|
|
26670
27168
|
},
|
|
27169
|
+
"recording.deleteFootprint": {
|
|
27170
|
+
capName: "recording",
|
|
27171
|
+
capScope: "system",
|
|
27172
|
+
addonId: null,
|
|
27173
|
+
access: "delete"
|
|
27174
|
+
},
|
|
26671
27175
|
"recording.getAvailability": {
|
|
26672
27176
|
capName: "recording",
|
|
26673
27177
|
capScope: "system",
|
|
@@ -26698,6 +27202,12 @@ Object.freeze({
|
|
|
26698
27202
|
addonId: null,
|
|
26699
27203
|
access: "view"
|
|
26700
27204
|
},
|
|
27205
|
+
"recording.listOpsLog": {
|
|
27206
|
+
capName: "recording",
|
|
27207
|
+
capScope: "system",
|
|
27208
|
+
addonId: null,
|
|
27209
|
+
access: "view"
|
|
27210
|
+
},
|
|
26701
27211
|
"recording.locateSegment": {
|
|
26702
27212
|
capName: "recording",
|
|
26703
27213
|
capScope: "system",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-import-alexa",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|