@camstack/addon-provider-rademacher 0.2.98 → 0.2.100
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 +292 -58
- package/dist/addon.mjs +292 -58
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -984,7 +984,7 @@ var Rademacher = class {
|
|
|
984
984
|
}
|
|
985
985
|
};
|
|
986
986
|
//#endregion
|
|
987
|
-
//#region ../types/dist/event-category-
|
|
987
|
+
//#region ../types/dist/event-category-ZyX6jcse.mjs
|
|
988
988
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
989
989
|
EventCategory["SystemBoot"] = "system.boot";
|
|
990
990
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1545,7 +1545,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1545
1545
|
* a package zone — a newly-appeared stationary object of a package class
|
|
1546
1546
|
* that cleared the class / zone / dwell / size gates. Payload:
|
|
1547
1547
|
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
1548
|
-
* entryId, className, zoneIds,
|
|
1548
|
+
* entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
|
|
1549
1549
|
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
1550
1550
|
* this bus topic drives notifier rules + live UI. See
|
|
1551
1551
|
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
@@ -6331,7 +6331,7 @@ var ZodIssueCode = {
|
|
|
6331
6331
|
var ZodFirstPartyTypeKind;
|
|
6332
6332
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6333
6333
|
//#endregion
|
|
6334
|
-
//#region ../types/dist/sleep-
|
|
6334
|
+
//#region ../types/dist/sleep-DBKu2-U5.mjs
|
|
6335
6335
|
/**
|
|
6336
6336
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6337
6337
|
* window to float samples (D455).
|
|
@@ -8298,13 +8298,30 @@ new Set([
|
|
|
8298
8298
|
"scene",
|
|
8299
8299
|
"motion",
|
|
8300
8300
|
"object",
|
|
8301
|
-
"audio"
|
|
8301
|
+
"audio",
|
|
8302
|
+
"mosaic"
|
|
8302
8303
|
]);
|
|
8303
|
-
|
|
8304
|
+
/**
|
|
8305
|
+
* The owner types that are event tables, in the order the event-media resolver
|
|
8306
|
+
* should consider them. Exported so a consumer asking "is this key an event?"
|
|
8307
|
+
* does not re-spell the list and drift from it.
|
|
8308
|
+
*/
|
|
8309
|
+
var EVENT_OWNER_TYPES = [
|
|
8304
8310
|
"motion",
|
|
8305
8311
|
"object",
|
|
8306
8312
|
"audio"
|
|
8307
|
-
]
|
|
8313
|
+
];
|
|
8314
|
+
/**
|
|
8315
|
+
* The same list as a Zod enum, for the cap inputs that must NAME the table
|
|
8316
|
+
* (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
|
|
8317
|
+
* `(table, id)`).
|
|
8318
|
+
*
|
|
8319
|
+
* Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
|
|
8320
|
+
* table would otherwise be accepted by the codec and refused at the door, with
|
|
8321
|
+
* nothing failing until a caller asked.
|
|
8322
|
+
*/
|
|
8323
|
+
var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
8324
|
+
new Set(EVENT_OWNER_TYPES);
|
|
8308
8325
|
var EncodeProfileSchema = object({
|
|
8309
8326
|
video: object({
|
|
8310
8327
|
codec: _enum([
|
|
@@ -8343,7 +8360,23 @@ var EncodeProfileSchema = object({
|
|
|
8343
8360
|
"zerolatency",
|
|
8344
8361
|
"film",
|
|
8345
8362
|
"animation"
|
|
8346
|
-
]).optional()
|
|
8363
|
+
]).optional(),
|
|
8364
|
+
/**
|
|
8365
|
+
* ONE slice per access unit.
|
|
8366
|
+
*
|
|
8367
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
8368
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
8369
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
8370
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
8371
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
8372
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
8373
|
+
*
|
|
8374
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
8375
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
8376
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
8377
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
8378
|
+
*/
|
|
8379
|
+
singleSlicePerFrame: boolean().optional()
|
|
8347
8380
|
}),
|
|
8348
8381
|
audio: union([literal("passthrough"), object({
|
|
8349
8382
|
codec: _enum([
|
|
@@ -8393,7 +8426,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
8393
8426
|
audio: "passthrough"
|
|
8394
8427
|
};
|
|
8395
8428
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
8396
|
-
({ ...BASE_LIVE_EGRESS_PROFILE });
|
|
8429
|
+
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
8397
8430
|
/**
|
|
8398
8431
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
8399
8432
|
* every declared capability + widget of every installed plugin, on every
|
|
@@ -13503,6 +13536,16 @@ method(object({
|
|
|
13503
13536
|
filter: QueryFilterSchema.optional(),
|
|
13504
13537
|
columns: array(string()).readonly().optional()
|
|
13505
13538
|
}), array(SettingsRecordSchema).readonly()), method(object({
|
|
13539
|
+
namespace: string().optional(),
|
|
13540
|
+
collection: string(),
|
|
13541
|
+
/** Declared columns identifying the slot; must be covered by a UNIQUE
|
|
13542
|
+
* index on the collection. Never empty. */
|
|
13543
|
+
conflict: array(string()).readonly(),
|
|
13544
|
+
record: BulkRecordSchema
|
|
13545
|
+
}), object({
|
|
13546
|
+
/** The id the row HAS: assigned by SQLite on an insert, or the existing
|
|
13547
|
+
* row's own id on an update. */
|
|
13548
|
+
id: union([string(), number()]) }), { kind: "mutation" }), method(object({
|
|
13506
13549
|
namespace: string().optional(),
|
|
13507
13550
|
collection: string(),
|
|
13508
13551
|
record: object({
|
|
@@ -13637,6 +13680,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13637
13680
|
id: union([string(), number()]) }), {
|
|
13638
13681
|
kind: "mutation",
|
|
13639
13682
|
auth: "admin"
|
|
13683
|
+
}), method(object({
|
|
13684
|
+
namespace: string().optional(),
|
|
13685
|
+
collection: string(),
|
|
13686
|
+
conflict: array(string()).readonly(),
|
|
13687
|
+
record: BulkRecordSchema
|
|
13688
|
+
}), object({ id: union([string(), number()]) }), {
|
|
13689
|
+
kind: "mutation",
|
|
13690
|
+
auth: "admin"
|
|
13640
13691
|
}), method(object({
|
|
13641
13692
|
namespace: string().optional(),
|
|
13642
13693
|
collection: string(),
|
|
@@ -20119,8 +20170,8 @@ var TrackPositionSchema = object({
|
|
|
20119
20170
|
var TrackSnapshotSchema = object({
|
|
20120
20171
|
timestamp: number(),
|
|
20121
20172
|
position: TrackPositionSchema,
|
|
20122
|
-
/**
|
|
20123
|
-
|
|
20173
|
+
/** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
|
|
20174
|
+
mediaId: number().int()
|
|
20124
20175
|
});
|
|
20125
20176
|
/**
|
|
20126
20177
|
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
@@ -20724,14 +20775,14 @@ var ObjectEventSchema = object({
|
|
|
20724
20775
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
20725
20776
|
frameWidth: number().optional(),
|
|
20726
20777
|
frameHeight: number().optional(),
|
|
20727
|
-
/**
|
|
20728
|
-
|
|
20729
|
-
/** Design B:
|
|
20778
|
+
/** Media row id of the crop attached to this event (if any) — D482. */
|
|
20779
|
+
mediaId: number().int().optional(),
|
|
20780
|
+
/** Design B: media row id of the track's native-resolution key frame (the
|
|
20730
20781
|
* best-detection full frame). Resolve via the event-media data-plane
|
|
20731
|
-
* (`/addon/<addonId>/event-media/<
|
|
20782
|
+
* (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
|
|
20732
20783
|
* draws `bbox` over the native frame. Absent on legacy rows / non-decoded
|
|
20733
|
-
* sources — consumers fall back to `
|
|
20734
|
-
|
|
20784
|
+
* sources — consumers fall back to `mediaId` (the tight crop). */
|
|
20785
|
+
keyFrameMediaId: number().int().optional(),
|
|
20735
20786
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20736
20787
|
mediaUrl: string().optional(),
|
|
20737
20788
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
@@ -20781,7 +20832,7 @@ var MediaFileKindEnum = _enum([
|
|
|
20781
20832
|
* hub-main's heap on the way past — for an `<img>` that would have cached it.
|
|
20782
20833
|
*
|
|
20783
20834
|
* `url` points at the `event-media` data plane
|
|
20784
|
-
* (`/addon/<addonId>/event-media/<
|
|
20835
|
+
* (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
|
|
20785
20836
|
* with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
|
|
20786
20837
|
* render a `?variant=thumb`, and streams. The hub gate in front of it requires
|
|
20787
20838
|
* a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
|
|
@@ -20789,10 +20840,13 @@ var MediaFileKindEnum = _enum([
|
|
|
20789
20840
|
* `data-plane-access.ts` for the rule and the one gap it does not close
|
|
20790
20841
|
* (per-device scoping).
|
|
20791
20842
|
*
|
|
20792
|
-
* The URL is built from the row's
|
|
20793
|
-
*
|
|
20843
|
+
* The URL is built from the row's own id, which since D482 says nothing about
|
|
20844
|
+
* the row's owner or kind — and that is the point. The published `kind` is not
|
|
20845
|
+
* the stored one (a track's face/plate crop is stored as `crop` under
|
|
20794
20846
|
* `('face'|'plate', '<prefix>-<trackId>')` and published as
|
|
20795
|
-
* `faceCrop`/`plateCrop
|
|
20847
|
+
* `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
|
|
20848
|
+
* taken from `row.key` verbatim or it 404'd exactly those two rows. An id
|
|
20849
|
+
* cannot be mis-reconstructed, because there is nothing in it to reconstruct.
|
|
20796
20850
|
*
|
|
20797
20851
|
* ## `base64` is TRANSITIONAL and is going away
|
|
20798
20852
|
*
|
|
@@ -20805,7 +20859,19 @@ var MediaFileKindEnum = _enum([
|
|
|
20805
20859
|
* `analytics-query-facade.ts`; nothing else reads it.
|
|
20806
20860
|
*/
|
|
20807
20861
|
var MediaFileSchema = object({
|
|
20808
|
-
|
|
20862
|
+
/**
|
|
20863
|
+
* The media row's OWN id — the rowid SQLite assigned it (D482).
|
|
20864
|
+
*
|
|
20865
|
+
* It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
|
|
20866
|
+
* [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
|
|
20867
|
+
* per-table rowid aliases, so `object:101314` and `motion:101314` are two
|
|
20868
|
+
* different rows that spell the same number, and a track whose
|
|
20869
|
+
* `bestEventId` was an object event was served a motion event's snapshot —
|
|
20870
|
+
* a night-time thumbnail on an afternoon track, with no error anywhere. A
|
|
20871
|
+
* surrogate id cannot name the wrong row's owner, because it names no owner
|
|
20872
|
+
* at all.
|
|
20873
|
+
*/
|
|
20874
|
+
mediaId: number().int(),
|
|
20809
20875
|
kind: MediaFileKindEnum,
|
|
20810
20876
|
sizeBytes: number(),
|
|
20811
20877
|
timestamp: number()
|
|
@@ -20913,7 +20979,7 @@ var RetrainTrackSchema = object({
|
|
|
20913
20979
|
});
|
|
20914
20980
|
/** A frame the picker may offer — an index row, no blob was read to produce it. */
|
|
20915
20981
|
var RetrainFrameCandidateSchema = object({
|
|
20916
|
-
|
|
20982
|
+
mediaId: number().int(),
|
|
20917
20983
|
kind: MediaFileKindEnum,
|
|
20918
20984
|
timestamp: number(),
|
|
20919
20985
|
sizeBytes: number().int(),
|
|
@@ -20927,7 +20993,7 @@ var RetrainFrameSchema = object({
|
|
|
20927
20993
|
deviceId: number(),
|
|
20928
20994
|
trackId: string(),
|
|
20929
20995
|
/** Provenance only. It may already point at nothing — that is expected. */
|
|
20930
|
-
|
|
20996
|
+
sourceMediaId: number().int(),
|
|
20931
20997
|
sourceKind: MediaFileKindEnum,
|
|
20932
20998
|
sizeBytes: number().int(),
|
|
20933
20999
|
width: number().int(),
|
|
@@ -20943,7 +21009,7 @@ var RetrainCopyRefusalSchema = _enum([
|
|
|
20943
21009
|
var RetrainFrameSelectionSchema = object({
|
|
20944
21010
|
copied: array(RetrainFrameSchema).readonly(),
|
|
20945
21011
|
refused: array(object({
|
|
20946
|
-
|
|
21012
|
+
sourceMediaId: number().int(),
|
|
20947
21013
|
reason: RetrainCopyRefusalSchema
|
|
20948
21014
|
})).readonly()
|
|
20949
21015
|
});
|
|
@@ -20951,7 +21017,7 @@ var RetrainFrameListSchema = object({
|
|
|
20951
21017
|
candidates: array(RetrainFrameCandidateSchema).readonly(),
|
|
20952
21018
|
copies: array(RetrainFrameSchema).readonly(),
|
|
20953
21019
|
/** What the page pre-selects — the native key frame when one survives. */
|
|
20954
|
-
|
|
21020
|
+
autoPickMediaId: number().int().optional()
|
|
20955
21021
|
});
|
|
20956
21022
|
/** What the operator asked the assist to look for. */
|
|
20957
21023
|
var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
|
|
@@ -21046,9 +21112,11 @@ var RecentTracksQueryInput = object({
|
|
|
21046
21112
|
});
|
|
21047
21113
|
/**
|
|
21048
21114
|
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21049
|
-
* `
|
|
21050
|
-
* served by the event-media plane
|
|
21051
|
-
* member visible has been materialised
|
|
21115
|
+
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21116
|
+
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21117
|
+
* first frame with a member visible has been materialised (D482 — it was the
|
|
21118
|
+
* row's composite key, which embedded the owner and could name another table's
|
|
21119
|
+
* row once event ids became per-table rowids).
|
|
21052
21120
|
*/
|
|
21053
21121
|
var SummarySchema = object({
|
|
21054
21122
|
id: string(),
|
|
@@ -21057,19 +21125,115 @@ var SummarySchema = object({
|
|
|
21057
21125
|
lastActiveAt: number(),
|
|
21058
21126
|
sealedAt: number().nullable(),
|
|
21059
21127
|
memberCount: number().int().nonnegative(),
|
|
21060
|
-
|
|
21128
|
+
groupShotMediaId: number().int().nullable()
|
|
21061
21129
|
});
|
|
21062
21130
|
var SummariesQueryInput = object({
|
|
21063
21131
|
deviceIds: array(number()).min(1),
|
|
21064
21132
|
since: number().optional(),
|
|
21065
21133
|
until: number().optional(),
|
|
21066
|
-
limit: number().int().min(1).max(200).default(50)
|
|
21134
|
+
limit: number().int().min(1).max(200).default(50),
|
|
21135
|
+
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21136
|
+
* meaning of "dog" on every summary surface. */
|
|
21137
|
+
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21067
21138
|
});
|
|
21068
|
-
var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
|
|
21069
21139
|
var SummaryDetailSchema = object({
|
|
21070
21140
|
summary: SummarySchema,
|
|
21071
|
-
/**
|
|
21072
|
-
|
|
21141
|
+
/** Members in absorption order, oldest join first. */
|
|
21142
|
+
members: array(object({
|
|
21143
|
+
trackId: string(),
|
|
21144
|
+
/**
|
|
21145
|
+
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21146
|
+
* and the track no longer exists to fill it.
|
|
21147
|
+
*
|
|
21148
|
+
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21149
|
+
* class afterwards, and a group's composition is the history of who came
|
|
21150
|
+
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21151
|
+
* dog" — rather than being handed a second, denormalised tally that would
|
|
21152
|
+
* drift from the members it claims to describe.
|
|
21153
|
+
*/
|
|
21154
|
+
className: string().nullable(),
|
|
21155
|
+
/** `primary` is the one member that carries the group's identity. */
|
|
21156
|
+
role: _enum([
|
|
21157
|
+
"primary",
|
|
21158
|
+
"sibling",
|
|
21159
|
+
"child"
|
|
21160
|
+
]).nullable(),
|
|
21161
|
+
joinedAt: number(),
|
|
21162
|
+
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21163
|
+
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21164
|
+
label: string().optional(),
|
|
21165
|
+
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21166
|
+
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21167
|
+
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21168
|
+
subLabel: string().optional()
|
|
21169
|
+
})).readonly()
|
|
21170
|
+
});
|
|
21171
|
+
/**
|
|
21172
|
+
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21173
|
+
*
|
|
21174
|
+
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21175
|
+
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21176
|
+
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21177
|
+
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21178
|
+
* can count them turns a page of two hundred groups into a thousand records to
|
|
21179
|
+
* draw two hundred badges.
|
|
21180
|
+
*/
|
|
21181
|
+
var SummaryListItemSchema = object({
|
|
21182
|
+
summary: SummarySchema,
|
|
21183
|
+
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21184
|
+
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21185
|
+
classes: array(object({
|
|
21186
|
+
className: string().nullable(),
|
|
21187
|
+
count: number().int().positive()
|
|
21188
|
+
})).readonly()
|
|
21189
|
+
});
|
|
21190
|
+
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21191
|
+
/**
|
|
21192
|
+
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21193
|
+
*
|
|
21194
|
+
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21195
|
+
* summaries feed that could only answer "the last N for these cameras"
|
|
21196
|
+
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21197
|
+
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21198
|
+
* "newest" means, on one screen.
|
|
21199
|
+
*/
|
|
21200
|
+
var RecentSummariesQueryInput = object({
|
|
21201
|
+
/** Devices to merge. An empty array yields an empty page. */
|
|
21202
|
+
deviceIds: array(number()),
|
|
21203
|
+
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21204
|
+
since: number().optional(),
|
|
21205
|
+
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21206
|
+
until: number().optional(),
|
|
21207
|
+
limit: number().int().min(1).max(500).default(100),
|
|
21208
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21209
|
+
cursor: string().optional(),
|
|
21210
|
+
/**
|
|
21211
|
+
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21212
|
+
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21213
|
+
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21214
|
+
* make the operator's one filter component produce two shapes.
|
|
21215
|
+
*
|
|
21216
|
+
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21217
|
+
* me the arrivals with a dog" has to return the group of four people who had
|
|
21218
|
+
* one with them; a filter on the group's own fields could only ever answer
|
|
21219
|
+
* about its primary.
|
|
21220
|
+
*
|
|
21221
|
+
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21222
|
+
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21223
|
+
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21224
|
+
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21225
|
+
* that read only the class would answer "animal" and never "dog".
|
|
21226
|
+
*
|
|
21227
|
+
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21228
|
+
*/
|
|
21229
|
+
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21230
|
+
});
|
|
21231
|
+
var RecentSummariesPageSchema = object({
|
|
21232
|
+
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21233
|
+
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21234
|
+
* whichever feed drew it. */
|
|
21235
|
+
summaries: array(SummaryListItemSchema).readonly(),
|
|
21236
|
+
nextCursor: string().nullable()
|
|
21073
21237
|
});
|
|
21074
21238
|
var RecentTracksPageSchema = object({
|
|
21075
21239
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
@@ -21483,7 +21647,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21483
21647
|
classes: array(string()).optional(),
|
|
21484
21648
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21485
21649
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21486
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
21650
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(RecentSummariesQueryInput, RecentSummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
21487
21651
|
kind: "mutation",
|
|
21488
21652
|
auth: "admin"
|
|
21489
21653
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -21611,7 +21775,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21611
21775
|
}), method(object({
|
|
21612
21776
|
deviceId: number(),
|
|
21613
21777
|
trackId: string(),
|
|
21614
|
-
|
|
21778
|
+
mediaIds: array(number().int()).min(1)
|
|
21615
21779
|
}), RetrainFrameSelectionSchema, {
|
|
21616
21780
|
kind: "mutation",
|
|
21617
21781
|
auth: "admin"
|
|
@@ -21679,7 +21843,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21679
21843
|
kind: "query",
|
|
21680
21844
|
auth: "admin"
|
|
21681
21845
|
}), method(object({
|
|
21682
|
-
|
|
21846
|
+
/** Which of the three event tables owns the row. */
|
|
21847
|
+
ownerType: EventOwnerTypeSchema,
|
|
21848
|
+
/** The event's rowid in that table (D474: an event id is a number). */
|
|
21849
|
+
eventId: number().int(),
|
|
21683
21850
|
kind: MediaFileKindEnum.optional(),
|
|
21684
21851
|
deviceId: number()
|
|
21685
21852
|
}), array(MediaFileSchema).readonly()), method(object({
|
|
@@ -21690,7 +21857,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21690
21857
|
trackId: string(),
|
|
21691
21858
|
deviceId: number()
|
|
21692
21859
|
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21693
|
-
|
|
21860
|
+
ownerType: EventOwnerTypeSchema,
|
|
21861
|
+
eventId: number().int(),
|
|
21694
21862
|
deviceId: number()
|
|
21695
21863
|
}), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
|
|
21696
21864
|
kind: "mutation",
|
|
@@ -26883,8 +27051,8 @@ var IdentitySchema = object({
|
|
|
26883
27051
|
id: string(),
|
|
26884
27052
|
name: string(),
|
|
26885
27053
|
sampleCount: number().int().nonnegative(),
|
|
26886
|
-
|
|
26887
|
-
/** Inline base64 of the cover sample's crop, resolved from `
|
|
27054
|
+
coverMediaId: number().int().optional(),
|
|
27055
|
+
/** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
|
|
26888
27056
|
* Lets the UI render the person's face avatar instead of a placeholder icon. */
|
|
26889
27057
|
coverBase64: string().optional()
|
|
26890
27058
|
});
|
|
@@ -26910,8 +27078,8 @@ var IdentitySampleAuditRowSchema = object({
|
|
|
26910
27078
|
enrolledAt: number().int(),
|
|
26911
27079
|
deviceId: number().int().optional(),
|
|
26912
27080
|
source: _enum(["detected", "photo"]),
|
|
26913
|
-
/** The enrolled crop's media
|
|
26914
|
-
|
|
27081
|
+
/** The enrolled crop's media row id, so the panel can show the evidence. */
|
|
27082
|
+
mediaId: number().int().optional(),
|
|
26915
27083
|
/**
|
|
26916
27084
|
* False = the sample is stamped with a DIFFERENT face model, and a cosine
|
|
26917
27085
|
* across feature spaces is a well-formed float with no meaning. Every number
|
|
@@ -26980,15 +27148,15 @@ var FaceInfoSchema = object({
|
|
|
26980
27148
|
*/
|
|
26981
27149
|
cropUrl: string().optional(),
|
|
26982
27150
|
/** Design B: the face bbox (pixel space) on the key frame — lets a detail
|
|
26983
|
-
* view draw the box over the native `
|
|
27151
|
+
* view draw the box over the native `keyFrameMediaId` frame. Absent on
|
|
26984
27152
|
* legacy rows written before design B. */
|
|
26985
27153
|
faceBbox: BoundingBoxSchema.optional(),
|
|
26986
27154
|
/** Design B: MediaStore key of the track's native-resolution key frame.
|
|
26987
27155
|
* Fetch the native JPEG via the event-media data-plane
|
|
26988
|
-
* (`/addon/<addonId>/event-media/<
|
|
27156
|
+
* (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
|
|
26989
27157
|
* track produced no key frame (e.g. native/onboard source) — the UI falls
|
|
26990
27158
|
* back to the inline `base64` face crop. */
|
|
26991
|
-
|
|
27159
|
+
keyFrameMediaId: number().int().optional(),
|
|
26992
27160
|
/** Winning identity-match cosine (0..1) for this face's track, when an
|
|
26993
27161
|
* identity was auto-confirmed. Lets the UI surface WHY a face was assigned
|
|
26994
27162
|
* (confidence badge / low-confidence audit). Absent on legacy rows and on
|
|
@@ -27057,11 +27225,14 @@ var FaceClusterSchema = object({
|
|
|
27057
27225
|
* `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
|
|
27058
27226
|
* dialog already rendering its key FRAME from the `event-media` plane.
|
|
27059
27227
|
*
|
|
27060
|
-
* `url` is `/addon/<addonId>/event-media/<
|
|
27061
|
-
* media
|
|
27228
|
+
* `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
|
|
27229
|
+
* resolves a media row by its own id, so this needed no new plane and no new
|
|
27230
|
+
* access decision.
|
|
27062
27231
|
*/
|
|
27063
27232
|
var MediaFileLiteSchema$1 = object({
|
|
27064
|
-
|
|
27233
|
+
/** The media row's own id — the same address `MediaFileRef.mediaId` carries
|
|
27234
|
+
* (D482). It was the row's composite key, which embedded the owner. */
|
|
27235
|
+
mediaId: number().int(),
|
|
27065
27236
|
kind: string(),
|
|
27066
27237
|
url: string(),
|
|
27067
27238
|
sizeBytes: number(),
|
|
@@ -27078,7 +27249,7 @@ method(object({
|
|
|
27078
27249
|
* covers inline, ~10 KB of base64 per row, on a query this UI mounts
|
|
27079
27250
|
* four times and the viewer holds at `staleTime: 30_000`.
|
|
27080
27251
|
*
|
|
27081
|
-
* Nothing loses its avatar: `
|
|
27252
|
+
* Nothing loses its avatar: `coverMediaId` is already on every row and
|
|
27082
27253
|
* the `event-media` plane serves that key `immutable` with an ETag.
|
|
27083
27254
|
*
|
|
27084
27255
|
* **This is an INPUT field, so it does not reach the addon until the
|
|
@@ -30441,8 +30612,8 @@ var VehicleSchema = object({
|
|
|
30441
30612
|
id: string(),
|
|
30442
30613
|
name: string(),
|
|
30443
30614
|
sampleCount: number().int().nonnegative(),
|
|
30444
|
-
|
|
30445
|
-
/** Inline base64 of the cover sample's plate crop, resolved from `
|
|
30615
|
+
coverMediaId: number().int().optional(),
|
|
30616
|
+
/** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
|
|
30446
30617
|
coverBase64: string().optional()
|
|
30447
30618
|
});
|
|
30448
30619
|
var VehicleSampleInfoSchema = object({
|
|
@@ -30475,7 +30646,7 @@ var PlateInfoSchema = object({
|
|
|
30475
30646
|
/** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
|
|
30476
30647
|
plateBbox: BoundingBoxSchema.optional(),
|
|
30477
30648
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
30478
|
-
|
|
30649
|
+
keyFrameMediaId: number().int().optional(),
|
|
30479
30650
|
base64: string().optional(),
|
|
30480
30651
|
/**
|
|
30481
30652
|
* Same crop as a data-plane URL, always present when the plate has a stored
|
|
@@ -30496,11 +30667,14 @@ var PlateInfoSchema = object({
|
|
|
30496
30667
|
* `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
|
|
30497
30668
|
* dialog already rendering its key FRAME from the `event-media` plane.
|
|
30498
30669
|
*
|
|
30499
|
-
* `url` is `/addon/<addonId>/event-media/<
|
|
30500
|
-
* media
|
|
30670
|
+
* `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
|
|
30671
|
+
* resolves a media row by its own id, so this needed no new plane and no new
|
|
30672
|
+
* access decision.
|
|
30501
30673
|
*/
|
|
30502
30674
|
var MediaFileLiteSchema = object({
|
|
30503
|
-
|
|
30675
|
+
/** The media row's own id — the same address `MediaFileRef.mediaId` carries
|
|
30676
|
+
* (D482). It was the row's composite key, which embedded the owner. */
|
|
30677
|
+
mediaId: number().int(),
|
|
30504
30678
|
kind: string(),
|
|
30505
30679
|
url: string(),
|
|
30506
30680
|
sizeBytes: number(),
|
|
@@ -30559,7 +30733,7 @@ method(object({
|
|
|
30559
30733
|
}), method(object({
|
|
30560
30734
|
/** Inline {@link VehicleSchema.coverBase64} on every row. Default
|
|
30561
30735
|
* `false` — the vehicle twin of `faceGallery.listIdentities`'s
|
|
30562
|
-
* option; `
|
|
30736
|
+
* option; `coverMediaId` + the `event-media` plane carry the picture.
|
|
30563
30737
|
* INPUT field: stripped by the hub router until the train ships, which
|
|
30564
30738
|
* resolves to `false` and is exactly the intended default. */
|
|
30565
30739
|
includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
|
|
@@ -32128,7 +32302,14 @@ var SceneReferenceSchema = object({
|
|
|
32128
32302
|
modelId: string(),
|
|
32129
32303
|
condition: SceneConditionSchema,
|
|
32130
32304
|
capturedAt: number(),
|
|
32131
|
-
|
|
32305
|
+
/**
|
|
32306
|
+
* The reference thumbnail's media ROW id (D482).
|
|
32307
|
+
*
|
|
32308
|
+
* The name already said `mediaId` while the value was the row's composite
|
|
32309
|
+
* key — a leftover that read as done and was not. It is the row's own id
|
|
32310
|
+
* now, addressed at `/addon/<addonId>/event-media/m/<id>`.
|
|
32311
|
+
*/
|
|
32312
|
+
thumbnailMediaId: number().int().optional(),
|
|
32132
32313
|
/** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
|
|
32133
32314
|
* anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
|
|
32134
32315
|
* normalized rect frame a different piece of world, and the scene would
|
|
@@ -33219,7 +33400,29 @@ var LoggingSettingsPatchSchema = object({
|
|
|
33219
33400
|
* disarmed the channels it did not mention would make the Levels page and
|
|
33220
33401
|
* the Diagnostics page fight over the same value.
|
|
33221
33402
|
*/
|
|
33222
|
-
channels: array(LogChannelWindowPatchSchema).readonly().optional()
|
|
33403
|
+
channels: array(LogChannelWindowPatchSchema).readonly().optional(),
|
|
33404
|
+
/**
|
|
33405
|
+
* How many days the analytics OPS LOG is kept — the audit trail of what
|
|
33406
|
+
* retention actually deleted.
|
|
33407
|
+
*
|
|
33408
|
+
* It lives HERE, on the logging document, and not on the analytics addon's
|
|
33409
|
+
* settings form, on the operator's instruction: every other log-ish window in
|
|
33410
|
+
* this system is configured through this one document, and a retention audit
|
|
33411
|
+
* configured somewhere else is a second place to look when the question is
|
|
33412
|
+
* "what happened to my data".
|
|
33413
|
+
*
|
|
33414
|
+
* That placement has a cost worth stating: this document ships in the
|
|
33415
|
+
* framework closure, so this knob needs a published `@camstack/server` while
|
|
33416
|
+
* the four windows beside it (D485) reach a node on `camstack deploy`.
|
|
33417
|
+
*
|
|
33418
|
+
* `retention-model.ts` argued this one must NOT follow a device window,
|
|
33419
|
+
* because the audit trail is the history of the SWEEP and not of the camera.
|
|
33420
|
+
* That argument stands and is untouched — what changes is that 30 days stops
|
|
33421
|
+
* being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
|
|
33422
|
+
* rather than 0-as-delete: an audit log truncated to nothing is precisely the
|
|
33423
|
+
* state in which the next 9.5 GiB leak cannot be explained.
|
|
33424
|
+
*/
|
|
33425
|
+
opsLogRetentionDays: number().int().min(0).max(3650).optional()
|
|
33223
33426
|
});
|
|
33224
33427
|
/**
|
|
33225
33428
|
* Which LAYER of the hierarchy is addressed. Absent = the cluster layer.
|
|
@@ -33292,6 +33495,14 @@ var LoggingSettingsStateSchema = object({
|
|
|
33292
33495
|
channels: array(LogChannelDescriptorSchema).readonly(),
|
|
33293
33496
|
/** The channels ARMED right now, each with its deadline. */
|
|
33294
33497
|
activeChannels: array(LogChannelWindowStateSchema).readonly(),
|
|
33498
|
+
/**
|
|
33499
|
+
* The ops-log window in days, as it is in force. `0` = kept forever.
|
|
33500
|
+
*
|
|
33501
|
+
* Reported rather than left to the caller's memory of what it wrote: this is
|
|
33502
|
+
* the value the analytics sweep will actually use, and an operator asking how
|
|
33503
|
+
* long their audit trail lives should not have to infer it from a default.
|
|
33504
|
+
*/
|
|
33505
|
+
opsLogRetentionDays: number().int().min(0),
|
|
33295
33506
|
persisted: boolean()
|
|
33296
33507
|
});
|
|
33297
33508
|
method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
@@ -34112,7 +34323,7 @@ var StationaryObjectSchema = object({
|
|
|
34112
34323
|
/** Enrichment label carried from the source track (identity / plate). */
|
|
34113
34324
|
label: string().optional(),
|
|
34114
34325
|
/** Native-resolution key-frame media key for the parked object's best image. */
|
|
34115
|
-
|
|
34326
|
+
keyFrameMediaId: number().int().optional()
|
|
34116
34327
|
});
|
|
34117
34328
|
var CameraOccupancySnapshotSchema = object({
|
|
34118
34329
|
/** Frame timestamp of the inference result that produced this snapshot. */
|
|
@@ -36850,6 +37061,12 @@ Object.freeze({
|
|
|
36850
37061
|
addonId: null,
|
|
36851
37062
|
access: "create"
|
|
36852
37063
|
},
|
|
37064
|
+
"dataStoreProvider.upsert": {
|
|
37065
|
+
capName: "data-store-provider",
|
|
37066
|
+
capScope: "system",
|
|
37067
|
+
addonId: null,
|
|
37068
|
+
access: "create"
|
|
37069
|
+
},
|
|
36853
37070
|
"dayNight.getOptions": {
|
|
36854
37071
|
capName: "day-night",
|
|
36855
37072
|
capScope: "device",
|
|
@@ -39286,6 +39503,12 @@ Object.freeze({
|
|
|
39286
39503
|
addonId: null,
|
|
39287
39504
|
access: "view"
|
|
39288
39505
|
},
|
|
39506
|
+
"pipelineAnalytics.listRecentSummaries": {
|
|
39507
|
+
capName: "pipeline-analytics",
|
|
39508
|
+
capScope: "device",
|
|
39509
|
+
addonId: null,
|
|
39510
|
+
access: "view"
|
|
39511
|
+
},
|
|
39289
39512
|
"pipelineAnalytics.listRecentTracks": {
|
|
39290
39513
|
capName: "pipeline-analytics",
|
|
39291
39514
|
capScope: "device",
|
|
@@ -40714,6 +40937,12 @@ Object.freeze({
|
|
|
40714
40937
|
addonId: null,
|
|
40715
40938
|
access: "create"
|
|
40716
40939
|
},
|
|
40940
|
+
"settingsStore.upsert": {
|
|
40941
|
+
capName: "settings-store",
|
|
40942
|
+
capScope: "system",
|
|
40943
|
+
addonId: null,
|
|
40944
|
+
access: "create"
|
|
40945
|
+
},
|
|
40717
40946
|
"smtpProvider.getStatus": {
|
|
40718
40947
|
capName: "smtp-provider",
|
|
40719
40948
|
capScope: "system",
|
|
@@ -43107,6 +43336,11 @@ Object.freeze({
|
|
|
43107
43336
|
form: "single",
|
|
43108
43337
|
optional: true
|
|
43109
43338
|
}],
|
|
43339
|
+
"pipelineAnalytics.listRecentSummaries": [{
|
|
43340
|
+
name: "deviceIds",
|
|
43341
|
+
form: "array",
|
|
43342
|
+
optional: false
|
|
43343
|
+
}],
|
|
43110
43344
|
"pipelineAnalytics.listRecentTracks": [{
|
|
43111
43345
|
name: "deviceIds",
|
|
43112
43346
|
form: "array",
|
package/dist/addon.mjs
CHANGED
|
@@ -983,7 +983,7 @@ var Rademacher = class {
|
|
|
983
983
|
}
|
|
984
984
|
};
|
|
985
985
|
//#endregion
|
|
986
|
-
//#region ../types/dist/event-category-
|
|
986
|
+
//#region ../types/dist/event-category-ZyX6jcse.mjs
|
|
987
987
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
988
988
|
EventCategory["SystemBoot"] = "system.boot";
|
|
989
989
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1544,7 +1544,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1544
1544
|
* a package zone — a newly-appeared stationary object of a package class
|
|
1545
1545
|
* that cleared the class / zone / dwell / size gates. Payload:
|
|
1546
1546
|
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
1547
|
-
* entryId, className, zoneIds,
|
|
1547
|
+
* entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
|
|
1548
1548
|
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
1549
1549
|
* this bus topic drives notifier rules + live UI. See
|
|
1550
1550
|
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
@@ -6330,7 +6330,7 @@ var ZodIssueCode = {
|
|
|
6330
6330
|
var ZodFirstPartyTypeKind;
|
|
6331
6331
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6332
6332
|
//#endregion
|
|
6333
|
-
//#region ../types/dist/sleep-
|
|
6333
|
+
//#region ../types/dist/sleep-DBKu2-U5.mjs
|
|
6334
6334
|
/**
|
|
6335
6335
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6336
6336
|
* window to float samples (D455).
|
|
@@ -8297,13 +8297,30 @@ new Set([
|
|
|
8297
8297
|
"scene",
|
|
8298
8298
|
"motion",
|
|
8299
8299
|
"object",
|
|
8300
|
-
"audio"
|
|
8300
|
+
"audio",
|
|
8301
|
+
"mosaic"
|
|
8301
8302
|
]);
|
|
8302
|
-
|
|
8303
|
+
/**
|
|
8304
|
+
* The owner types that are event tables, in the order the event-media resolver
|
|
8305
|
+
* should consider them. Exported so a consumer asking "is this key an event?"
|
|
8306
|
+
* does not re-spell the list and drift from it.
|
|
8307
|
+
*/
|
|
8308
|
+
var EVENT_OWNER_TYPES = [
|
|
8303
8309
|
"motion",
|
|
8304
8310
|
"object",
|
|
8305
8311
|
"audio"
|
|
8306
|
-
]
|
|
8312
|
+
];
|
|
8313
|
+
/**
|
|
8314
|
+
* The same list as a Zod enum, for the cap inputs that must NAME the table
|
|
8315
|
+
* (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
|
|
8316
|
+
* `(table, id)`).
|
|
8317
|
+
*
|
|
8318
|
+
* Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
|
|
8319
|
+
* table would otherwise be accepted by the codec and refused at the door, with
|
|
8320
|
+
* nothing failing until a caller asked.
|
|
8321
|
+
*/
|
|
8322
|
+
var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
8323
|
+
new Set(EVENT_OWNER_TYPES);
|
|
8307
8324
|
var EncodeProfileSchema = object({
|
|
8308
8325
|
video: object({
|
|
8309
8326
|
codec: _enum([
|
|
@@ -8342,7 +8359,23 @@ var EncodeProfileSchema = object({
|
|
|
8342
8359
|
"zerolatency",
|
|
8343
8360
|
"film",
|
|
8344
8361
|
"animation"
|
|
8345
|
-
]).optional()
|
|
8362
|
+
]).optional(),
|
|
8363
|
+
/**
|
|
8364
|
+
* ONE slice per access unit.
|
|
8365
|
+
*
|
|
8366
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
8367
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
8368
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
8369
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
8370
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
8371
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
8372
|
+
*
|
|
8373
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
8374
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
8375
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
8376
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
8377
|
+
*/
|
|
8378
|
+
singleSlicePerFrame: boolean().optional()
|
|
8346
8379
|
}),
|
|
8347
8380
|
audio: union([literal("passthrough"), object({
|
|
8348
8381
|
codec: _enum([
|
|
@@ -8392,7 +8425,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
8392
8425
|
audio: "passthrough"
|
|
8393
8426
|
};
|
|
8394
8427
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
8395
|
-
({ ...BASE_LIVE_EGRESS_PROFILE });
|
|
8428
|
+
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
8396
8429
|
/**
|
|
8397
8430
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
8398
8431
|
* every declared capability + widget of every installed plugin, on every
|
|
@@ -13502,6 +13535,16 @@ method(object({
|
|
|
13502
13535
|
filter: QueryFilterSchema.optional(),
|
|
13503
13536
|
columns: array(string()).readonly().optional()
|
|
13504
13537
|
}), array(SettingsRecordSchema).readonly()), method(object({
|
|
13538
|
+
namespace: string().optional(),
|
|
13539
|
+
collection: string(),
|
|
13540
|
+
/** Declared columns identifying the slot; must be covered by a UNIQUE
|
|
13541
|
+
* index on the collection. Never empty. */
|
|
13542
|
+
conflict: array(string()).readonly(),
|
|
13543
|
+
record: BulkRecordSchema
|
|
13544
|
+
}), object({
|
|
13545
|
+
/** The id the row HAS: assigned by SQLite on an insert, or the existing
|
|
13546
|
+
* row's own id on an update. */
|
|
13547
|
+
id: union([string(), number()]) }), { kind: "mutation" }), method(object({
|
|
13505
13548
|
namespace: string().optional(),
|
|
13506
13549
|
collection: string(),
|
|
13507
13550
|
record: object({
|
|
@@ -13636,6 +13679,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13636
13679
|
id: union([string(), number()]) }), {
|
|
13637
13680
|
kind: "mutation",
|
|
13638
13681
|
auth: "admin"
|
|
13682
|
+
}), method(object({
|
|
13683
|
+
namespace: string().optional(),
|
|
13684
|
+
collection: string(),
|
|
13685
|
+
conflict: array(string()).readonly(),
|
|
13686
|
+
record: BulkRecordSchema
|
|
13687
|
+
}), object({ id: union([string(), number()]) }), {
|
|
13688
|
+
kind: "mutation",
|
|
13689
|
+
auth: "admin"
|
|
13639
13690
|
}), method(object({
|
|
13640
13691
|
namespace: string().optional(),
|
|
13641
13692
|
collection: string(),
|
|
@@ -20118,8 +20169,8 @@ var TrackPositionSchema = object({
|
|
|
20118
20169
|
var TrackSnapshotSchema = object({
|
|
20119
20170
|
timestamp: number(),
|
|
20120
20171
|
position: TrackPositionSchema,
|
|
20121
|
-
/**
|
|
20122
|
-
|
|
20172
|
+
/** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
|
|
20173
|
+
mediaId: number().int()
|
|
20123
20174
|
});
|
|
20124
20175
|
/**
|
|
20125
20176
|
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
@@ -20723,14 +20774,14 @@ var ObjectEventSchema = object({
|
|
|
20723
20774
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
20724
20775
|
frameWidth: number().optional(),
|
|
20725
20776
|
frameHeight: number().optional(),
|
|
20726
|
-
/**
|
|
20727
|
-
|
|
20728
|
-
/** Design B:
|
|
20777
|
+
/** Media row id of the crop attached to this event (if any) — D482. */
|
|
20778
|
+
mediaId: number().int().optional(),
|
|
20779
|
+
/** Design B: media row id of the track's native-resolution key frame (the
|
|
20729
20780
|
* best-detection full frame). Resolve via the event-media data-plane
|
|
20730
|
-
* (`/addon/<addonId>/event-media/<
|
|
20781
|
+
* (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
|
|
20731
20782
|
* draws `bbox` over the native frame. Absent on legacy rows / non-decoded
|
|
20732
|
-
* sources — consumers fall back to `
|
|
20733
|
-
|
|
20783
|
+
* sources — consumers fall back to `mediaId` (the tight crop). */
|
|
20784
|
+
keyFrameMediaId: number().int().optional(),
|
|
20734
20785
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20735
20786
|
mediaUrl: string().optional(),
|
|
20736
20787
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
@@ -20780,7 +20831,7 @@ var MediaFileKindEnum = _enum([
|
|
|
20780
20831
|
* hub-main's heap on the way past — for an `<img>` that would have cached it.
|
|
20781
20832
|
*
|
|
20782
20833
|
* `url` points at the `event-media` data plane
|
|
20783
|
-
* (`/addon/<addonId>/event-media/<
|
|
20834
|
+
* (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
|
|
20784
20835
|
* with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
|
|
20785
20836
|
* render a `?variant=thumb`, and streams. The hub gate in front of it requires
|
|
20786
20837
|
* a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
|
|
@@ -20788,10 +20839,13 @@ var MediaFileKindEnum = _enum([
|
|
|
20788
20839
|
* `data-plane-access.ts` for the rule and the one gap it does not close
|
|
20789
20840
|
* (per-device scoping).
|
|
20790
20841
|
*
|
|
20791
|
-
* The URL is built from the row's
|
|
20792
|
-
*
|
|
20842
|
+
* The URL is built from the row's own id, which since D482 says nothing about
|
|
20843
|
+
* the row's owner or kind — and that is the point. The published `kind` is not
|
|
20844
|
+
* the stored one (a track's face/plate crop is stored as `crop` under
|
|
20793
20845
|
* `('face'|'plate', '<prefix>-<trackId>')` and published as
|
|
20794
|
-
* `faceCrop`/`plateCrop
|
|
20846
|
+
* `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
|
|
20847
|
+
* taken from `row.key` verbatim or it 404'd exactly those two rows. An id
|
|
20848
|
+
* cannot be mis-reconstructed, because there is nothing in it to reconstruct.
|
|
20795
20849
|
*
|
|
20796
20850
|
* ## `base64` is TRANSITIONAL and is going away
|
|
20797
20851
|
*
|
|
@@ -20804,7 +20858,19 @@ var MediaFileKindEnum = _enum([
|
|
|
20804
20858
|
* `analytics-query-facade.ts`; nothing else reads it.
|
|
20805
20859
|
*/
|
|
20806
20860
|
var MediaFileSchema = object({
|
|
20807
|
-
|
|
20861
|
+
/**
|
|
20862
|
+
* The media row's OWN id — the rowid SQLite assigned it (D482).
|
|
20863
|
+
*
|
|
20864
|
+
* It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
|
|
20865
|
+
* [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
|
|
20866
|
+
* per-table rowid aliases, so `object:101314` and `motion:101314` are two
|
|
20867
|
+
* different rows that spell the same number, and a track whose
|
|
20868
|
+
* `bestEventId` was an object event was served a motion event's snapshot —
|
|
20869
|
+
* a night-time thumbnail on an afternoon track, with no error anywhere. A
|
|
20870
|
+
* surrogate id cannot name the wrong row's owner, because it names no owner
|
|
20871
|
+
* at all.
|
|
20872
|
+
*/
|
|
20873
|
+
mediaId: number().int(),
|
|
20808
20874
|
kind: MediaFileKindEnum,
|
|
20809
20875
|
sizeBytes: number(),
|
|
20810
20876
|
timestamp: number()
|
|
@@ -20912,7 +20978,7 @@ var RetrainTrackSchema = object({
|
|
|
20912
20978
|
});
|
|
20913
20979
|
/** A frame the picker may offer — an index row, no blob was read to produce it. */
|
|
20914
20980
|
var RetrainFrameCandidateSchema = object({
|
|
20915
|
-
|
|
20981
|
+
mediaId: number().int(),
|
|
20916
20982
|
kind: MediaFileKindEnum,
|
|
20917
20983
|
timestamp: number(),
|
|
20918
20984
|
sizeBytes: number().int(),
|
|
@@ -20926,7 +20992,7 @@ var RetrainFrameSchema = object({
|
|
|
20926
20992
|
deviceId: number(),
|
|
20927
20993
|
trackId: string(),
|
|
20928
20994
|
/** Provenance only. It may already point at nothing — that is expected. */
|
|
20929
|
-
|
|
20995
|
+
sourceMediaId: number().int(),
|
|
20930
20996
|
sourceKind: MediaFileKindEnum,
|
|
20931
20997
|
sizeBytes: number().int(),
|
|
20932
20998
|
width: number().int(),
|
|
@@ -20942,7 +21008,7 @@ var RetrainCopyRefusalSchema = _enum([
|
|
|
20942
21008
|
var RetrainFrameSelectionSchema = object({
|
|
20943
21009
|
copied: array(RetrainFrameSchema).readonly(),
|
|
20944
21010
|
refused: array(object({
|
|
20945
|
-
|
|
21011
|
+
sourceMediaId: number().int(),
|
|
20946
21012
|
reason: RetrainCopyRefusalSchema
|
|
20947
21013
|
})).readonly()
|
|
20948
21014
|
});
|
|
@@ -20950,7 +21016,7 @@ var RetrainFrameListSchema = object({
|
|
|
20950
21016
|
candidates: array(RetrainFrameCandidateSchema).readonly(),
|
|
20951
21017
|
copies: array(RetrainFrameSchema).readonly(),
|
|
20952
21018
|
/** What the page pre-selects — the native key frame when one survives. */
|
|
20953
|
-
|
|
21019
|
+
autoPickMediaId: number().int().optional()
|
|
20954
21020
|
});
|
|
20955
21021
|
/** What the operator asked the assist to look for. */
|
|
20956
21022
|
var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
|
|
@@ -21045,9 +21111,11 @@ var RecentTracksQueryInput = object({
|
|
|
21045
21111
|
});
|
|
21046
21112
|
/**
|
|
21047
21113
|
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21048
|
-
* `
|
|
21049
|
-
* served by the event-media plane
|
|
21050
|
-
* member visible has been materialised
|
|
21114
|
+
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21115
|
+
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21116
|
+
* first frame with a member visible has been materialised (D482 — it was the
|
|
21117
|
+
* row's composite key, which embedded the owner and could name another table's
|
|
21118
|
+
* row once event ids became per-table rowids).
|
|
21051
21119
|
*/
|
|
21052
21120
|
var SummarySchema = object({
|
|
21053
21121
|
id: string(),
|
|
@@ -21056,19 +21124,115 @@ var SummarySchema = object({
|
|
|
21056
21124
|
lastActiveAt: number(),
|
|
21057
21125
|
sealedAt: number().nullable(),
|
|
21058
21126
|
memberCount: number().int().nonnegative(),
|
|
21059
|
-
|
|
21127
|
+
groupShotMediaId: number().int().nullable()
|
|
21060
21128
|
});
|
|
21061
21129
|
var SummariesQueryInput = object({
|
|
21062
21130
|
deviceIds: array(number()).min(1),
|
|
21063
21131
|
since: number().optional(),
|
|
21064
21132
|
until: number().optional(),
|
|
21065
|
-
limit: number().int().min(1).max(200).default(50)
|
|
21133
|
+
limit: number().int().min(1).max(200).default(50),
|
|
21134
|
+
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21135
|
+
* meaning of "dog" on every summary surface. */
|
|
21136
|
+
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21066
21137
|
});
|
|
21067
|
-
var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
|
|
21068
21138
|
var SummaryDetailSchema = object({
|
|
21069
21139
|
summary: SummarySchema,
|
|
21070
|
-
/**
|
|
21071
|
-
|
|
21140
|
+
/** Members in absorption order, oldest join first. */
|
|
21141
|
+
members: array(object({
|
|
21142
|
+
trackId: string(),
|
|
21143
|
+
/**
|
|
21144
|
+
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21145
|
+
* and the track no longer exists to fill it.
|
|
21146
|
+
*
|
|
21147
|
+
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21148
|
+
* class afterwards, and a group's composition is the history of who came
|
|
21149
|
+
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21150
|
+
* dog" — rather than being handed a second, denormalised tally that would
|
|
21151
|
+
* drift from the members it claims to describe.
|
|
21152
|
+
*/
|
|
21153
|
+
className: string().nullable(),
|
|
21154
|
+
/** `primary` is the one member that carries the group's identity. */
|
|
21155
|
+
role: _enum([
|
|
21156
|
+
"primary",
|
|
21157
|
+
"sibling",
|
|
21158
|
+
"child"
|
|
21159
|
+
]).nullable(),
|
|
21160
|
+
joinedAt: number(),
|
|
21161
|
+
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21162
|
+
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21163
|
+
label: string().optional(),
|
|
21164
|
+
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21165
|
+
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21166
|
+
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21167
|
+
subLabel: string().optional()
|
|
21168
|
+
})).readonly()
|
|
21169
|
+
});
|
|
21170
|
+
/**
|
|
21171
|
+
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21172
|
+
*
|
|
21173
|
+
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21174
|
+
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21175
|
+
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21176
|
+
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21177
|
+
* can count them turns a page of two hundred groups into a thousand records to
|
|
21178
|
+
* draw two hundred badges.
|
|
21179
|
+
*/
|
|
21180
|
+
var SummaryListItemSchema = object({
|
|
21181
|
+
summary: SummarySchema,
|
|
21182
|
+
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21183
|
+
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21184
|
+
classes: array(object({
|
|
21185
|
+
className: string().nullable(),
|
|
21186
|
+
count: number().int().positive()
|
|
21187
|
+
})).readonly()
|
|
21188
|
+
});
|
|
21189
|
+
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21190
|
+
/**
|
|
21191
|
+
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21192
|
+
*
|
|
21193
|
+
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21194
|
+
* summaries feed that could only answer "the last N for these cameras"
|
|
21195
|
+
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21196
|
+
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21197
|
+
* "newest" means, on one screen.
|
|
21198
|
+
*/
|
|
21199
|
+
var RecentSummariesQueryInput = object({
|
|
21200
|
+
/** Devices to merge. An empty array yields an empty page. */
|
|
21201
|
+
deviceIds: array(number()),
|
|
21202
|
+
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21203
|
+
since: number().optional(),
|
|
21204
|
+
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21205
|
+
until: number().optional(),
|
|
21206
|
+
limit: number().int().min(1).max(500).default(100),
|
|
21207
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21208
|
+
cursor: string().optional(),
|
|
21209
|
+
/**
|
|
21210
|
+
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21211
|
+
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21212
|
+
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21213
|
+
* make the operator's one filter component produce two shapes.
|
|
21214
|
+
*
|
|
21215
|
+
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21216
|
+
* me the arrivals with a dog" has to return the group of four people who had
|
|
21217
|
+
* one with them; a filter on the group's own fields could only ever answer
|
|
21218
|
+
* about its primary.
|
|
21219
|
+
*
|
|
21220
|
+
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21221
|
+
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21222
|
+
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21223
|
+
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21224
|
+
* that read only the class would answer "animal" and never "dog".
|
|
21225
|
+
*
|
|
21226
|
+
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21227
|
+
*/
|
|
21228
|
+
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21229
|
+
});
|
|
21230
|
+
var RecentSummariesPageSchema = object({
|
|
21231
|
+
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21232
|
+
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21233
|
+
* whichever feed drew it. */
|
|
21234
|
+
summaries: array(SummaryListItemSchema).readonly(),
|
|
21235
|
+
nextCursor: string().nullable()
|
|
21072
21236
|
});
|
|
21073
21237
|
var RecentTracksPageSchema = object({
|
|
21074
21238
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
@@ -21482,7 +21646,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21482
21646
|
classes: array(string()).optional(),
|
|
21483
21647
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21484
21648
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21485
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
21649
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(RecentSummariesQueryInput, RecentSummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
21486
21650
|
kind: "mutation",
|
|
21487
21651
|
auth: "admin"
|
|
21488
21652
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -21610,7 +21774,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21610
21774
|
}), method(object({
|
|
21611
21775
|
deviceId: number(),
|
|
21612
21776
|
trackId: string(),
|
|
21613
|
-
|
|
21777
|
+
mediaIds: array(number().int()).min(1)
|
|
21614
21778
|
}), RetrainFrameSelectionSchema, {
|
|
21615
21779
|
kind: "mutation",
|
|
21616
21780
|
auth: "admin"
|
|
@@ -21678,7 +21842,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21678
21842
|
kind: "query",
|
|
21679
21843
|
auth: "admin"
|
|
21680
21844
|
}), method(object({
|
|
21681
|
-
|
|
21845
|
+
/** Which of the three event tables owns the row. */
|
|
21846
|
+
ownerType: EventOwnerTypeSchema,
|
|
21847
|
+
/** The event's rowid in that table (D474: an event id is a number). */
|
|
21848
|
+
eventId: number().int(),
|
|
21682
21849
|
kind: MediaFileKindEnum.optional(),
|
|
21683
21850
|
deviceId: number()
|
|
21684
21851
|
}), array(MediaFileSchema).readonly()), method(object({
|
|
@@ -21689,7 +21856,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21689
21856
|
trackId: string(),
|
|
21690
21857
|
deviceId: number()
|
|
21691
21858
|
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21692
|
-
|
|
21859
|
+
ownerType: EventOwnerTypeSchema,
|
|
21860
|
+
eventId: number().int(),
|
|
21693
21861
|
deviceId: number()
|
|
21694
21862
|
}), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
|
|
21695
21863
|
kind: "mutation",
|
|
@@ -26882,8 +27050,8 @@ var IdentitySchema = object({
|
|
|
26882
27050
|
id: string(),
|
|
26883
27051
|
name: string(),
|
|
26884
27052
|
sampleCount: number().int().nonnegative(),
|
|
26885
|
-
|
|
26886
|
-
/** Inline base64 of the cover sample's crop, resolved from `
|
|
27053
|
+
coverMediaId: number().int().optional(),
|
|
27054
|
+
/** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
|
|
26887
27055
|
* Lets the UI render the person's face avatar instead of a placeholder icon. */
|
|
26888
27056
|
coverBase64: string().optional()
|
|
26889
27057
|
});
|
|
@@ -26909,8 +27077,8 @@ var IdentitySampleAuditRowSchema = object({
|
|
|
26909
27077
|
enrolledAt: number().int(),
|
|
26910
27078
|
deviceId: number().int().optional(),
|
|
26911
27079
|
source: _enum(["detected", "photo"]),
|
|
26912
|
-
/** The enrolled crop's media
|
|
26913
|
-
|
|
27080
|
+
/** The enrolled crop's media row id, so the panel can show the evidence. */
|
|
27081
|
+
mediaId: number().int().optional(),
|
|
26914
27082
|
/**
|
|
26915
27083
|
* False = the sample is stamped with a DIFFERENT face model, and a cosine
|
|
26916
27084
|
* across feature spaces is a well-formed float with no meaning. Every number
|
|
@@ -26979,15 +27147,15 @@ var FaceInfoSchema = object({
|
|
|
26979
27147
|
*/
|
|
26980
27148
|
cropUrl: string().optional(),
|
|
26981
27149
|
/** Design B: the face bbox (pixel space) on the key frame — lets a detail
|
|
26982
|
-
* view draw the box over the native `
|
|
27150
|
+
* view draw the box over the native `keyFrameMediaId` frame. Absent on
|
|
26983
27151
|
* legacy rows written before design B. */
|
|
26984
27152
|
faceBbox: BoundingBoxSchema.optional(),
|
|
26985
27153
|
/** Design B: MediaStore key of the track's native-resolution key frame.
|
|
26986
27154
|
* Fetch the native JPEG via the event-media data-plane
|
|
26987
|
-
* (`/addon/<addonId>/event-media/<
|
|
27155
|
+
* (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
|
|
26988
27156
|
* track produced no key frame (e.g. native/onboard source) — the UI falls
|
|
26989
27157
|
* back to the inline `base64` face crop. */
|
|
26990
|
-
|
|
27158
|
+
keyFrameMediaId: number().int().optional(),
|
|
26991
27159
|
/** Winning identity-match cosine (0..1) for this face's track, when an
|
|
26992
27160
|
* identity was auto-confirmed. Lets the UI surface WHY a face was assigned
|
|
26993
27161
|
* (confidence badge / low-confidence audit). Absent on legacy rows and on
|
|
@@ -27056,11 +27224,14 @@ var FaceClusterSchema = object({
|
|
|
27056
27224
|
* `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
|
|
27057
27225
|
* dialog already rendering its key FRAME from the `event-media` plane.
|
|
27058
27226
|
*
|
|
27059
|
-
* `url` is `/addon/<addonId>/event-media/<
|
|
27060
|
-
* media
|
|
27227
|
+
* `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
|
|
27228
|
+
* resolves a media row by its own id, so this needed no new plane and no new
|
|
27229
|
+
* access decision.
|
|
27061
27230
|
*/
|
|
27062
27231
|
var MediaFileLiteSchema$1 = object({
|
|
27063
|
-
|
|
27232
|
+
/** The media row's own id — the same address `MediaFileRef.mediaId` carries
|
|
27233
|
+
* (D482). It was the row's composite key, which embedded the owner. */
|
|
27234
|
+
mediaId: number().int(),
|
|
27064
27235
|
kind: string(),
|
|
27065
27236
|
url: string(),
|
|
27066
27237
|
sizeBytes: number(),
|
|
@@ -27077,7 +27248,7 @@ method(object({
|
|
|
27077
27248
|
* covers inline, ~10 KB of base64 per row, on a query this UI mounts
|
|
27078
27249
|
* four times and the viewer holds at `staleTime: 30_000`.
|
|
27079
27250
|
*
|
|
27080
|
-
* Nothing loses its avatar: `
|
|
27251
|
+
* Nothing loses its avatar: `coverMediaId` is already on every row and
|
|
27081
27252
|
* the `event-media` plane serves that key `immutable` with an ETag.
|
|
27082
27253
|
*
|
|
27083
27254
|
* **This is an INPUT field, so it does not reach the addon until the
|
|
@@ -30440,8 +30611,8 @@ var VehicleSchema = object({
|
|
|
30440
30611
|
id: string(),
|
|
30441
30612
|
name: string(),
|
|
30442
30613
|
sampleCount: number().int().nonnegative(),
|
|
30443
|
-
|
|
30444
|
-
/** Inline base64 of the cover sample's plate crop, resolved from `
|
|
30614
|
+
coverMediaId: number().int().optional(),
|
|
30615
|
+
/** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
|
|
30445
30616
|
coverBase64: string().optional()
|
|
30446
30617
|
});
|
|
30447
30618
|
var VehicleSampleInfoSchema = object({
|
|
@@ -30474,7 +30645,7 @@ var PlateInfoSchema = object({
|
|
|
30474
30645
|
/** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
|
|
30475
30646
|
plateBbox: BoundingBoxSchema.optional(),
|
|
30476
30647
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
30477
|
-
|
|
30648
|
+
keyFrameMediaId: number().int().optional(),
|
|
30478
30649
|
base64: string().optional(),
|
|
30479
30650
|
/**
|
|
30480
30651
|
* Same crop as a data-plane URL, always present when the plate has a stored
|
|
@@ -30495,11 +30666,14 @@ var PlateInfoSchema = object({
|
|
|
30495
30666
|
* `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
|
|
30496
30667
|
* dialog already rendering its key FRAME from the `event-media` plane.
|
|
30497
30668
|
*
|
|
30498
|
-
* `url` is `/addon/<addonId>/event-media/<
|
|
30499
|
-
* media
|
|
30669
|
+
* `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
|
|
30670
|
+
* resolves a media row by its own id, so this needed no new plane and no new
|
|
30671
|
+
* access decision.
|
|
30500
30672
|
*/
|
|
30501
30673
|
var MediaFileLiteSchema = object({
|
|
30502
|
-
|
|
30674
|
+
/** The media row's own id — the same address `MediaFileRef.mediaId` carries
|
|
30675
|
+
* (D482). It was the row's composite key, which embedded the owner. */
|
|
30676
|
+
mediaId: number().int(),
|
|
30503
30677
|
kind: string(),
|
|
30504
30678
|
url: string(),
|
|
30505
30679
|
sizeBytes: number(),
|
|
@@ -30558,7 +30732,7 @@ method(object({
|
|
|
30558
30732
|
}), method(object({
|
|
30559
30733
|
/** Inline {@link VehicleSchema.coverBase64} on every row. Default
|
|
30560
30734
|
* `false` — the vehicle twin of `faceGallery.listIdentities`'s
|
|
30561
|
-
* option; `
|
|
30735
|
+
* option; `coverMediaId` + the `event-media` plane carry the picture.
|
|
30562
30736
|
* INPUT field: stripped by the hub router until the train ships, which
|
|
30563
30737
|
* resolves to `false` and is exactly the intended default. */
|
|
30564
30738
|
includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
|
|
@@ -32127,7 +32301,14 @@ var SceneReferenceSchema = object({
|
|
|
32127
32301
|
modelId: string(),
|
|
32128
32302
|
condition: SceneConditionSchema,
|
|
32129
32303
|
capturedAt: number(),
|
|
32130
|
-
|
|
32304
|
+
/**
|
|
32305
|
+
* The reference thumbnail's media ROW id (D482).
|
|
32306
|
+
*
|
|
32307
|
+
* The name already said `mediaId` while the value was the row's composite
|
|
32308
|
+
* key — a leftover that read as done and was not. It is the row's own id
|
|
32309
|
+
* now, addressed at `/addon/<addonId>/event-media/m/<id>`.
|
|
32310
|
+
*/
|
|
32311
|
+
thumbnailMediaId: number().int().optional(),
|
|
32131
32312
|
/** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
|
|
32132
32313
|
* anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
|
|
32133
32314
|
* normalized rect frame a different piece of world, and the scene would
|
|
@@ -33218,7 +33399,29 @@ var LoggingSettingsPatchSchema = object({
|
|
|
33218
33399
|
* disarmed the channels it did not mention would make the Levels page and
|
|
33219
33400
|
* the Diagnostics page fight over the same value.
|
|
33220
33401
|
*/
|
|
33221
|
-
channels: array(LogChannelWindowPatchSchema).readonly().optional()
|
|
33402
|
+
channels: array(LogChannelWindowPatchSchema).readonly().optional(),
|
|
33403
|
+
/**
|
|
33404
|
+
* How many days the analytics OPS LOG is kept — the audit trail of what
|
|
33405
|
+
* retention actually deleted.
|
|
33406
|
+
*
|
|
33407
|
+
* It lives HERE, on the logging document, and not on the analytics addon's
|
|
33408
|
+
* settings form, on the operator's instruction: every other log-ish window in
|
|
33409
|
+
* this system is configured through this one document, and a retention audit
|
|
33410
|
+
* configured somewhere else is a second place to look when the question is
|
|
33411
|
+
* "what happened to my data".
|
|
33412
|
+
*
|
|
33413
|
+
* That placement has a cost worth stating: this document ships in the
|
|
33414
|
+
* framework closure, so this knob needs a published `@camstack/server` while
|
|
33415
|
+
* the four windows beside it (D485) reach a node on `camstack deploy`.
|
|
33416
|
+
*
|
|
33417
|
+
* `retention-model.ts` argued this one must NOT follow a device window,
|
|
33418
|
+
* because the audit trail is the history of the SWEEP and not of the camera.
|
|
33419
|
+
* That argument stands and is untouched — what changes is that 30 days stops
|
|
33420
|
+
* being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
|
|
33421
|
+
* rather than 0-as-delete: an audit log truncated to nothing is precisely the
|
|
33422
|
+
* state in which the next 9.5 GiB leak cannot be explained.
|
|
33423
|
+
*/
|
|
33424
|
+
opsLogRetentionDays: number().int().min(0).max(3650).optional()
|
|
33222
33425
|
});
|
|
33223
33426
|
/**
|
|
33224
33427
|
* Which LAYER of the hierarchy is addressed. Absent = the cluster layer.
|
|
@@ -33291,6 +33494,14 @@ var LoggingSettingsStateSchema = object({
|
|
|
33291
33494
|
channels: array(LogChannelDescriptorSchema).readonly(),
|
|
33292
33495
|
/** The channels ARMED right now, each with its deadline. */
|
|
33293
33496
|
activeChannels: array(LogChannelWindowStateSchema).readonly(),
|
|
33497
|
+
/**
|
|
33498
|
+
* The ops-log window in days, as it is in force. `0` = kept forever.
|
|
33499
|
+
*
|
|
33500
|
+
* Reported rather than left to the caller's memory of what it wrote: this is
|
|
33501
|
+
* the value the analytics sweep will actually use, and an operator asking how
|
|
33502
|
+
* long their audit trail lives should not have to infer it from a default.
|
|
33503
|
+
*/
|
|
33504
|
+
opsLogRetentionDays: number().int().min(0),
|
|
33294
33505
|
persisted: boolean()
|
|
33295
33506
|
});
|
|
33296
33507
|
method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
@@ -34111,7 +34322,7 @@ var StationaryObjectSchema = object({
|
|
|
34111
34322
|
/** Enrichment label carried from the source track (identity / plate). */
|
|
34112
34323
|
label: string().optional(),
|
|
34113
34324
|
/** Native-resolution key-frame media key for the parked object's best image. */
|
|
34114
|
-
|
|
34325
|
+
keyFrameMediaId: number().int().optional()
|
|
34115
34326
|
});
|
|
34116
34327
|
var CameraOccupancySnapshotSchema = object({
|
|
34117
34328
|
/** Frame timestamp of the inference result that produced this snapshot. */
|
|
@@ -36849,6 +37060,12 @@ Object.freeze({
|
|
|
36849
37060
|
addonId: null,
|
|
36850
37061
|
access: "create"
|
|
36851
37062
|
},
|
|
37063
|
+
"dataStoreProvider.upsert": {
|
|
37064
|
+
capName: "data-store-provider",
|
|
37065
|
+
capScope: "system",
|
|
37066
|
+
addonId: null,
|
|
37067
|
+
access: "create"
|
|
37068
|
+
},
|
|
36852
37069
|
"dayNight.getOptions": {
|
|
36853
37070
|
capName: "day-night",
|
|
36854
37071
|
capScope: "device",
|
|
@@ -39285,6 +39502,12 @@ Object.freeze({
|
|
|
39285
39502
|
addonId: null,
|
|
39286
39503
|
access: "view"
|
|
39287
39504
|
},
|
|
39505
|
+
"pipelineAnalytics.listRecentSummaries": {
|
|
39506
|
+
capName: "pipeline-analytics",
|
|
39507
|
+
capScope: "device",
|
|
39508
|
+
addonId: null,
|
|
39509
|
+
access: "view"
|
|
39510
|
+
},
|
|
39288
39511
|
"pipelineAnalytics.listRecentTracks": {
|
|
39289
39512
|
capName: "pipeline-analytics",
|
|
39290
39513
|
capScope: "device",
|
|
@@ -40713,6 +40936,12 @@ Object.freeze({
|
|
|
40713
40936
|
addonId: null,
|
|
40714
40937
|
access: "create"
|
|
40715
40938
|
},
|
|
40939
|
+
"settingsStore.upsert": {
|
|
40940
|
+
capName: "settings-store",
|
|
40941
|
+
capScope: "system",
|
|
40942
|
+
addonId: null,
|
|
40943
|
+
access: "create"
|
|
40944
|
+
},
|
|
40716
40945
|
"smtpProvider.getStatus": {
|
|
40717
40946
|
capName: "smtp-provider",
|
|
40718
40947
|
capScope: "system",
|
|
@@ -43106,6 +43335,11 @@ Object.freeze({
|
|
|
43106
43335
|
form: "single",
|
|
43107
43336
|
optional: true
|
|
43108
43337
|
}],
|
|
43338
|
+
"pipelineAnalytics.listRecentSummaries": [{
|
|
43339
|
+
name: "deviceIds",
|
|
43340
|
+
form: "array",
|
|
43341
|
+
optional: false
|
|
43342
|
+
}],
|
|
43109
43343
|
"pipelineAnalytics.listRecentTracks": [{
|
|
43110
43344
|
name: "deviceIds",
|
|
43111
43345
|
form: "array",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-rademacher",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.100",
|
|
4
4
|
"description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|