camstack 1.2.45 → 1.2.47
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.
|
@@ -14522,7 +14522,7 @@ function date4(params) {
|
|
|
14522
14522
|
// ../../node_modules/zod/v4/classic/external.js
|
|
14523
14523
|
config(en_default());
|
|
14524
14524
|
|
|
14525
|
-
// ../types/dist/sleep-
|
|
14525
|
+
// ../types/dist/sleep-CdbM8ge4.mjs
|
|
14526
14526
|
var WELL_KNOWN_TABS = [
|
|
14527
14527
|
{
|
|
14528
14528
|
id: "overview",
|
|
@@ -15603,6 +15603,28 @@ var OpsLogQueryInputSchema = external_exports.object({
|
|
|
15603
15603
|
/** Max rows returned, newest-first. */
|
|
15604
15604
|
limit: external_exports.number().int().min(1).max(1e3).optional()
|
|
15605
15605
|
});
|
|
15606
|
+
var LabelDefinitionSchema = external_exports.object({
|
|
15607
|
+
id: external_exports.string(),
|
|
15608
|
+
name: external_exports.string(),
|
|
15609
|
+
category: external_exports.string().optional(),
|
|
15610
|
+
description: external_exports.string().optional(),
|
|
15611
|
+
icon: external_exports.string().optional()
|
|
15612
|
+
});
|
|
15613
|
+
var CLASS_MAP_MACRO_TARGETS = [
|
|
15614
|
+
"person",
|
|
15615
|
+
"vehicle",
|
|
15616
|
+
"animal",
|
|
15617
|
+
"package"
|
|
15618
|
+
];
|
|
15619
|
+
var FIRST_LEVEL_MACRO_CLASSES = [
|
|
15620
|
+
"person",
|
|
15621
|
+
"vehicle",
|
|
15622
|
+
"animal"
|
|
15623
|
+
];
|
|
15624
|
+
var DetectionCatalogClassMapSchema = external_exports.object({
|
|
15625
|
+
mapping: external_exports.record(external_exports.string(), external_exports.enum(CLASS_MAP_MACRO_TARGETS)),
|
|
15626
|
+
preserveOriginal: external_exports.boolean()
|
|
15627
|
+
});
|
|
15606
15628
|
var RecordingWeekdaySchema = external_exports.number().int().min(0).max(6);
|
|
15607
15629
|
var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
15608
15630
|
var RecordingStorageModeSchema = external_exports.enum([
|
|
@@ -15610,9 +15632,42 @@ var RecordingStorageModeSchema = external_exports.enum([
|
|
|
15610
15632
|
"events",
|
|
15611
15633
|
"continuous"
|
|
15612
15634
|
]);
|
|
15635
|
+
var RecordingObjectTriggerClassSchema = external_exports.enum(FIRST_LEVEL_MACRO_CLASSES);
|
|
15636
|
+
var noDuplicates = (values) => new Set(values).size === values.length;
|
|
15613
15637
|
var RecordingTriggersSchema = external_exports.object({
|
|
15614
15638
|
motion: external_exports.boolean().optional(),
|
|
15615
|
-
audioThresholdDbfs: external_exports.number().optional()
|
|
15639
|
+
audioThresholdDbfs: external_exports.number().optional(),
|
|
15640
|
+
/**
|
|
15641
|
+
* Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
|
|
15642
|
+
* non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
|
|
15643
|
+
* object acceso, nessuna classe" è la stessa forma "abilitata e non registra
|
|
15644
|
+
* nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
|
|
15645
|
+
*
|
|
15646
|
+
* Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
|
|
15647
|
+
* quelle che hanno attraversato `enabledMacroClasses`, i
|
|
15648
|
+
* `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
|
|
15649
|
+
* (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
|
|
15650
|
+
* finestre — vedi `recorder/object-trigger.ts`.
|
|
15651
|
+
*/
|
|
15652
|
+
objectClasses: external_exports.array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
|
|
15653
|
+
/**
|
|
15654
|
+
* I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
|
|
15655
|
+
* non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
|
|
15656
|
+
* `objectClasses`.
|
|
15657
|
+
*
|
|
15658
|
+
* Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
|
|
15659
|
+
* percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
|
|
15660
|
+
* non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
|
|
15661
|
+
* si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
|
|
15662
|
+
* device (D12) — mai un elenco globale di cap.
|
|
15663
|
+
*
|
|
15664
|
+
* Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
|
|
15665
|
+
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
|
|
15666
|
+
* la stessa che il virtual-doorbell usa dal 2026-08-05. Ed è il FRONTE, non
|
|
15667
|
+
* il livello: un contatto trovato già aperto al riavvio del runner non fa
|
|
15668
|
+
* registrare.
|
|
15669
|
+
*/
|
|
15670
|
+
sensorDeviceIds: external_exports.array(external_exports.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
15616
15671
|
});
|
|
15617
15672
|
var RecordingBandModeSchema = external_exports.enum(["continuous", "events"]);
|
|
15618
15673
|
var RecordingBandTriggersSchema = RecordingTriggersSchema;
|
|
@@ -15929,23 +15984,6 @@ var DecoderSessionConfigSchema = external_exports.object({
|
|
|
15929
15984
|
*/
|
|
15930
15985
|
debug: external_exports.boolean().optional()
|
|
15931
15986
|
});
|
|
15932
|
-
var LabelDefinitionSchema = external_exports.object({
|
|
15933
|
-
id: external_exports.string(),
|
|
15934
|
-
name: external_exports.string(),
|
|
15935
|
-
category: external_exports.string().optional(),
|
|
15936
|
-
description: external_exports.string().optional(),
|
|
15937
|
-
icon: external_exports.string().optional()
|
|
15938
|
-
});
|
|
15939
|
-
var CLASS_MAP_MACRO_TARGETS = [
|
|
15940
|
-
"person",
|
|
15941
|
-
"vehicle",
|
|
15942
|
-
"animal",
|
|
15943
|
-
"package"
|
|
15944
|
-
];
|
|
15945
|
-
var DetectionCatalogClassMapSchema = external_exports.object({
|
|
15946
|
-
mapping: external_exports.record(external_exports.string(), external_exports.enum(CLASS_MAP_MACRO_TARGETS)),
|
|
15947
|
-
preserveOriginal: external_exports.boolean()
|
|
15948
|
-
});
|
|
15949
15987
|
var MODEL_FORMATS = [
|
|
15950
15988
|
"onnx",
|
|
15951
15989
|
"coreml",
|
|
@@ -23694,7 +23732,23 @@ var NcHistoryEntrySchema = external_exports.object({
|
|
|
23694
23732
|
updatedAt: external_exports.number(),
|
|
23695
23733
|
/** Failure detail — present on a `dead` row. */
|
|
23696
23734
|
error: external_exports.string().optional(),
|
|
23697
|
-
subject: NcHistorySubjectSchema
|
|
23735
|
+
subject: NcHistorySubjectSchema,
|
|
23736
|
+
/**
|
|
23737
|
+
* Ids of the artefacts (still, then gif, then clip) this row's successful
|
|
23738
|
+
* delivery indexed in the artefact library — a REFERENCE, never the bytes
|
|
23739
|
+
* (an artefact is often megabytes; this row is durable JSON rewritten on
|
|
23740
|
+
* every delivery attempt). Absent on a row still pending/dead, a row
|
|
23741
|
+
* delivered before this field shipped, or a wiring with no artefact index.
|
|
23742
|
+
*
|
|
23743
|
+
* Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
|
|
23744
|
+
* outlives any one URL's TTL, so a caller mints a fresh link on demand
|
|
23745
|
+
* rather than trusting one frozen at delivery time. `resolveArtifactUrl`
|
|
23746
|
+
* also answers `null` for an id whose artefact has since expired past the
|
|
23747
|
+
* retained shelf's own age bound — the degrade a caller (the Home
|
|
23748
|
+
* Assistant export) must render as "no image right now", never as a
|
|
23749
|
+
* broken link.
|
|
23750
|
+
*/
|
|
23751
|
+
artifactIds: external_exports.array(external_exports.string().min(1)).optional()
|
|
23698
23752
|
});
|
|
23699
23753
|
var NcHistoryFilterSchema = external_exports.object({
|
|
23700
23754
|
ruleId: external_exports.string().optional(),
|
|
@@ -23940,6 +23994,20 @@ var notificationRulesCapability = {
|
|
|
23940
23994
|
*/
|
|
23941
23995
|
getHistory: method(external_exports.object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), external_exports.object({ entries: external_exports.array(NcHistoryEntrySchema) }), { auth: "admin" }),
|
|
23942
23996
|
/**
|
|
23997
|
+
* Mint a fresh, externally-reachable URL for one artefact a history row
|
|
23998
|
+
* named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
|
|
23999
|
+
* signed-link mechanism the dispatcher uses to attach media to an
|
|
24000
|
+
* outgoing notification (one derivation; this never re-implements it).
|
|
24001
|
+
*
|
|
24002
|
+
* `url: null` on THREE causes a caller must treat identically ("no image
|
|
24003
|
+
* right now", never a broken link): the id is unknown, its artefact has
|
|
24004
|
+
* expired past the retained shelf's own age bound, or this install has no
|
|
24005
|
+
* externally-reachable base URL. A caller that received a URL on a
|
|
24006
|
+
* previous call and now gets `null` must stop showing it — a link that
|
|
24007
|
+
* worked five minutes ago is not proof it works now.
|
|
24008
|
+
*/
|
|
24009
|
+
resolveArtifactUrl: method(external_exports.object({ artifactId: external_exports.string().min(1) }), external_exports.object({ url: external_exports.string().nullable() }), { auth: "admin" }),
|
|
24010
|
+
/**
|
|
23943
24011
|
* Snooze windows currently in effect, plus any whose digest has not yet
|
|
23944
24012
|
* gone out. `caller: 'required'`: a user sees their OWN windows and the
|
|
23945
24013
|
* global ones that silence them, never another person's private silence.
|
|
@@ -29804,7 +29872,7 @@ var lifecycleJobSchema = external_exports.object({
|
|
|
29804
29872
|
state: lifecycleJobStateSchema,
|
|
29805
29873
|
schemaVersion: external_exports.literal(1)
|
|
29806
29874
|
});
|
|
29807
|
-
var LogLevelSchema$
|
|
29875
|
+
var LogLevelSchema$2 = external_exports.enum([
|
|
29808
29876
|
"debug",
|
|
29809
29877
|
"info",
|
|
29810
29878
|
"warn",
|
|
@@ -30004,7 +30072,7 @@ var addonsCapability = {
|
|
|
30004
30072
|
getLogs: method(external_exports.object({
|
|
30005
30073
|
addonId: external_exports.string(),
|
|
30006
30074
|
limit: external_exports.number().min(1).max(500).default(100),
|
|
30007
|
-
level: LogLevelSchema$
|
|
30075
|
+
level: LogLevelSchema$2.optional()
|
|
30008
30076
|
}), external_exports.array(LogQueryEntrySchema)),
|
|
30009
30077
|
listPackages: method(external_exports.void(), external_exports.array(InstalledPackageSchema).readonly()),
|
|
30010
30078
|
installPackage: method(external_exports.object({
|
|
@@ -30242,7 +30310,7 @@ var addonsCapability = {
|
|
|
30242
30310
|
}),
|
|
30243
30311
|
onAddonLogs: method(external_exports.object({
|
|
30244
30312
|
addonId: external_exports.string(),
|
|
30245
|
-
level: LogLevelSchema$
|
|
30313
|
+
level: LogLevelSchema$2.optional()
|
|
30246
30314
|
}), LogStreamEntrySchema, { kind: "subscription" })
|
|
30247
30315
|
},
|
|
30248
30316
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
@@ -31701,6 +31769,14 @@ var FaceFilterEnum = external_exports.enum([
|
|
|
31701
31769
|
"identified",
|
|
31702
31770
|
"all"
|
|
31703
31771
|
]);
|
|
31772
|
+
var FaceSortFieldEnum = external_exports.enum(["timestamp", "suggestionConfidence"]);
|
|
31773
|
+
var FaceSortDirectionEnum = external_exports.enum(["asc", "desc"]);
|
|
31774
|
+
var FaceClusterSchema = external_exports.object({
|
|
31775
|
+
faceIds: external_exports.array(external_exports.string()).readonly(),
|
|
31776
|
+
representativeFaceId: external_exports.string(),
|
|
31777
|
+
size: external_exports.number().int(),
|
|
31778
|
+
cohesion: external_exports.number()
|
|
31779
|
+
});
|
|
31704
31780
|
var MediaFileLiteSchema$1 = external_exports.object({
|
|
31705
31781
|
key: external_exports.string(),
|
|
31706
31782
|
kind: external_exports.string(),
|
|
@@ -31759,24 +31835,72 @@ var faceGalleryCapability = {
|
|
|
31759
31835
|
auth: "admin"
|
|
31760
31836
|
}),
|
|
31761
31837
|
listRecentFaces: method(external_exports.object({
|
|
31762
|
-
/**
|
|
31838
|
+
/**
|
|
31839
|
+
* Restrict to ONE camera. Absent keeps the cluster-wide gallery view.
|
|
31840
|
+
*
|
|
31841
|
+
* The legacy single-camera form, kept verbatim for every caller that
|
|
31842
|
+
* already sends it. A caller that wants a SET sends {@link deviceIds}
|
|
31843
|
+
* instead — never both: `deviceIds` is the authority whenever it is
|
|
31844
|
+
* present, and this field is then ignored rather than unioned, so
|
|
31845
|
+
* there is exactly one answer to "which cameras did I ask for".
|
|
31846
|
+
*/
|
|
31763
31847
|
deviceId: external_exports.number().int().optional(),
|
|
31848
|
+
/**
|
|
31849
|
+
* Restrict to a SET of cameras — the review UI's camera filter, which
|
|
31850
|
+
* until now had to fetch the cluster-wide page and drop rows in the
|
|
31851
|
+
* client (so the `limit` it asked for was spent on cameras it was
|
|
31852
|
+
* about to discard).
|
|
31853
|
+
*
|
|
31854
|
+
* An **empty array reads NOTHING** — `[]` is an empty page, never
|
|
31855
|
+
* "every camera". A request for no devices is a request, not an
|
|
31856
|
+
* omission; same contract as `deviceManager.listFleet` and
|
|
31857
|
+
* `pipelineAnalytics.listRecentTracks`.
|
|
31858
|
+
*
|
|
31859
|
+
* Absent (`undefined`) is the omission, and keeps the cluster-wide view.
|
|
31860
|
+
*/
|
|
31861
|
+
deviceIds: external_exports.array(external_exports.number().int()).optional(),
|
|
31764
31862
|
limit: external_exports.number().int().positive().optional(),
|
|
31765
31863
|
filter: FaceFilterEnum.optional(),
|
|
31766
31864
|
/**
|
|
31767
|
-
*
|
|
31768
|
-
*
|
|
31865
|
+
* Window lower bound on {@link FaceInfo.timestamp}, INCLUSIVE.
|
|
31866
|
+
* Absent means no lower bound.
|
|
31867
|
+
*/
|
|
31868
|
+
since: external_exports.number().int().optional(),
|
|
31869
|
+
/**
|
|
31870
|
+
* Window upper bound on {@link FaceInfo.timestamp}, INCLUSIVE.
|
|
31871
|
+
* Absent means no upper bound.
|
|
31872
|
+
*/
|
|
31873
|
+
until: external_exports.number().int().optional(),
|
|
31874
|
+
/**
|
|
31875
|
+
* Order the page by time or by suggestion certainty. Default
|
|
31876
|
+
* `'timestamp'` — the historical order, unchanged for every caller
|
|
31877
|
+
* that does not ask.
|
|
31769
31878
|
*
|
|
31770
|
-
*
|
|
31771
|
-
*
|
|
31772
|
-
* the browser cache the images.
|
|
31879
|
+
* See {@link FaceSortFieldEnum} for what a row with no suggestion
|
|
31880
|
+
* does under `'suggestionConfidence'`.
|
|
31773
31881
|
*
|
|
31774
|
-
*
|
|
31775
|
-
*
|
|
31776
|
-
*
|
|
31777
|
-
*
|
|
31778
|
-
*
|
|
31779
|
-
|
|
31882
|
+
* Cost note: `'timestamp'` is served by the `(deviceId, timestamp)`
|
|
31883
|
+
* index and stops reading as soon as `limit` rows have PASSED the
|
|
31884
|
+
* filter. `'suggestionConfidence'` cannot stop early — the most
|
|
31885
|
+
* certain row may be the oldest — so it walks the window. Narrow it
|
|
31886
|
+
* with {@link since} / {@link until}.
|
|
31887
|
+
*/
|
|
31888
|
+
sortBy: FaceSortFieldEnum.optional(),
|
|
31889
|
+
/** Sort direction for {@link sortBy}. Default `'desc'`. */
|
|
31890
|
+
sortDirection: FaceSortDirectionEnum.optional(),
|
|
31891
|
+
/**
|
|
31892
|
+
* Inline the base64 crop on every row.
|
|
31893
|
+
*
|
|
31894
|
+
* Default `false` since the 2026-08-25 inversion — see
|
|
31895
|
+
* `include-crops-default.ts`, which is the ONE place that resolves
|
|
31896
|
+
* this for every gallery, and which records why the inline shape had
|
|
31897
|
+
* to become the one you ASK for (60 457 ms → UDS timeout at 500 rows).
|
|
31898
|
+
* The doc here used to still say `true`; it was wrong, and a leftover
|
|
31899
|
+
* that describes the old design reads as permission to rely on it.
|
|
31900
|
+
*
|
|
31901
|
+
* Nothing loses its image: the row carries {@link FaceInfo.cropUrl},
|
|
31902
|
+
* which the browser fetches off the `event-media` plane in parallel,
|
|
31903
|
+
* cached and ETagged.
|
|
31780
31904
|
*/
|
|
31781
31905
|
includeCrops: external_exports.boolean().optional()
|
|
31782
31906
|
}).optional(), external_exports.array(FaceInfoSchema).readonly()),
|
|
@@ -31825,13 +31949,39 @@ var faceGalleryCapability = {
|
|
|
31825
31949
|
suggestFaceClusters: method(external_exports.object({
|
|
31826
31950
|
threshold: external_exports.number().min(0).max(1).optional(),
|
|
31827
31951
|
minClusterSize: external_exports.number().int().min(2).optional(),
|
|
31828
|
-
|
|
31829
|
-
|
|
31830
|
-
|
|
31831
|
-
|
|
31832
|
-
|
|
31833
|
-
|
|
31834
|
-
|
|
31952
|
+
/**
|
|
31953
|
+
* Cap on the number of CLUSTERS returned. Renamed from `limit`,
|
|
31954
|
+
* which read as though it bounded the work — it never did.
|
|
31955
|
+
*
|
|
31956
|
+
* Wins over {@link limit} when both are sent.
|
|
31957
|
+
*/
|
|
31958
|
+
maxClusters: external_exports.number().int().positive().optional(),
|
|
31959
|
+
/**
|
|
31960
|
+
* @deprecated Ambiguous name for {@link maxClusters} — it cuts the
|
|
31961
|
+
* RESULT, not the scan. Kept so existing callers keep working; send
|
|
31962
|
+
* `maxClusters` (and, if you care about cost, {@link maxFacesScanned}).
|
|
31963
|
+
*/
|
|
31964
|
+
limit: external_exports.number().int().positive().optional(),
|
|
31965
|
+
/**
|
|
31966
|
+
* Cap on the number of unassigned faces READ AND CLUSTERED — the
|
|
31967
|
+
* POOL, not the result.
|
|
31968
|
+
*
|
|
31969
|
+
* This is the knob {@link maxClusters} was mistaken for. Clustering
|
|
31970
|
+
* used to read every unassigned face on the hub no matter what the
|
|
31971
|
+
* caller asked for, because the only bound cut the finished clusters
|
|
31972
|
+
* afterwards; a UI showing a window of 100 paid for a scan of the
|
|
31973
|
+
* whole corpus, on an addon whose disk is under contention.
|
|
31974
|
+
*
|
|
31975
|
+
* The pool is the NEWEST matching faces first — the same order the
|
|
31976
|
+
* gallery shows — so a bound here shortens the horizon, it does not
|
|
31977
|
+
* sample it randomly.
|
|
31978
|
+
*
|
|
31979
|
+
* Default: 1 000 (`FACE_SWEEP_PAGE`, exactly one store page). Chosen
|
|
31980
|
+
* so the live corpus — 372 face rows — is unaffected while the
|
|
31981
|
+
* unbounded scan can never come back as the table grows.
|
|
31982
|
+
*/
|
|
31983
|
+
maxFacesScanned: external_exports.number().int().positive().optional()
|
|
31984
|
+
}).optional(), external_exports.array(FaceClusterSchema).readonly())
|
|
31835
31985
|
}
|
|
31836
31986
|
};
|
|
31837
31987
|
var FanDirectionSchema = external_exports.enum(["forward", "reverse"]);
|
|
@@ -35381,6 +35531,23 @@ var ReadGopBytesResultSchema = external_exports.object({
|
|
|
35381
35531
|
/** Media ms the returned fragment covers. */
|
|
35382
35532
|
gopDurMs: external_exports.number()
|
|
35383
35533
|
});
|
|
35534
|
+
var ReadWindowBytesResultSchema = external_exports.discriminatedUnion("kind", [external_exports.object({
|
|
35535
|
+
kind: external_exports.literal("ok"),
|
|
35536
|
+
data: external_exports.instanceof(Uint8Array),
|
|
35537
|
+
/** Absolute epoch ms of the returned bytes' first sample — at or before
|
|
35538
|
+
* the requested `fromMs` (anchored on the nearest keyframe). */
|
|
35539
|
+
gopStartMs: external_exports.number(),
|
|
35540
|
+
/** Media ms the returned bytes cover, from `gopStartMs`. */
|
|
35541
|
+
gopDurMs: external_exports.number(),
|
|
35542
|
+
/** `false` ⇒ the safety byte cap cut the read short before it reached
|
|
35543
|
+
* the requested `toMs`; the caller got fewer frames than asked for. */
|
|
35544
|
+
reachesRequestedEnd: external_exports.boolean()
|
|
35545
|
+
}), external_exports.object({
|
|
35546
|
+
kind: external_exports.literal("spans-multiple-segments"),
|
|
35547
|
+
/** Where the covering segment's own footage runs out — informational,
|
|
35548
|
+
* not a retry hint (retrying the same window would refuse again). */
|
|
35549
|
+
segmentEndMs: external_exports.number()
|
|
35550
|
+
})]);
|
|
35384
35551
|
var recordingCapability = {
|
|
35385
35552
|
name: "recording",
|
|
35386
35553
|
scope: "system",
|
|
@@ -35460,6 +35627,21 @@ var recordingCapability = {
|
|
|
35460
35627
|
kind: "query",
|
|
35461
35628
|
auth: "admin"
|
|
35462
35629
|
}),
|
|
35630
|
+
/** Read a WINDOW `[fromMs, toMs)` of segment `startMs`, by mfra byte
|
|
35631
|
+
* range — the multi-GOP twin of `readGopBytes`. Refuses (does not
|
|
35632
|
+
* degrade) when the window runs past the covering segment. Used by the
|
|
35633
|
+
* replay clip's `recording` source to fetch several seconds of native
|
|
35634
|
+
* footage for its single ffmpeg decode pass. */
|
|
35635
|
+
readWindowBytes: method(external_exports.object({
|
|
35636
|
+
deviceId: external_exports.number(),
|
|
35637
|
+
profile: external_exports.string(),
|
|
35638
|
+
startMs: external_exports.number(),
|
|
35639
|
+
fromMs: external_exports.number(),
|
|
35640
|
+
toMs: external_exports.number()
|
|
35641
|
+
}), ReadWindowBytesResultSchema, {
|
|
35642
|
+
kind: "query",
|
|
35643
|
+
auth: "admin"
|
|
35644
|
+
}),
|
|
35463
35645
|
setDeviceConfig: method(external_exports.object({
|
|
35464
35646
|
deviceId: external_exports.number(),
|
|
35465
35647
|
config: RecordingConfigSchema
|
|
@@ -36399,6 +36581,121 @@ var SetSiteLocationInputSchema = external_exports.object({
|
|
|
36399
36581
|
latitude: external_exports.number().min(-90).max(90),
|
|
36400
36582
|
longitude: external_exports.number().min(-180).max(180)
|
|
36401
36583
|
}).nullable();
|
|
36584
|
+
var RequestCensusGroupSchema = external_exports.object({
|
|
36585
|
+
procedure: external_exports.string(),
|
|
36586
|
+
userAgent: external_exports.string(),
|
|
36587
|
+
ip: external_exports.string(),
|
|
36588
|
+
principal: external_exports.string(),
|
|
36589
|
+
calls: external_exports.number(),
|
|
36590
|
+
perMin: external_exports.number()
|
|
36591
|
+
});
|
|
36592
|
+
var RequestCensusProcedureSchema = external_exports.object({
|
|
36593
|
+
procedure: external_exports.string(),
|
|
36594
|
+
calls: external_exports.number(),
|
|
36595
|
+
perMin: external_exports.number()
|
|
36596
|
+
});
|
|
36597
|
+
var RequestCensusSnapshotSchema = external_exports.object({
|
|
36598
|
+
armed: external_exports.boolean(),
|
|
36599
|
+
/** How long the current - or just-closed - window collected, in ms. */
|
|
36600
|
+
elapsedMs: external_exports.number(),
|
|
36601
|
+
/** The window actually armed, after the server clamped the request. */
|
|
36602
|
+
windowMs: external_exports.number(),
|
|
36603
|
+
/** Epoch ms the window closes at. 0 when disarmed. */
|
|
36604
|
+
armedUntilMs: external_exports.number(),
|
|
36605
|
+
httpRequests: external_exports.number(),
|
|
36606
|
+
batchedRequests: external_exports.number(),
|
|
36607
|
+
/**
|
|
36608
|
+
* Procedure invocations. Higher than `httpRequests` whenever tRPC batching
|
|
36609
|
+
* is in play (`?batch=1` carries several procedures in one request); this is
|
|
36610
|
+
* the number comparable with a store-side call count.
|
|
36611
|
+
*/
|
|
36612
|
+
procedureCalls: external_exports.number(),
|
|
36613
|
+
/**
|
|
36614
|
+
* tRPC WebSocket connections opened during the window. NOT calls - the WS
|
|
36615
|
+
* transport resolves one context per connection - but the number that says
|
|
36616
|
+
* whether a plane this census cannot see was busy while HTTP was quiet.
|
|
36617
|
+
*/
|
|
36618
|
+
wsConnections: external_exports.number(),
|
|
36619
|
+
distinctGroups: external_exports.number(),
|
|
36620
|
+
/** Calls counted in the totals whose group attribution was shed at the
|
|
36621
|
+
* cardinality bound. */
|
|
36622
|
+
unattributedCalls: external_exports.number(),
|
|
36623
|
+
procedures: external_exports.array(RequestCensusProcedureSchema).readonly(),
|
|
36624
|
+
groups: external_exports.array(RequestCensusGroupSchema).readonly()
|
|
36625
|
+
});
|
|
36626
|
+
var RequestCensusStatusSchema = RequestCensusSnapshotSchema.extend({ persisted: external_exports.boolean() });
|
|
36627
|
+
var LogLevelSchema$1 = external_exports.enum([
|
|
36628
|
+
"debug",
|
|
36629
|
+
"info",
|
|
36630
|
+
"warn",
|
|
36631
|
+
"error"
|
|
36632
|
+
]);
|
|
36633
|
+
var DiagnosticIdSchema = external_exports.enum(["request-census"]);
|
|
36634
|
+
var LoggingScopeKindSchema = external_exports.enum([
|
|
36635
|
+
"cluster",
|
|
36636
|
+
"node",
|
|
36637
|
+
"component"
|
|
36638
|
+
]);
|
|
36639
|
+
var LoggingLevelSourceSchema = external_exports.enum([
|
|
36640
|
+
"default",
|
|
36641
|
+
"cluster",
|
|
36642
|
+
"node",
|
|
36643
|
+
"component"
|
|
36644
|
+
]);
|
|
36645
|
+
var LoggingLevelLayerSchema = external_exports.object({
|
|
36646
|
+
scope: LoggingScopeKindSchema,
|
|
36647
|
+
/** The node this layer speaks for; `null` on the cluster layer. */
|
|
36648
|
+
nodeId: external_exports.string().nullable(),
|
|
36649
|
+
/** Explicitly set here, or `null` when this layer inherits. */
|
|
36650
|
+
level: LogLevelSchema$1.nullable()
|
|
36651
|
+
});
|
|
36652
|
+
var LoggingEffectiveSchema = external_exports.object({
|
|
36653
|
+
level: LogLevelSchema$1,
|
|
36654
|
+
levelSource: LoggingLevelSourceSchema
|
|
36655
|
+
});
|
|
36656
|
+
var LoggingExplicitSchema = external_exports.object({ layers: external_exports.array(LoggingLevelLayerSchema).readonly() });
|
|
36657
|
+
var DiagnosticWindowSchema = external_exports.object({
|
|
36658
|
+
id: DiagnosticIdSchema,
|
|
36659
|
+
armed: external_exports.boolean(),
|
|
36660
|
+
/** Epoch ms the window closes at. 0 when disarmed. */
|
|
36661
|
+
armedUntilMs: external_exports.number(),
|
|
36662
|
+
/** Ms left before it expires on its own. 0 when disarmed. */
|
|
36663
|
+
remainingMs: external_exports.number(),
|
|
36664
|
+
/** Whether the stored deadline is the one the live diagnostic is running —
|
|
36665
|
+
* i.e. whether this window would survive a restart. */
|
|
36666
|
+
persisted: external_exports.boolean()
|
|
36667
|
+
});
|
|
36668
|
+
var DiagnosticWindowPatchSchema = external_exports.object({
|
|
36669
|
+
id: DiagnosticIdSchema,
|
|
36670
|
+
armMs: external_exports.number().int().min(0),
|
|
36671
|
+
/** Cadence of the diagnostic's aggregated report line. Clamped by the server. */
|
|
36672
|
+
reportEveryMs: external_exports.number().int().positive().optional()
|
|
36673
|
+
});
|
|
36674
|
+
var LoggingSettingsPatchSchema = external_exports.object({
|
|
36675
|
+
/**
|
|
36676
|
+
* Absent leaves the level untouched. `null` CLEARS the explicit value at the
|
|
36677
|
+
* addressed scope so it inherits again. A value sets it.
|
|
36678
|
+
*/
|
|
36679
|
+
level: LogLevelSchema$1.nullable().optional(),
|
|
36680
|
+
/**
|
|
36681
|
+
* Only the diagnostics NAMED here change. An armed window that is not listed
|
|
36682
|
+
* keeps running — a patch is never a full replacement.
|
|
36683
|
+
*/
|
|
36684
|
+
diagnostics: external_exports.array(DiagnosticWindowPatchSchema).readonly().optional()
|
|
36685
|
+
});
|
|
36686
|
+
var GetLoggingSettingsInputSchema = external_exports.object({ scopeNodeId: external_exports.string().optional() });
|
|
36687
|
+
var SetLoggingSettingsInputSchema = external_exports.object({
|
|
36688
|
+
scopeNodeId: external_exports.string().optional(),
|
|
36689
|
+
patch: LoggingSettingsPatchSchema
|
|
36690
|
+
});
|
|
36691
|
+
var LoggingSettingsStateSchema = external_exports.object({
|
|
36692
|
+
/** The layer this document was read at. `null` = the cluster layer. */
|
|
36693
|
+
scopeNodeId: external_exports.string().nullable(),
|
|
36694
|
+
effective: LoggingEffectiveSchema,
|
|
36695
|
+
explicit: LoggingExplicitSchema,
|
|
36696
|
+
activeWindows: external_exports.array(DiagnosticWindowSchema).readonly(),
|
|
36697
|
+
persisted: external_exports.boolean()
|
|
36698
|
+
});
|
|
36402
36699
|
var systemCapability = {
|
|
36403
36700
|
name: "system",
|
|
36404
36701
|
scope: "system",
|
|
@@ -36442,6 +36739,38 @@ var systemCapability = {
|
|
|
36442
36739
|
detectSiteLocation: method(external_exports.void(), SiteLocationStatusSchema, {
|
|
36443
36740
|
kind: "mutation",
|
|
36444
36741
|
auth: "admin"
|
|
36742
|
+
}),
|
|
36743
|
+
/**
|
|
36744
|
+
* Read the HTTP request census - which caller, from which address, with
|
|
36745
|
+
* which user-agent, invoked which tRPC procedure, and how often.
|
|
36746
|
+
*
|
|
36747
|
+
* Reading NEVER re-arms: re-arming clears the counts, which would throw
|
|
36748
|
+
* away exactly the numbers being asked for. A closed window may be read as
|
|
36749
|
+
* many times as the operator likes and always describes the same window.
|
|
36750
|
+
*
|
|
36751
|
+
* Admin-only: the rows carry source addresses and principal names.
|
|
36752
|
+
*/
|
|
36753
|
+
getRequestCensus: method(external_exports.void(), RequestCensusStatusSchema, { auth: "admin" }),
|
|
36754
|
+
/**
|
|
36755
|
+
* The logging settings document — levels and armed diagnostics — resolved
|
|
36756
|
+
* for `nodeId`, or for the cluster when `nodeId` is absent.
|
|
36757
|
+
*
|
|
36758
|
+
* Returns BOTH `effective` and `explicit`. See
|
|
36759
|
+
* {@link LoggingLevelLayerSchema} for why collapsing them is the defect.
|
|
36760
|
+
*/
|
|
36761
|
+
getLoggingSettings: method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }),
|
|
36762
|
+
/**
|
|
36763
|
+
* Write the logging settings document. The ONLY write authority over log
|
|
36764
|
+
* levels and diagnostic windows — arming the request census went through
|
|
36765
|
+
* `system.setRequestCensus` until 2026-08-27 and no longer does, because
|
|
36766
|
+
* two writes that disagree about the same window is exactly the defect
|
|
36767
|
+
* this document exists to remove (D245).
|
|
36768
|
+
*
|
|
36769
|
+
* The patch MERGES: see {@link LoggingSettingsPatchSchema}.
|
|
36770
|
+
*/
|
|
36771
|
+
setLoggingSettings: method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
|
|
36772
|
+
kind: "mutation",
|
|
36773
|
+
auth: "admin"
|
|
36445
36774
|
})
|
|
36446
36775
|
},
|
|
36447
36776
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
@@ -37305,6 +37634,19 @@ var PIPELINE_OWNER_CAPABILITY_NAMES = [
|
|
|
37305
37634
|
"pipeline-orchestrator",
|
|
37306
37635
|
"pipeline-runner"
|
|
37307
37636
|
];
|
|
37637
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
37638
|
+
contact: "entryOpen",
|
|
37639
|
+
binary: "on",
|
|
37640
|
+
switch: "on",
|
|
37641
|
+
motion: "detected",
|
|
37642
|
+
flood: "flooded",
|
|
37643
|
+
gas: "detected",
|
|
37644
|
+
smoke: "detected",
|
|
37645
|
+
"carbon-monoxide": "detected",
|
|
37646
|
+
vibration: "detected",
|
|
37647
|
+
tamper: "tampered"
|
|
37648
|
+
};
|
|
37649
|
+
var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
|
|
37308
37650
|
var HF_REPO = "camstack/camstack-models";
|
|
37309
37651
|
var HF_BASE_URL = `https://huggingface.co/${HF_REPO}/resolve/main`;
|
|
37310
37652
|
var AccessoryKind = {
|
|
@@ -37327,6 +37669,7 @@ var ACCESSORY_LABEL = {
|
|
|
37327
37669
|
[AccessoryKind.Nightvision]: "Night Vision",
|
|
37328
37670
|
[AccessoryKind.PrivacyMask]: "Privacy Mask"
|
|
37329
37671
|
};
|
|
37672
|
+
var BATTERY_UNREACHABLE_AFTER_MS = 360 * 6e4;
|
|
37330
37673
|
var DEVICE_TYPE_CONTROL_KIND = {
|
|
37331
37674
|
[DeviceType.Cover]: "cover",
|
|
37332
37675
|
[DeviceType.Valve]: "valve",
|
|
@@ -37371,7 +37714,6 @@ var BATTERY_DEVICE_PROFILE = {
|
|
|
37371
37714
|
},
|
|
37372
37715
|
settings: {}
|
|
37373
37716
|
};
|
|
37374
|
-
var BATTERY_UNREACHABLE_AFTER_MS = 360 * 6e4;
|
|
37375
37717
|
var OPERATOR_WRITTEN_STALE_MS = 10 * 6e4;
|
|
37376
37718
|
var METHOD_ACCESS_MAP = Object.freeze({
|
|
37377
37719
|
"accessories.setChildHidden": {
|
|
@@ -40278,6 +40620,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
40278
40620
|
addonId: null,
|
|
40279
40621
|
access: "view"
|
|
40280
40622
|
},
|
|
40623
|
+
"notificationRules.resolveArtifactUrl": {
|
|
40624
|
+
capName: "notification-rules",
|
|
40625
|
+
capScope: "system",
|
|
40626
|
+
addonId: null,
|
|
40627
|
+
access: "view"
|
|
40628
|
+
},
|
|
40281
40629
|
"notificationRules.setAlarmConfig": {
|
|
40282
40630
|
capName: "notification-rules",
|
|
40283
40631
|
capScope: "system",
|
|
@@ -41682,6 +42030,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
41682
42030
|
addonId: null,
|
|
41683
42031
|
access: "view"
|
|
41684
42032
|
},
|
|
42033
|
+
"recording.readWindowBytes": {
|
|
42034
|
+
capName: "recording",
|
|
42035
|
+
capScope: "system",
|
|
42036
|
+
addonId: null,
|
|
42037
|
+
access: "view"
|
|
42038
|
+
},
|
|
41685
42039
|
"recording.refreshStorageLocationsForMigration": {
|
|
41686
42040
|
capName: "recording",
|
|
41687
42041
|
capScope: "system",
|
|
@@ -42522,6 +42876,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
42522
42876
|
addonId: null,
|
|
42523
42877
|
access: "create"
|
|
42524
42878
|
},
|
|
42879
|
+
"system.getLoggingSettings": {
|
|
42880
|
+
capName: "system",
|
|
42881
|
+
capScope: "system",
|
|
42882
|
+
addonId: null,
|
|
42883
|
+
access: "view"
|
|
42884
|
+
},
|
|
42885
|
+
"system.getRequestCensus": {
|
|
42886
|
+
capName: "system",
|
|
42887
|
+
capScope: "system",
|
|
42888
|
+
addonId: null,
|
|
42889
|
+
access: "view"
|
|
42890
|
+
},
|
|
42525
42891
|
"system.getRetentionConfig": {
|
|
42526
42892
|
capName: "system",
|
|
42527
42893
|
capScope: "system",
|
|
@@ -42552,6 +42918,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
42552
42918
|
addonId: null,
|
|
42553
42919
|
access: "view"
|
|
42554
42920
|
},
|
|
42921
|
+
"system.setLoggingSettings": {
|
|
42922
|
+
capName: "system",
|
|
42923
|
+
capScope: "system",
|
|
42924
|
+
addonId: null,
|
|
42925
|
+
access: "create"
|
|
42926
|
+
},
|
|
42555
42927
|
"system.setRetentionConfig": {
|
|
42556
42928
|
capName: "system",
|
|
42557
42929
|
capScope: "system",
|
|
@@ -43707,6 +44079,10 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
43707
44079
|
name: "deviceId",
|
|
43708
44080
|
form: "single",
|
|
43709
44081
|
optional: true
|
|
44082
|
+
}, {
|
|
44083
|
+
name: "deviceIds",
|
|
44084
|
+
form: "array",
|
|
44085
|
+
optional: true
|
|
43710
44086
|
}],
|
|
43711
44087
|
"fanControl.setDirection": [{
|
|
43712
44088
|
name: "deviceId",
|
|
@@ -44512,6 +44888,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
44512
44888
|
form: "single",
|
|
44513
44889
|
optional: false
|
|
44514
44890
|
}],
|
|
44891
|
+
"recording.readWindowBytes": [{
|
|
44892
|
+
name: "deviceId",
|
|
44893
|
+
form: "single",
|
|
44894
|
+
optional: false
|
|
44895
|
+
}],
|
|
44515
44896
|
"recording.relocateFootage": [{
|
|
44516
44897
|
name: "deviceId",
|
|
44517
44898
|
form: "single",
|
|
@@ -45179,13 +45560,45 @@ var NativeLeaseSettingsSchema = external_exports.object({
|
|
|
45179
45560
|
* fallback — i.e. the pre-2026-08-13 miss profile. Set it there only to
|
|
45180
45561
|
* reproduce that.
|
|
45181
45562
|
*/
|
|
45182
|
-
tileBudgetMb: external_exports.number().int().min(0).max(1024)
|
|
45563
|
+
tileBudgetMb: external_exports.number().int().min(0).max(1024),
|
|
45564
|
+
/**
|
|
45565
|
+
* RAM ceiling per decode worker, in MB, for the SCENE TILES — one
|
|
45566
|
+
* JPEG-encoded copy of the WHOLE native frame, cut in the same instant as the
|
|
45567
|
+
* subject tiles, on frames that detected something.
|
|
45568
|
+
*
|
|
45569
|
+
* It exists because a subject tile cannot answer a FULL-FRAME request:
|
|
45570
|
+
* containment is strict by design, so the native `keyFrame`, the detail
|
|
45571
|
+
* plane's `frameJpeg` rung and the display-crop fallback had no rung at all
|
|
45572
|
+
* below the hold. Measured on the live cluster: 23.3% of key-frame captures
|
|
45573
|
+
* missed, 95.7% of them with `worker-lease-gone` — the raster released one
|
|
45574
|
+
* frame-time after delivery, with the request only p50 367 ms behind it.
|
|
45575
|
+
*
|
|
45576
|
+
* Sizing, and why this is a budget and not a duration: a scene tile is
|
|
45577
|
+
* ~1.5-2.5 MB at 4K (against ~23.75 MB for the raster it was cut from and
|
|
45578
|
+
* ~60-120 KB for a subject tile), and it is cut ~0.4 times a second per busy
|
|
45579
|
+
* camera — only detection-bearing frames get one. 48 MB is therefore ~20-30
|
|
45580
|
+
* frames, i.e. the store's 30 s TTL binds at the steady state and the budget
|
|
45581
|
+
* binds only through a detection burst, where it still covers well past the
|
|
45582
|
+
* measured p90 ask age of 4.3 s. Holding the RASTERS for the same window
|
|
45583
|
+
* would be ~498 MB per camera and ~6 GB at peak concurrency — the OOM this
|
|
45584
|
+
* whole shape exists to avoid.
|
|
45585
|
+
*
|
|
45586
|
+
* A SEPARATE ceiling from `tileBudgetMb` on purpose: a scene tile is ~20× a
|
|
45587
|
+
* subject tile, so one shared budget would let a busy camera's key frames
|
|
45588
|
+
* evict the face/plate tiles the recognisers depend on. Two budgets make that
|
|
45589
|
+
* impossible rather than unlikely. `0` DISABLES scene tiles and restores the
|
|
45590
|
+
* pre-existing behaviour, where a late full-frame request had nothing but the
|
|
45591
|
+
* ≤640 RAM raster — which the `keyFrame` gate rejects, so in practice it had
|
|
45592
|
+
* nothing.
|
|
45593
|
+
*/
|
|
45594
|
+
sceneBudgetMb: external_exports.number().int().min(0).max(1024)
|
|
45183
45595
|
});
|
|
45184
45596
|
var DEFAULT_NATIVE_LEASE_SETTINGS = {
|
|
45185
45597
|
holdFrames: 8,
|
|
45186
45598
|
budgetMb: 1024,
|
|
45187
45599
|
activityMs: 15e3,
|
|
45188
45600
|
tileBudgetMb: 64,
|
|
45601
|
+
sceneBudgetMb: 48,
|
|
45189
45602
|
admission: "inferred"
|
|
45190
45603
|
};
|
|
45191
45604
|
var NATIVE_LEASE_HOLD_FIELD = {
|
|
@@ -45212,6 +45625,12 @@ var NATIVE_LEASE_TILE_BUDGET_FIELD = {
|
|
|
45212
45625
|
step: 16,
|
|
45213
45626
|
default: DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb
|
|
45214
45627
|
};
|
|
45628
|
+
var NATIVE_LEASE_SCENE_BUDGET_FIELD = {
|
|
45629
|
+
min: 0,
|
|
45630
|
+
max: 1024,
|
|
45631
|
+
step: 16,
|
|
45632
|
+
default: DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb
|
|
45633
|
+
};
|
|
45215
45634
|
var NATIVE_LEASE_ADMISSION_FIELD = {
|
|
45216
45635
|
options: [{
|
|
45217
45636
|
value: "all",
|