@camstack/addon-provider-wyze 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
|
@@ -7375,6 +7375,62 @@ var RecordingConfigSchema = object({
|
|
|
7375
7375
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7376
7376
|
});
|
|
7377
7377
|
/**
|
|
7378
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7379
|
+
* recordings and events management surfaces.
|
|
7380
|
+
*
|
|
7381
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7382
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7383
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7384
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7385
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7386
|
+
* never fail the operation it records.
|
|
7387
|
+
*/
|
|
7388
|
+
/** Which management domain the operation belongs to. */
|
|
7389
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7390
|
+
/** The kind of management operation performed. */
|
|
7391
|
+
var OpsLogOpSchema = _enum([
|
|
7392
|
+
"prune",
|
|
7393
|
+
"manual-delete",
|
|
7394
|
+
"rescan",
|
|
7395
|
+
"retention-run"
|
|
7396
|
+
]);
|
|
7397
|
+
/** Why the operation ran. */
|
|
7398
|
+
var OpsLogReasonSchema = _enum([
|
|
7399
|
+
"retention",
|
|
7400
|
+
"quota",
|
|
7401
|
+
"manual",
|
|
7402
|
+
"operator"
|
|
7403
|
+
]);
|
|
7404
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7405
|
+
var OpsLogEntrySchema = object({
|
|
7406
|
+
/** Unique row id. */
|
|
7407
|
+
id: string(),
|
|
7408
|
+
/** Epoch ms the operation completed. */
|
|
7409
|
+
at: number(),
|
|
7410
|
+
domain: OpsLogDomainSchema,
|
|
7411
|
+
op: OpsLogOpSchema,
|
|
7412
|
+
reason: OpsLogReasonSchema,
|
|
7413
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7414
|
+
deviceId: number().nullable(),
|
|
7415
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7416
|
+
nodeId: string(),
|
|
7417
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7418
|
+
itemsAffected: number(),
|
|
7419
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7420
|
+
bytesReclaimed: number(),
|
|
7421
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7422
|
+
detail: string().nullable(),
|
|
7423
|
+
/** Who/what triggered the op. */
|
|
7424
|
+
actor: string()
|
|
7425
|
+
});
|
|
7426
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7427
|
+
var OpsLogQueryInputSchema = object({
|
|
7428
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7429
|
+
deviceId: number().optional(),
|
|
7430
|
+
/** Max rows returned, newest-first. */
|
|
7431
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7432
|
+
});
|
|
7433
|
+
/**
|
|
7378
7434
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7379
7435
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7380
7436
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7618,6 +7674,160 @@ var EncodeProfileSchema = object({
|
|
|
7618
7674
|
*/
|
|
7619
7675
|
outputArgs: array(string()).optional()
|
|
7620
7676
|
});
|
|
7677
|
+
var COCO_TO_MACRO = {
|
|
7678
|
+
mapping: {
|
|
7679
|
+
person: "person",
|
|
7680
|
+
bicycle: "vehicle",
|
|
7681
|
+
car: "vehicle",
|
|
7682
|
+
motorcycle: "vehicle",
|
|
7683
|
+
airplane: "vehicle",
|
|
7684
|
+
bus: "vehicle",
|
|
7685
|
+
train: "vehicle",
|
|
7686
|
+
truck: "vehicle",
|
|
7687
|
+
boat: "vehicle",
|
|
7688
|
+
bird: "animal",
|
|
7689
|
+
cat: "animal",
|
|
7690
|
+
dog: "animal",
|
|
7691
|
+
horse: "animal",
|
|
7692
|
+
sheep: "animal",
|
|
7693
|
+
cow: "animal",
|
|
7694
|
+
elephant: "animal",
|
|
7695
|
+
bear: "animal",
|
|
7696
|
+
zebra: "animal",
|
|
7697
|
+
giraffe: "animal",
|
|
7698
|
+
suitcase: "package",
|
|
7699
|
+
backpack: "package",
|
|
7700
|
+
handbag: "package"
|
|
7701
|
+
},
|
|
7702
|
+
preserveOriginal: false
|
|
7703
|
+
};
|
|
7704
|
+
var AUDIO_MACRO_LABELS = [
|
|
7705
|
+
{
|
|
7706
|
+
id: "speech",
|
|
7707
|
+
name: "Speech",
|
|
7708
|
+
icon: "🗣️"
|
|
7709
|
+
},
|
|
7710
|
+
{
|
|
7711
|
+
id: "scream",
|
|
7712
|
+
name: "Scream / Shout",
|
|
7713
|
+
icon: "😱"
|
|
7714
|
+
},
|
|
7715
|
+
{
|
|
7716
|
+
id: "crying",
|
|
7717
|
+
name: "Crying / Baby",
|
|
7718
|
+
icon: "😢"
|
|
7719
|
+
},
|
|
7720
|
+
{
|
|
7721
|
+
id: "laughter",
|
|
7722
|
+
name: "Laughter",
|
|
7723
|
+
icon: "😂"
|
|
7724
|
+
},
|
|
7725
|
+
{
|
|
7726
|
+
id: "music",
|
|
7727
|
+
name: "Music",
|
|
7728
|
+
icon: "🎵"
|
|
7729
|
+
},
|
|
7730
|
+
{
|
|
7731
|
+
id: "dog",
|
|
7732
|
+
name: "Dog",
|
|
7733
|
+
icon: "🐕"
|
|
7734
|
+
},
|
|
7735
|
+
{
|
|
7736
|
+
id: "cat",
|
|
7737
|
+
name: "Cat",
|
|
7738
|
+
icon: "🐈"
|
|
7739
|
+
},
|
|
7740
|
+
{
|
|
7741
|
+
id: "bird",
|
|
7742
|
+
name: "Bird",
|
|
7743
|
+
icon: "🐦"
|
|
7744
|
+
},
|
|
7745
|
+
{
|
|
7746
|
+
id: "animal",
|
|
7747
|
+
name: "Animal (other)",
|
|
7748
|
+
icon: "🐾"
|
|
7749
|
+
},
|
|
7750
|
+
{
|
|
7751
|
+
id: "alarm",
|
|
7752
|
+
name: "Alarm / Siren",
|
|
7753
|
+
icon: "🚨"
|
|
7754
|
+
},
|
|
7755
|
+
{
|
|
7756
|
+
id: "doorbell",
|
|
7757
|
+
name: "Doorbell / Knock",
|
|
7758
|
+
icon: "🔔"
|
|
7759
|
+
},
|
|
7760
|
+
{
|
|
7761
|
+
id: "glass_breaking",
|
|
7762
|
+
name: "Glass Breaking",
|
|
7763
|
+
icon: "💥"
|
|
7764
|
+
},
|
|
7765
|
+
{
|
|
7766
|
+
id: "gunshot",
|
|
7767
|
+
name: "Gunshot / Explosion",
|
|
7768
|
+
icon: "💣"
|
|
7769
|
+
},
|
|
7770
|
+
{
|
|
7771
|
+
id: "vehicle",
|
|
7772
|
+
name: "Vehicle",
|
|
7773
|
+
icon: "🚗"
|
|
7774
|
+
},
|
|
7775
|
+
{
|
|
7776
|
+
id: "siren",
|
|
7777
|
+
name: "Emergency Siren",
|
|
7778
|
+
icon: "🚑"
|
|
7779
|
+
},
|
|
7780
|
+
{
|
|
7781
|
+
id: "fire",
|
|
7782
|
+
name: "Fire / Smoke",
|
|
7783
|
+
icon: "🔥"
|
|
7784
|
+
},
|
|
7785
|
+
{
|
|
7786
|
+
id: "water",
|
|
7787
|
+
name: "Water",
|
|
7788
|
+
icon: "💧"
|
|
7789
|
+
},
|
|
7790
|
+
{
|
|
7791
|
+
id: "wind",
|
|
7792
|
+
name: "Wind / Weather",
|
|
7793
|
+
icon: "🌬️"
|
|
7794
|
+
},
|
|
7795
|
+
{
|
|
7796
|
+
id: "door",
|
|
7797
|
+
name: "Door",
|
|
7798
|
+
icon: "🚪"
|
|
7799
|
+
},
|
|
7800
|
+
{
|
|
7801
|
+
id: "footsteps",
|
|
7802
|
+
name: "Footsteps",
|
|
7803
|
+
icon: "👣"
|
|
7804
|
+
},
|
|
7805
|
+
{
|
|
7806
|
+
id: "crowd",
|
|
7807
|
+
name: "Crowd / Chatter",
|
|
7808
|
+
icon: "👥"
|
|
7809
|
+
},
|
|
7810
|
+
{
|
|
7811
|
+
id: "telephone",
|
|
7812
|
+
name: "Telephone",
|
|
7813
|
+
icon: "📞"
|
|
7814
|
+
},
|
|
7815
|
+
{
|
|
7816
|
+
id: "engine",
|
|
7817
|
+
name: "Engine / Motor",
|
|
7818
|
+
icon: "⚙️"
|
|
7819
|
+
},
|
|
7820
|
+
{
|
|
7821
|
+
id: "tools",
|
|
7822
|
+
name: "Tools / Construction",
|
|
7823
|
+
icon: "🔨"
|
|
7824
|
+
},
|
|
7825
|
+
{
|
|
7826
|
+
id: "silence",
|
|
7827
|
+
name: "Silence",
|
|
7828
|
+
icon: "🤫"
|
|
7829
|
+
}
|
|
7830
|
+
];
|
|
7621
7831
|
var YAMNET_TO_MACRO = {
|
|
7622
7832
|
mapping: {
|
|
7623
7833
|
Speech: "speech",
|
|
@@ -7884,6 +8094,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
7884
8094
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7885
8095
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7886
8096
|
/**
|
|
8097
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8098
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8099
|
+
* icon }`.
|
|
8100
|
+
*
|
|
8101
|
+
* This dictionary folds together what used to be scattered across four
|
|
8102
|
+
* copies:
|
|
8103
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8104
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8105
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8106
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8107
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8108
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8109
|
+
*
|
|
8110
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8111
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8112
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8113
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8114
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8115
|
+
*
|
|
8116
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8117
|
+
*/
|
|
8118
|
+
var TAXONOMY_COLORS = {
|
|
8119
|
+
motion: "#f59e0b",
|
|
8120
|
+
audio: "#06b6d4",
|
|
8121
|
+
person: "#22c55e",
|
|
8122
|
+
vehicle: "#3b82f6",
|
|
8123
|
+
animal: "#f97316",
|
|
8124
|
+
package: "#a855f7",
|
|
8125
|
+
sensor: "#8b5cf6",
|
|
8126
|
+
control: "#10b981",
|
|
8127
|
+
genericDetection: "#64748b"
|
|
8128
|
+
};
|
|
8129
|
+
var DETECTION_SUB_COLORS = {
|
|
8130
|
+
car: "#f59e0b",
|
|
8131
|
+
truck: "#d97706",
|
|
8132
|
+
bus: "#b45309",
|
|
8133
|
+
motorcycle: "#eab308",
|
|
8134
|
+
bicycle: "#ca8a04",
|
|
8135
|
+
airplane: "#60a5fa",
|
|
8136
|
+
boat: "#2563eb",
|
|
8137
|
+
train: "#1d4ed8",
|
|
8138
|
+
bird: "#14b8a6",
|
|
8139
|
+
dog: "#84cc16",
|
|
8140
|
+
cat: "#f97316",
|
|
8141
|
+
horse: "#a16207",
|
|
8142
|
+
sheep: "#a3a3a3",
|
|
8143
|
+
cow: "#78716c",
|
|
8144
|
+
elephant: "#6b7280",
|
|
8145
|
+
bear: "#7c2d12",
|
|
8146
|
+
zebra: "#404040",
|
|
8147
|
+
giraffe: "#d4a373"
|
|
8148
|
+
};
|
|
8149
|
+
function titleCase(id) {
|
|
8150
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8151
|
+
}
|
|
8152
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8153
|
+
function macro(kind, category, color, iconId, label) {
|
|
8154
|
+
entries.set(kind, {
|
|
8155
|
+
kind,
|
|
8156
|
+
parentKind: null,
|
|
8157
|
+
level: "macro",
|
|
8158
|
+
category,
|
|
8159
|
+
color,
|
|
8160
|
+
iconId,
|
|
8161
|
+
labelKey: `eventKind.${kind}`,
|
|
8162
|
+
label
|
|
8163
|
+
});
|
|
8164
|
+
}
|
|
8165
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8166
|
+
entries.set(kind, {
|
|
8167
|
+
kind,
|
|
8168
|
+
parentKind,
|
|
8169
|
+
level: "sub",
|
|
8170
|
+
category,
|
|
8171
|
+
color,
|
|
8172
|
+
iconId,
|
|
8173
|
+
labelKey: `eventKind.${kind}`,
|
|
8174
|
+
label
|
|
8175
|
+
});
|
|
8176
|
+
}
|
|
8177
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8178
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8179
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8180
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8181
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8182
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8183
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8184
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8185
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8186
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8187
|
+
if (entries.has(cocoClass)) continue;
|
|
8188
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8189
|
+
}
|
|
8190
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8191
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8192
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8193
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8194
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8195
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8196
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8197
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8198
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8199
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8200
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8201
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8202
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8203
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8204
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8205
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8206
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8207
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8208
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8209
|
+
const kind = `audio-${l.id}`;
|
|
8210
|
+
if (entries.has(kind)) continue;
|
|
8211
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8212
|
+
}
|
|
8213
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8214
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8215
|
+
/**
|
|
7887
8216
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7888
8217
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
7889
8218
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -14838,9 +15167,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14838
15167
|
* `package` backs the package-drop detector — a package zone is a
|
|
14839
15168
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14840
15169
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14841
|
-
* The orchestrator provider
|
|
14842
|
-
*
|
|
14843
|
-
* consumers read
|
|
15170
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15171
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15172
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15173
|
+
* off `device.state.zoneRules.value.package`.
|
|
14844
15174
|
*/
|
|
14845
15175
|
runtimeState: object({
|
|
14846
15176
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -18832,17 +19162,30 @@ var EventKindCategorySchema = _enum([
|
|
|
18832
19162
|
"audio",
|
|
18833
19163
|
"detection",
|
|
18834
19164
|
"sensor",
|
|
19165
|
+
"control",
|
|
18835
19166
|
"custom",
|
|
18836
19167
|
"package"
|
|
18837
19168
|
]);
|
|
19169
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19170
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
18838
19171
|
var EventKindDescriptorSchema = object({
|
|
18839
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19172
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
18840
19173
|
kind: string(),
|
|
19174
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19175
|
+
labelKey: string(),
|
|
19176
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
18841
19177
|
label: string(),
|
|
18842
19178
|
/** Hex color for timeline/legend rendering. */
|
|
18843
19179
|
color: string(),
|
|
19180
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19181
|
+
iconId: string(),
|
|
19182
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
18844
19183
|
icon: EventKindIconSchema,
|
|
18845
19184
|
category: EventKindCategorySchema,
|
|
19185
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19186
|
+
parentKind: string().nullable(),
|
|
19187
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19188
|
+
level: EventKindLevelSchema,
|
|
18846
19189
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18847
19190
|
* itself; for sensor kinds the LINKED source device. */
|
|
18848
19191
|
source: object({
|
|
@@ -18915,11 +19258,21 @@ var TrackAudioLabelSchema = object({
|
|
|
18915
19258
|
firstAt: number(),
|
|
18916
19259
|
lastAt: number()
|
|
18917
19260
|
});
|
|
19261
|
+
/**
|
|
19262
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19263
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19264
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19265
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19266
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19267
|
+
*/
|
|
19268
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
18918
19269
|
var TrackSchema = object({
|
|
18919
19270
|
trackId: string(),
|
|
18920
19271
|
deviceId: number(),
|
|
18921
19272
|
className: string(),
|
|
18922
19273
|
label: string().optional(),
|
|
19274
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19275
|
+
source: TrackSourceSchema.optional(),
|
|
18923
19276
|
firstSeen: number(),
|
|
18924
19277
|
lastSeen: number(),
|
|
18925
19278
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19174,6 +19527,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19174
19527
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19175
19528
|
embeddings: number().int()
|
|
19176
19529
|
});
|
|
19530
|
+
/** Event-store footprint for one camera. */
|
|
19531
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19532
|
+
deviceId: number(),
|
|
19533
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19534
|
+
rows: number().int(),
|
|
19535
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19536
|
+
bytes: number().int()
|
|
19537
|
+
});
|
|
19538
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19539
|
+
var EventStoreFootprintSchema = object({
|
|
19540
|
+
totalRows: number().int(),
|
|
19541
|
+
totalBytes: number().int(),
|
|
19542
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19543
|
+
});
|
|
19544
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19545
|
+
var EventPruneCountsSchema = object({
|
|
19546
|
+
motion: number().int(),
|
|
19547
|
+
object: number().int(),
|
|
19548
|
+
audio: number().int()
|
|
19549
|
+
});
|
|
19177
19550
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19178
19551
|
deviceId: number(),
|
|
19179
19552
|
trackId: string()
|
|
@@ -19237,6 +19610,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19237
19610
|
}), {
|
|
19238
19611
|
kind: "mutation",
|
|
19239
19612
|
auth: "admin"
|
|
19613
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19614
|
+
kind: "query",
|
|
19615
|
+
auth: "admin"
|
|
19616
|
+
}), method(object({
|
|
19617
|
+
olderThanMs: number(),
|
|
19618
|
+
reason: OpsLogReasonSchema.optional()
|
|
19619
|
+
}), EventPruneCountsSchema, {
|
|
19620
|
+
kind: "mutation",
|
|
19621
|
+
auth: "admin"
|
|
19622
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19623
|
+
kind: "mutation",
|
|
19624
|
+
auth: "admin"
|
|
19625
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19626
|
+
kind: "query",
|
|
19627
|
+
auth: "admin"
|
|
19240
19628
|
}), method(object({
|
|
19241
19629
|
eventId: string(),
|
|
19242
19630
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19261,6 +19649,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19261
19649
|
eventId: string(),
|
|
19262
19650
|
timestamp: number()
|
|
19263
19651
|
});
|
|
19652
|
+
/**
|
|
19653
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19654
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19655
|
+
* caps into per-camera event-kind descriptors.
|
|
19656
|
+
*
|
|
19657
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19658
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19659
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19660
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19661
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19662
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19663
|
+
* eventful cap is missing.
|
|
19664
|
+
*/
|
|
19665
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19666
|
+
var LEGACY_ICON = {
|
|
19667
|
+
motion: "motion",
|
|
19668
|
+
audio: "audio",
|
|
19669
|
+
person: "person",
|
|
19670
|
+
vehicle: "vehicle",
|
|
19671
|
+
animal: "animal",
|
|
19672
|
+
package: "package",
|
|
19673
|
+
door: "door",
|
|
19674
|
+
pir: "pir",
|
|
19675
|
+
smoke: "smoke",
|
|
19676
|
+
water: "water",
|
|
19677
|
+
button: "button",
|
|
19678
|
+
generic: "generic",
|
|
19679
|
+
gas: "smoke",
|
|
19680
|
+
vibration: "generic",
|
|
19681
|
+
tamper: "generic",
|
|
19682
|
+
presence: "person",
|
|
19683
|
+
lock: "generic",
|
|
19684
|
+
siren: "generic",
|
|
19685
|
+
switch: "generic",
|
|
19686
|
+
doorbell: "button"
|
|
19687
|
+
};
|
|
19688
|
+
function legacyIcon(iconId) {
|
|
19689
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19690
|
+
}
|
|
19691
|
+
/**
|
|
19692
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19693
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19694
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19695
|
+
*/
|
|
19696
|
+
var CAP_TO_KIND = {
|
|
19697
|
+
contact: "contact",
|
|
19698
|
+
motion: "motion-sensor",
|
|
19699
|
+
smoke: "smoke",
|
|
19700
|
+
flood: "flood",
|
|
19701
|
+
gas: "gas",
|
|
19702
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19703
|
+
vibration: "vibration",
|
|
19704
|
+
tamper: "tamper",
|
|
19705
|
+
presence: "presence",
|
|
19706
|
+
"enum-sensor": "enum-sensor",
|
|
19707
|
+
"event-emitter": "device-event",
|
|
19708
|
+
"lock-control": "lock",
|
|
19709
|
+
switch: "switch",
|
|
19710
|
+
button: "button",
|
|
19711
|
+
doorbell: "doorbell"
|
|
19712
|
+
};
|
|
19713
|
+
function buildDescriptor(capName, kind) {
|
|
19714
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19715
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19716
|
+
return {
|
|
19717
|
+
...t,
|
|
19718
|
+
icon: legacyIcon(t.iconId)
|
|
19719
|
+
};
|
|
19720
|
+
}
|
|
19721
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19264
19722
|
var CameraPipelineConfigSchema = object({
|
|
19265
19723
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19266
19724
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22572,13 +23030,29 @@ method(object({
|
|
|
22572
23030
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22573
23031
|
kind: "mutation",
|
|
22574
23032
|
auth: "admin"
|
|
22575
|
-
}), method(object({
|
|
23033
|
+
}), method(object({
|
|
23034
|
+
deviceId: number(),
|
|
23035
|
+
reason: OpsLogReasonSchema.optional()
|
|
23036
|
+
}), object({
|
|
22576
23037
|
floorMs: number().nullable(),
|
|
22577
23038
|
deletedBuckets: number().int(),
|
|
22578
23039
|
reclaimedBytes: number().int()
|
|
22579
23040
|
}), {
|
|
22580
23041
|
kind: "mutation",
|
|
22581
23042
|
auth: "admin"
|
|
23043
|
+
}), method(object({
|
|
23044
|
+
deviceId: number(),
|
|
23045
|
+
fromMs: number().optional(),
|
|
23046
|
+
toMs: number().optional()
|
|
23047
|
+
}), object({
|
|
23048
|
+
deletedBuckets: number().int(),
|
|
23049
|
+
reclaimedBytes: number().int()
|
|
23050
|
+
}), {
|
|
23051
|
+
kind: "mutation",
|
|
23052
|
+
auth: "admin"
|
|
23053
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23054
|
+
kind: "query",
|
|
23055
|
+
auth: "admin"
|
|
22582
23056
|
});
|
|
22583
23057
|
/**
|
|
22584
23058
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -25713,6 +26187,12 @@ Object.freeze({
|
|
|
25713
26187
|
addonId: null,
|
|
25714
26188
|
access: "delete"
|
|
25715
26189
|
},
|
|
26190
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26191
|
+
capName: "pipeline-analytics",
|
|
26192
|
+
capScope: "device",
|
|
26193
|
+
addonId: null,
|
|
26194
|
+
access: "delete"
|
|
26195
|
+
},
|
|
25716
26196
|
"pipelineAnalytics.deleteTracks": {
|
|
25717
26197
|
capName: "pipeline-analytics",
|
|
25718
26198
|
capScope: "device",
|
|
@@ -25743,6 +26223,12 @@ Object.freeze({
|
|
|
25743
26223
|
addonId: null,
|
|
25744
26224
|
access: "view"
|
|
25745
26225
|
},
|
|
26226
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26227
|
+
capName: "pipeline-analytics",
|
|
26228
|
+
capScope: "device",
|
|
26229
|
+
addonId: null,
|
|
26230
|
+
access: "view"
|
|
26231
|
+
},
|
|
25746
26232
|
"pipelineAnalytics.getKeyEvents": {
|
|
25747
26233
|
capName: "pipeline-analytics",
|
|
25748
26234
|
capScope: "device",
|
|
@@ -25785,6 +26271,12 @@ Object.freeze({
|
|
|
25785
26271
|
addonId: null,
|
|
25786
26272
|
access: "view"
|
|
25787
26273
|
},
|
|
26274
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26275
|
+
capName: "pipeline-analytics",
|
|
26276
|
+
capScope: "device",
|
|
26277
|
+
addonId: null,
|
|
26278
|
+
access: "view"
|
|
26279
|
+
},
|
|
25788
26280
|
"pipelineAnalytics.listRecentTracks": {
|
|
25789
26281
|
capName: "pipeline-analytics",
|
|
25790
26282
|
capScope: "device",
|
|
@@ -25797,6 +26289,12 @@ Object.freeze({
|
|
|
25797
26289
|
addonId: null,
|
|
25798
26290
|
access: "view"
|
|
25799
26291
|
},
|
|
26292
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26293
|
+
capName: "pipeline-analytics",
|
|
26294
|
+
capScope: "device",
|
|
26295
|
+
addonId: null,
|
|
26296
|
+
access: "create"
|
|
26297
|
+
},
|
|
25800
26298
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25801
26299
|
capName: "pipeline-analytics",
|
|
25802
26300
|
capScope: "device",
|
|
@@ -26559,6 +27057,12 @@ Object.freeze({
|
|
|
26559
27057
|
addonId: null,
|
|
26560
27058
|
access: "create"
|
|
26561
27059
|
},
|
|
27060
|
+
"recording.deleteFootprint": {
|
|
27061
|
+
capName: "recording",
|
|
27062
|
+
capScope: "system",
|
|
27063
|
+
addonId: null,
|
|
27064
|
+
access: "delete"
|
|
27065
|
+
},
|
|
26562
27066
|
"recording.getAvailability": {
|
|
26563
27067
|
capName: "recording",
|
|
26564
27068
|
capScope: "system",
|
|
@@ -26589,6 +27093,12 @@ Object.freeze({
|
|
|
26589
27093
|
addonId: null,
|
|
26590
27094
|
access: "view"
|
|
26591
27095
|
},
|
|
27096
|
+
"recording.listOpsLog": {
|
|
27097
|
+
capName: "recording",
|
|
27098
|
+
capScope: "system",
|
|
27099
|
+
addonId: null,
|
|
27100
|
+
access: "view"
|
|
27101
|
+
},
|
|
26592
27102
|
"recording.locateSegment": {
|
|
26593
27103
|
capName: "recording",
|
|
26594
27104
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -7354,6 +7354,62 @@ var RecordingConfigSchema = object({
|
|
|
7354
7354
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7355
7355
|
});
|
|
7356
7356
|
/**
|
|
7357
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7358
|
+
* recordings and events management surfaces.
|
|
7359
|
+
*
|
|
7360
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7361
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7362
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7363
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7364
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7365
|
+
* never fail the operation it records.
|
|
7366
|
+
*/
|
|
7367
|
+
/** Which management domain the operation belongs to. */
|
|
7368
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7369
|
+
/** The kind of management operation performed. */
|
|
7370
|
+
var OpsLogOpSchema = _enum([
|
|
7371
|
+
"prune",
|
|
7372
|
+
"manual-delete",
|
|
7373
|
+
"rescan",
|
|
7374
|
+
"retention-run"
|
|
7375
|
+
]);
|
|
7376
|
+
/** Why the operation ran. */
|
|
7377
|
+
var OpsLogReasonSchema = _enum([
|
|
7378
|
+
"retention",
|
|
7379
|
+
"quota",
|
|
7380
|
+
"manual",
|
|
7381
|
+
"operator"
|
|
7382
|
+
]);
|
|
7383
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7384
|
+
var OpsLogEntrySchema = object({
|
|
7385
|
+
/** Unique row id. */
|
|
7386
|
+
id: string(),
|
|
7387
|
+
/** Epoch ms the operation completed. */
|
|
7388
|
+
at: number(),
|
|
7389
|
+
domain: OpsLogDomainSchema,
|
|
7390
|
+
op: OpsLogOpSchema,
|
|
7391
|
+
reason: OpsLogReasonSchema,
|
|
7392
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7393
|
+
deviceId: number().nullable(),
|
|
7394
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7395
|
+
nodeId: string(),
|
|
7396
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7397
|
+
itemsAffected: number(),
|
|
7398
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7399
|
+
bytesReclaimed: number(),
|
|
7400
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7401
|
+
detail: string().nullable(),
|
|
7402
|
+
/** Who/what triggered the op. */
|
|
7403
|
+
actor: string()
|
|
7404
|
+
});
|
|
7405
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7406
|
+
var OpsLogQueryInputSchema = object({
|
|
7407
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7408
|
+
deviceId: number().optional(),
|
|
7409
|
+
/** Max rows returned, newest-first. */
|
|
7410
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7411
|
+
});
|
|
7412
|
+
/**
|
|
7357
7413
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7358
7414
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7359
7415
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7597,6 +7653,160 @@ var EncodeProfileSchema = object({
|
|
|
7597
7653
|
*/
|
|
7598
7654
|
outputArgs: array(string()).optional()
|
|
7599
7655
|
});
|
|
7656
|
+
var COCO_TO_MACRO = {
|
|
7657
|
+
mapping: {
|
|
7658
|
+
person: "person",
|
|
7659
|
+
bicycle: "vehicle",
|
|
7660
|
+
car: "vehicle",
|
|
7661
|
+
motorcycle: "vehicle",
|
|
7662
|
+
airplane: "vehicle",
|
|
7663
|
+
bus: "vehicle",
|
|
7664
|
+
train: "vehicle",
|
|
7665
|
+
truck: "vehicle",
|
|
7666
|
+
boat: "vehicle",
|
|
7667
|
+
bird: "animal",
|
|
7668
|
+
cat: "animal",
|
|
7669
|
+
dog: "animal",
|
|
7670
|
+
horse: "animal",
|
|
7671
|
+
sheep: "animal",
|
|
7672
|
+
cow: "animal",
|
|
7673
|
+
elephant: "animal",
|
|
7674
|
+
bear: "animal",
|
|
7675
|
+
zebra: "animal",
|
|
7676
|
+
giraffe: "animal",
|
|
7677
|
+
suitcase: "package",
|
|
7678
|
+
backpack: "package",
|
|
7679
|
+
handbag: "package"
|
|
7680
|
+
},
|
|
7681
|
+
preserveOriginal: false
|
|
7682
|
+
};
|
|
7683
|
+
var AUDIO_MACRO_LABELS = [
|
|
7684
|
+
{
|
|
7685
|
+
id: "speech",
|
|
7686
|
+
name: "Speech",
|
|
7687
|
+
icon: "🗣️"
|
|
7688
|
+
},
|
|
7689
|
+
{
|
|
7690
|
+
id: "scream",
|
|
7691
|
+
name: "Scream / Shout",
|
|
7692
|
+
icon: "😱"
|
|
7693
|
+
},
|
|
7694
|
+
{
|
|
7695
|
+
id: "crying",
|
|
7696
|
+
name: "Crying / Baby",
|
|
7697
|
+
icon: "😢"
|
|
7698
|
+
},
|
|
7699
|
+
{
|
|
7700
|
+
id: "laughter",
|
|
7701
|
+
name: "Laughter",
|
|
7702
|
+
icon: "😂"
|
|
7703
|
+
},
|
|
7704
|
+
{
|
|
7705
|
+
id: "music",
|
|
7706
|
+
name: "Music",
|
|
7707
|
+
icon: "🎵"
|
|
7708
|
+
},
|
|
7709
|
+
{
|
|
7710
|
+
id: "dog",
|
|
7711
|
+
name: "Dog",
|
|
7712
|
+
icon: "🐕"
|
|
7713
|
+
},
|
|
7714
|
+
{
|
|
7715
|
+
id: "cat",
|
|
7716
|
+
name: "Cat",
|
|
7717
|
+
icon: "🐈"
|
|
7718
|
+
},
|
|
7719
|
+
{
|
|
7720
|
+
id: "bird",
|
|
7721
|
+
name: "Bird",
|
|
7722
|
+
icon: "🐦"
|
|
7723
|
+
},
|
|
7724
|
+
{
|
|
7725
|
+
id: "animal",
|
|
7726
|
+
name: "Animal (other)",
|
|
7727
|
+
icon: "🐾"
|
|
7728
|
+
},
|
|
7729
|
+
{
|
|
7730
|
+
id: "alarm",
|
|
7731
|
+
name: "Alarm / Siren",
|
|
7732
|
+
icon: "🚨"
|
|
7733
|
+
},
|
|
7734
|
+
{
|
|
7735
|
+
id: "doorbell",
|
|
7736
|
+
name: "Doorbell / Knock",
|
|
7737
|
+
icon: "🔔"
|
|
7738
|
+
},
|
|
7739
|
+
{
|
|
7740
|
+
id: "glass_breaking",
|
|
7741
|
+
name: "Glass Breaking",
|
|
7742
|
+
icon: "💥"
|
|
7743
|
+
},
|
|
7744
|
+
{
|
|
7745
|
+
id: "gunshot",
|
|
7746
|
+
name: "Gunshot / Explosion",
|
|
7747
|
+
icon: "💣"
|
|
7748
|
+
},
|
|
7749
|
+
{
|
|
7750
|
+
id: "vehicle",
|
|
7751
|
+
name: "Vehicle",
|
|
7752
|
+
icon: "🚗"
|
|
7753
|
+
},
|
|
7754
|
+
{
|
|
7755
|
+
id: "siren",
|
|
7756
|
+
name: "Emergency Siren",
|
|
7757
|
+
icon: "🚑"
|
|
7758
|
+
},
|
|
7759
|
+
{
|
|
7760
|
+
id: "fire",
|
|
7761
|
+
name: "Fire / Smoke",
|
|
7762
|
+
icon: "🔥"
|
|
7763
|
+
},
|
|
7764
|
+
{
|
|
7765
|
+
id: "water",
|
|
7766
|
+
name: "Water",
|
|
7767
|
+
icon: "💧"
|
|
7768
|
+
},
|
|
7769
|
+
{
|
|
7770
|
+
id: "wind",
|
|
7771
|
+
name: "Wind / Weather",
|
|
7772
|
+
icon: "🌬️"
|
|
7773
|
+
},
|
|
7774
|
+
{
|
|
7775
|
+
id: "door",
|
|
7776
|
+
name: "Door",
|
|
7777
|
+
icon: "🚪"
|
|
7778
|
+
},
|
|
7779
|
+
{
|
|
7780
|
+
id: "footsteps",
|
|
7781
|
+
name: "Footsteps",
|
|
7782
|
+
icon: "👣"
|
|
7783
|
+
},
|
|
7784
|
+
{
|
|
7785
|
+
id: "crowd",
|
|
7786
|
+
name: "Crowd / Chatter",
|
|
7787
|
+
icon: "👥"
|
|
7788
|
+
},
|
|
7789
|
+
{
|
|
7790
|
+
id: "telephone",
|
|
7791
|
+
name: "Telephone",
|
|
7792
|
+
icon: "📞"
|
|
7793
|
+
},
|
|
7794
|
+
{
|
|
7795
|
+
id: "engine",
|
|
7796
|
+
name: "Engine / Motor",
|
|
7797
|
+
icon: "⚙️"
|
|
7798
|
+
},
|
|
7799
|
+
{
|
|
7800
|
+
id: "tools",
|
|
7801
|
+
name: "Tools / Construction",
|
|
7802
|
+
icon: "🔨"
|
|
7803
|
+
},
|
|
7804
|
+
{
|
|
7805
|
+
id: "silence",
|
|
7806
|
+
name: "Silence",
|
|
7807
|
+
icon: "🤫"
|
|
7808
|
+
}
|
|
7809
|
+
];
|
|
7600
7810
|
var YAMNET_TO_MACRO = {
|
|
7601
7811
|
mapping: {
|
|
7602
7812
|
Speech: "speech",
|
|
@@ -7863,6 +8073,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
7863
8073
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7864
8074
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
7865
8075
|
/**
|
|
8076
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8077
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8078
|
+
* icon }`.
|
|
8079
|
+
*
|
|
8080
|
+
* This dictionary folds together what used to be scattered across four
|
|
8081
|
+
* copies:
|
|
8082
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8083
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8084
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8085
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8086
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8087
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8088
|
+
*
|
|
8089
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8090
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8091
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8092
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8093
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8094
|
+
*
|
|
8095
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8096
|
+
*/
|
|
8097
|
+
var TAXONOMY_COLORS = {
|
|
8098
|
+
motion: "#f59e0b",
|
|
8099
|
+
audio: "#06b6d4",
|
|
8100
|
+
person: "#22c55e",
|
|
8101
|
+
vehicle: "#3b82f6",
|
|
8102
|
+
animal: "#f97316",
|
|
8103
|
+
package: "#a855f7",
|
|
8104
|
+
sensor: "#8b5cf6",
|
|
8105
|
+
control: "#10b981",
|
|
8106
|
+
genericDetection: "#64748b"
|
|
8107
|
+
};
|
|
8108
|
+
var DETECTION_SUB_COLORS = {
|
|
8109
|
+
car: "#f59e0b",
|
|
8110
|
+
truck: "#d97706",
|
|
8111
|
+
bus: "#b45309",
|
|
8112
|
+
motorcycle: "#eab308",
|
|
8113
|
+
bicycle: "#ca8a04",
|
|
8114
|
+
airplane: "#60a5fa",
|
|
8115
|
+
boat: "#2563eb",
|
|
8116
|
+
train: "#1d4ed8",
|
|
8117
|
+
bird: "#14b8a6",
|
|
8118
|
+
dog: "#84cc16",
|
|
8119
|
+
cat: "#f97316",
|
|
8120
|
+
horse: "#a16207",
|
|
8121
|
+
sheep: "#a3a3a3",
|
|
8122
|
+
cow: "#78716c",
|
|
8123
|
+
elephant: "#6b7280",
|
|
8124
|
+
bear: "#7c2d12",
|
|
8125
|
+
zebra: "#404040",
|
|
8126
|
+
giraffe: "#d4a373"
|
|
8127
|
+
};
|
|
8128
|
+
function titleCase(id) {
|
|
8129
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8130
|
+
}
|
|
8131
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8132
|
+
function macro(kind, category, color, iconId, label) {
|
|
8133
|
+
entries.set(kind, {
|
|
8134
|
+
kind,
|
|
8135
|
+
parentKind: null,
|
|
8136
|
+
level: "macro",
|
|
8137
|
+
category,
|
|
8138
|
+
color,
|
|
8139
|
+
iconId,
|
|
8140
|
+
labelKey: `eventKind.${kind}`,
|
|
8141
|
+
label
|
|
8142
|
+
});
|
|
8143
|
+
}
|
|
8144
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8145
|
+
entries.set(kind, {
|
|
8146
|
+
kind,
|
|
8147
|
+
parentKind,
|
|
8148
|
+
level: "sub",
|
|
8149
|
+
category,
|
|
8150
|
+
color,
|
|
8151
|
+
iconId,
|
|
8152
|
+
labelKey: `eventKind.${kind}`,
|
|
8153
|
+
label
|
|
8154
|
+
});
|
|
8155
|
+
}
|
|
8156
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8157
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8158
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8159
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8160
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8161
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8162
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8163
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8164
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8165
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8166
|
+
if (entries.has(cocoClass)) continue;
|
|
8167
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8168
|
+
}
|
|
8169
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8170
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8171
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8172
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8173
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8174
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8175
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8176
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8177
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8178
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8179
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8180
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8181
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8182
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8183
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8184
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8185
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8186
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8187
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8188
|
+
const kind = `audio-${l.id}`;
|
|
8189
|
+
if (entries.has(kind)) continue;
|
|
8190
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8191
|
+
}
|
|
8192
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8193
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8194
|
+
/**
|
|
7866
8195
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7867
8196
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
7868
8197
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -14817,9 +15146,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14817
15146
|
* `package` backs the package-drop detector — a package zone is a
|
|
14818
15147
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14819
15148
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14820
|
-
* The orchestrator provider
|
|
14821
|
-
*
|
|
14822
|
-
* consumers read
|
|
15149
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15150
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15151
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15152
|
+
* off `device.state.zoneRules.value.package`.
|
|
14823
15153
|
*/
|
|
14824
15154
|
runtimeState: object({
|
|
14825
15155
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -18811,17 +19141,30 @@ var EventKindCategorySchema = _enum([
|
|
|
18811
19141
|
"audio",
|
|
18812
19142
|
"detection",
|
|
18813
19143
|
"sensor",
|
|
19144
|
+
"control",
|
|
18814
19145
|
"custom",
|
|
18815
19146
|
"package"
|
|
18816
19147
|
]);
|
|
19148
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19149
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
18817
19150
|
var EventKindDescriptorSchema = object({
|
|
18818
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19151
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
18819
19152
|
kind: string(),
|
|
19153
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19154
|
+
labelKey: string(),
|
|
19155
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
18820
19156
|
label: string(),
|
|
18821
19157
|
/** Hex color for timeline/legend rendering. */
|
|
18822
19158
|
color: string(),
|
|
19159
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19160
|
+
iconId: string(),
|
|
19161
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
18823
19162
|
icon: EventKindIconSchema,
|
|
18824
19163
|
category: EventKindCategorySchema,
|
|
19164
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19165
|
+
parentKind: string().nullable(),
|
|
19166
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19167
|
+
level: EventKindLevelSchema,
|
|
18825
19168
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18826
19169
|
* itself; for sensor kinds the LINKED source device. */
|
|
18827
19170
|
source: object({
|
|
@@ -18894,11 +19237,21 @@ var TrackAudioLabelSchema = object({
|
|
|
18894
19237
|
firstAt: number(),
|
|
18895
19238
|
lastAt: number()
|
|
18896
19239
|
});
|
|
19240
|
+
/**
|
|
19241
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19242
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19243
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19244
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19245
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19246
|
+
*/
|
|
19247
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
18897
19248
|
var TrackSchema = object({
|
|
18898
19249
|
trackId: string(),
|
|
18899
19250
|
deviceId: number(),
|
|
18900
19251
|
className: string(),
|
|
18901
19252
|
label: string().optional(),
|
|
19253
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19254
|
+
source: TrackSourceSchema.optional(),
|
|
18902
19255
|
firstSeen: number(),
|
|
18903
19256
|
lastSeen: number(),
|
|
18904
19257
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19153,6 +19506,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19153
19506
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19154
19507
|
embeddings: number().int()
|
|
19155
19508
|
});
|
|
19509
|
+
/** Event-store footprint for one camera. */
|
|
19510
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19511
|
+
deviceId: number(),
|
|
19512
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19513
|
+
rows: number().int(),
|
|
19514
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19515
|
+
bytes: number().int()
|
|
19516
|
+
});
|
|
19517
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19518
|
+
var EventStoreFootprintSchema = object({
|
|
19519
|
+
totalRows: number().int(),
|
|
19520
|
+
totalBytes: number().int(),
|
|
19521
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19522
|
+
});
|
|
19523
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19524
|
+
var EventPruneCountsSchema = object({
|
|
19525
|
+
motion: number().int(),
|
|
19526
|
+
object: number().int(),
|
|
19527
|
+
audio: number().int()
|
|
19528
|
+
});
|
|
19156
19529
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19157
19530
|
deviceId: number(),
|
|
19158
19531
|
trackId: string()
|
|
@@ -19216,6 +19589,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19216
19589
|
}), {
|
|
19217
19590
|
kind: "mutation",
|
|
19218
19591
|
auth: "admin"
|
|
19592
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19593
|
+
kind: "query",
|
|
19594
|
+
auth: "admin"
|
|
19595
|
+
}), method(object({
|
|
19596
|
+
olderThanMs: number(),
|
|
19597
|
+
reason: OpsLogReasonSchema.optional()
|
|
19598
|
+
}), EventPruneCountsSchema, {
|
|
19599
|
+
kind: "mutation",
|
|
19600
|
+
auth: "admin"
|
|
19601
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19602
|
+
kind: "mutation",
|
|
19603
|
+
auth: "admin"
|
|
19604
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19605
|
+
kind: "query",
|
|
19606
|
+
auth: "admin"
|
|
19219
19607
|
}), method(object({
|
|
19220
19608
|
eventId: string(),
|
|
19221
19609
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19240,6 +19628,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19240
19628
|
eventId: string(),
|
|
19241
19629
|
timestamp: number()
|
|
19242
19630
|
});
|
|
19631
|
+
/**
|
|
19632
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19633
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19634
|
+
* caps into per-camera event-kind descriptors.
|
|
19635
|
+
*
|
|
19636
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19637
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19638
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19639
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19640
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19641
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19642
|
+
* eventful cap is missing.
|
|
19643
|
+
*/
|
|
19644
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19645
|
+
var LEGACY_ICON = {
|
|
19646
|
+
motion: "motion",
|
|
19647
|
+
audio: "audio",
|
|
19648
|
+
person: "person",
|
|
19649
|
+
vehicle: "vehicle",
|
|
19650
|
+
animal: "animal",
|
|
19651
|
+
package: "package",
|
|
19652
|
+
door: "door",
|
|
19653
|
+
pir: "pir",
|
|
19654
|
+
smoke: "smoke",
|
|
19655
|
+
water: "water",
|
|
19656
|
+
button: "button",
|
|
19657
|
+
generic: "generic",
|
|
19658
|
+
gas: "smoke",
|
|
19659
|
+
vibration: "generic",
|
|
19660
|
+
tamper: "generic",
|
|
19661
|
+
presence: "person",
|
|
19662
|
+
lock: "generic",
|
|
19663
|
+
siren: "generic",
|
|
19664
|
+
switch: "generic",
|
|
19665
|
+
doorbell: "button"
|
|
19666
|
+
};
|
|
19667
|
+
function legacyIcon(iconId) {
|
|
19668
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19669
|
+
}
|
|
19670
|
+
/**
|
|
19671
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19672
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19673
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19674
|
+
*/
|
|
19675
|
+
var CAP_TO_KIND = {
|
|
19676
|
+
contact: "contact",
|
|
19677
|
+
motion: "motion-sensor",
|
|
19678
|
+
smoke: "smoke",
|
|
19679
|
+
flood: "flood",
|
|
19680
|
+
gas: "gas",
|
|
19681
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19682
|
+
vibration: "vibration",
|
|
19683
|
+
tamper: "tamper",
|
|
19684
|
+
presence: "presence",
|
|
19685
|
+
"enum-sensor": "enum-sensor",
|
|
19686
|
+
"event-emitter": "device-event",
|
|
19687
|
+
"lock-control": "lock",
|
|
19688
|
+
switch: "switch",
|
|
19689
|
+
button: "button",
|
|
19690
|
+
doorbell: "doorbell"
|
|
19691
|
+
};
|
|
19692
|
+
function buildDescriptor(capName, kind) {
|
|
19693
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19694
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19695
|
+
return {
|
|
19696
|
+
...t,
|
|
19697
|
+
icon: legacyIcon(t.iconId)
|
|
19698
|
+
};
|
|
19699
|
+
}
|
|
19700
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19243
19701
|
var CameraPipelineConfigSchema = object({
|
|
19244
19702
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19245
19703
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22551,13 +23009,29 @@ method(object({
|
|
|
22551
23009
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22552
23010
|
kind: "mutation",
|
|
22553
23011
|
auth: "admin"
|
|
22554
|
-
}), method(object({
|
|
23012
|
+
}), method(object({
|
|
23013
|
+
deviceId: number(),
|
|
23014
|
+
reason: OpsLogReasonSchema.optional()
|
|
23015
|
+
}), object({
|
|
22555
23016
|
floorMs: number().nullable(),
|
|
22556
23017
|
deletedBuckets: number().int(),
|
|
22557
23018
|
reclaimedBytes: number().int()
|
|
22558
23019
|
}), {
|
|
22559
23020
|
kind: "mutation",
|
|
22560
23021
|
auth: "admin"
|
|
23022
|
+
}), method(object({
|
|
23023
|
+
deviceId: number(),
|
|
23024
|
+
fromMs: number().optional(),
|
|
23025
|
+
toMs: number().optional()
|
|
23026
|
+
}), object({
|
|
23027
|
+
deletedBuckets: number().int(),
|
|
23028
|
+
reclaimedBytes: number().int()
|
|
23029
|
+
}), {
|
|
23030
|
+
kind: "mutation",
|
|
23031
|
+
auth: "admin"
|
|
23032
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23033
|
+
kind: "query",
|
|
23034
|
+
auth: "admin"
|
|
22561
23035
|
});
|
|
22562
23036
|
/**
|
|
22563
23037
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -25692,6 +26166,12 @@ Object.freeze({
|
|
|
25692
26166
|
addonId: null,
|
|
25693
26167
|
access: "delete"
|
|
25694
26168
|
},
|
|
26169
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26170
|
+
capName: "pipeline-analytics",
|
|
26171
|
+
capScope: "device",
|
|
26172
|
+
addonId: null,
|
|
26173
|
+
access: "delete"
|
|
26174
|
+
},
|
|
25695
26175
|
"pipelineAnalytics.deleteTracks": {
|
|
25696
26176
|
capName: "pipeline-analytics",
|
|
25697
26177
|
capScope: "device",
|
|
@@ -25722,6 +26202,12 @@ Object.freeze({
|
|
|
25722
26202
|
addonId: null,
|
|
25723
26203
|
access: "view"
|
|
25724
26204
|
},
|
|
26205
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26206
|
+
capName: "pipeline-analytics",
|
|
26207
|
+
capScope: "device",
|
|
26208
|
+
addonId: null,
|
|
26209
|
+
access: "view"
|
|
26210
|
+
},
|
|
25725
26211
|
"pipelineAnalytics.getKeyEvents": {
|
|
25726
26212
|
capName: "pipeline-analytics",
|
|
25727
26213
|
capScope: "device",
|
|
@@ -25764,6 +26250,12 @@ Object.freeze({
|
|
|
25764
26250
|
addonId: null,
|
|
25765
26251
|
access: "view"
|
|
25766
26252
|
},
|
|
26253
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26254
|
+
capName: "pipeline-analytics",
|
|
26255
|
+
capScope: "device",
|
|
26256
|
+
addonId: null,
|
|
26257
|
+
access: "view"
|
|
26258
|
+
},
|
|
25767
26259
|
"pipelineAnalytics.listRecentTracks": {
|
|
25768
26260
|
capName: "pipeline-analytics",
|
|
25769
26261
|
capScope: "device",
|
|
@@ -25776,6 +26268,12 @@ Object.freeze({
|
|
|
25776
26268
|
addonId: null,
|
|
25777
26269
|
access: "view"
|
|
25778
26270
|
},
|
|
26271
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26272
|
+
capName: "pipeline-analytics",
|
|
26273
|
+
capScope: "device",
|
|
26274
|
+
addonId: null,
|
|
26275
|
+
access: "create"
|
|
26276
|
+
},
|
|
25779
26277
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25780
26278
|
capName: "pipeline-analytics",
|
|
25781
26279
|
capScope: "device",
|
|
@@ -26538,6 +27036,12 @@ Object.freeze({
|
|
|
26538
27036
|
addonId: null,
|
|
26539
27037
|
access: "create"
|
|
26540
27038
|
},
|
|
27039
|
+
"recording.deleteFootprint": {
|
|
27040
|
+
capName: "recording",
|
|
27041
|
+
capScope: "system",
|
|
27042
|
+
addonId: null,
|
|
27043
|
+
access: "delete"
|
|
27044
|
+
},
|
|
26541
27045
|
"recording.getAvailability": {
|
|
26542
27046
|
capName: "recording",
|
|
26543
27047
|
capScope: "system",
|
|
@@ -26568,6 +27072,12 @@ Object.freeze({
|
|
|
26568
27072
|
addonId: null,
|
|
26569
27073
|
access: "view"
|
|
26570
27074
|
},
|
|
27075
|
+
"recording.listOpsLog": {
|
|
27076
|
+
capName: "recording",
|
|
27077
|
+
capScope: "system",
|
|
27078
|
+
addonId: null,
|
|
27079
|
+
access: "view"
|
|
27080
|
+
},
|
|
26571
27081
|
"recording.locateSegment": {
|
|
26572
27082
|
capName: "recording",
|
|
26573
27083
|
capScope: "system",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-wyze",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|