@camstack/types 1.2.120 → 1.2.123
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/capabilities/intercom.cap.d.ts +27 -0
- package/dist/capabilities/metrics-provider.cap.d.ts +68 -1
- package/dist/capabilities/recording.cap.d.ts +4 -4
- package/dist/index.js +101 -16
- package/dist/index.mjs +101 -16
- package/dist/interfaces/event-bus.d.ts +11 -1
- package/dist/interfaces/metrics-provider.d.ts +3 -1
- package/dist/interfaces/recording-config.d.ts +4 -5
- package/package.json +1 -1
|
@@ -69,6 +69,33 @@ export declare const intercomCapability: {
|
|
|
69
69
|
readonly deviceNative: true;
|
|
70
70
|
readonly mode: "singleton";
|
|
71
71
|
readonly deviceTypes: readonly [DeviceType.Camera];
|
|
72
|
+
/**
|
|
73
|
+
* **Auth tier: `protected` on every method — deliberate, and load-bearing.**
|
|
74
|
+
*
|
|
75
|
+
* Talking through a camera is an OPERATE action, not a CONFIGURE one. This
|
|
76
|
+
* cap has no configuration surface at all: all six methods open, feed and
|
|
77
|
+
* close one live audio session against one `deviceId`. That is the same
|
|
78
|
+
* authority as `ptz.move` or `snapshot.getSnapshot`, both `protected` — and
|
|
79
|
+
* the opposite of `ptz.savePreset` / `snapshot.invalidateCache`, which are
|
|
80
|
+
* `admin` because they change what the device IS.
|
|
81
|
+
*
|
|
82
|
+
* `protected` does not mean ungated: `protectedProcedure` runs the
|
|
83
|
+
* `METHOD_ACCESS_MAP` scope check, and every method here is `scope: 'device'`
|
|
84
|
+
* with `access: 'create'` and a `deviceId` in its input. So a caller needs a
|
|
85
|
+
* grant that covers THAT camera at `create` — a `camera-viewer` (`view`
|
|
86
|
+
* only) still cannot talk, and a grant on camera 5 cannot talk through
|
|
87
|
+
* camera 7.
|
|
88
|
+
*
|
|
89
|
+
* Every method was `auth: 'admin'` from the initial commit, which made the
|
|
90
|
+
* cap unreachable by every non-admin principal — `adminProcedure` throws
|
|
91
|
+
* `FORBIDDEN: Admin required` BEFORE the scope check runs, so the scope
|
|
92
|
+
* machinery generated for this cap (`METHOD_ACCESS_MAP`,
|
|
93
|
+
* `DEVICE_SCOPED_CAPS`, `METHOD_DEVICE_SELECTORS`) was complete and dead. The
|
|
94
|
+
* `camera-operator` scope preset has promised "PTZ control, intercom,
|
|
95
|
+
* snapshots" since that same commit; the promise could not be kept. Recorded
|
|
96
|
+
* as D289; `scripts/check-scope-preset-promises.ts` now fails the build if a
|
|
97
|
+
* preset promises a cap no row of that preset can reach.
|
|
98
|
+
*/
|
|
72
99
|
readonly methods: {
|
|
73
100
|
/**
|
|
74
101
|
* Open a server-side WebRTC audio-only session. Returns an SDP
|
|
@@ -196,6 +196,45 @@ declare const NodeProcessSchema: z.ZodObject<{
|
|
|
196
196
|
threadCount: z.ZodNullable<z.ZodNumber>;
|
|
197
197
|
uptimeSec: z.ZodNumber;
|
|
198
198
|
}, z.core.$strip>;
|
|
199
|
+
declare const ContainerMemorySnapshotSchema: z.ZodObject<{
|
|
200
|
+
source: z.ZodEnum<{
|
|
201
|
+
"cgroup-v2": "cgroup-v2";
|
|
202
|
+
"cgroup-v1": "cgroup-v1";
|
|
203
|
+
}>;
|
|
204
|
+
currentBytes: z.ZodNumber;
|
|
205
|
+
limitBytes: z.ZodNullable<z.ZodNumber>;
|
|
206
|
+
anonBytes: z.ZodNullable<z.ZodNumber>;
|
|
207
|
+
fileBytes: z.ZodNullable<z.ZodNumber>;
|
|
208
|
+
shmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
209
|
+
slabBytes: z.ZodNullable<z.ZodNumber>;
|
|
210
|
+
gpuShmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
211
|
+
}, z.core.$strip>;
|
|
212
|
+
/**
|
|
213
|
+
* One retained container-memory reading.
|
|
214
|
+
*
|
|
215
|
+
* `atMs` is the timestamp of the PROCESS snapshot taken in the same tick, not
|
|
216
|
+
* a second clock: that is what makes "processes sum to X, container says Y"
|
|
217
|
+
* subtractable per point rather than an eyeballed comparison of two series
|
|
218
|
+
* sampled at different instants.
|
|
219
|
+
*
|
|
220
|
+
* A reduced window keeps the sample with the LARGEST `currentBytes` in each
|
|
221
|
+
* bucket, WHOLE. Taking a per-field maximum would synthesise a row whose parts
|
|
222
|
+
* never coexisted, and a mean would smear away the peak this exists to find.
|
|
223
|
+
*/
|
|
224
|
+
declare const ContainerMemoryPointSchema: z.ZodObject<{
|
|
225
|
+
source: z.ZodEnum<{
|
|
226
|
+
"cgroup-v2": "cgroup-v2";
|
|
227
|
+
"cgroup-v1": "cgroup-v1";
|
|
228
|
+
}>;
|
|
229
|
+
currentBytes: z.ZodNumber;
|
|
230
|
+
limitBytes: z.ZodNullable<z.ZodNumber>;
|
|
231
|
+
anonBytes: z.ZodNullable<z.ZodNumber>;
|
|
232
|
+
fileBytes: z.ZodNullable<z.ZodNumber>;
|
|
233
|
+
shmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
234
|
+
slabBytes: z.ZodNullable<z.ZodNumber>;
|
|
235
|
+
gpuShmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
236
|
+
atMs: z.ZodNumber;
|
|
237
|
+
}, z.core.$strip>;
|
|
199
238
|
declare const DumpHeapSnapshotInputSchema: z.ZodObject<{
|
|
200
239
|
addonId: z.ZodString;
|
|
201
240
|
}, z.core.$strip>;
|
|
@@ -280,6 +319,20 @@ declare const NodeLoadSeriesSchema: z.ZodObject<{
|
|
|
280
319
|
processCountMin: z.ZodNumber;
|
|
281
320
|
}, z.core.$strip>>>;
|
|
282
321
|
}, z.core.$strip>>>;
|
|
322
|
+
containerMemory: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
323
|
+
source: z.ZodEnum<{
|
|
324
|
+
"cgroup-v2": "cgroup-v2";
|
|
325
|
+
"cgroup-v1": "cgroup-v1";
|
|
326
|
+
}>;
|
|
327
|
+
currentBytes: z.ZodNumber;
|
|
328
|
+
limitBytes: z.ZodNullable<z.ZodNumber>;
|
|
329
|
+
anonBytes: z.ZodNullable<z.ZodNumber>;
|
|
330
|
+
fileBytes: z.ZodNullable<z.ZodNumber>;
|
|
331
|
+
shmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
332
|
+
slabBytes: z.ZodNullable<z.ZodNumber>;
|
|
333
|
+
gpuShmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
334
|
+
atMs: z.ZodNumber;
|
|
335
|
+
}, z.core.$strip>>>;
|
|
283
336
|
bucketMs: z.ZodNumber;
|
|
284
337
|
retainedSamples: z.ZodNumber;
|
|
285
338
|
oldestAtMs: z.ZodNullable<z.ZodNumber>;
|
|
@@ -641,6 +694,20 @@ export declare const metricsProviderCapability: {
|
|
|
641
694
|
processCountMin: z.ZodNumber;
|
|
642
695
|
}, z.core.$strip>>>;
|
|
643
696
|
}, z.core.$strip>>>;
|
|
697
|
+
containerMemory: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
698
|
+
source: z.ZodEnum<{
|
|
699
|
+
"cgroup-v2": "cgroup-v2";
|
|
700
|
+
"cgroup-v1": "cgroup-v1";
|
|
701
|
+
}>;
|
|
702
|
+
currentBytes: z.ZodNumber;
|
|
703
|
+
limitBytes: z.ZodNullable<z.ZodNumber>;
|
|
704
|
+
anonBytes: z.ZodNullable<z.ZodNumber>;
|
|
705
|
+
fileBytes: z.ZodNullable<z.ZodNumber>;
|
|
706
|
+
shmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
707
|
+
slabBytes: z.ZodNullable<z.ZodNumber>;
|
|
708
|
+
gpuShmemBytes: z.ZodNullable<z.ZodNumber>;
|
|
709
|
+
atMs: z.ZodNumber;
|
|
710
|
+
}, z.core.$strip>>>;
|
|
644
711
|
bucketMs: z.ZodNumber;
|
|
645
712
|
retainedSamples: z.ZodNumber;
|
|
646
713
|
oldestAtMs: z.ZodNullable<z.ZodNumber>;
|
|
@@ -666,4 +733,4 @@ export declare const metricsProviderCapability: {
|
|
|
666
733
|
};
|
|
667
734
|
};
|
|
668
735
|
export type IMetricsProvider = InferProvider<typeof metricsProviderCapability>;
|
|
669
|
-
export { SystemMetricsSchema, SystemResourceSnapshotSchema, DiskSpaceInfoSchema, MetricsGpuInfoSchema, PidResourceStatsSchema, AddonInstanceSchema, NodeProcessSchema, DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, LoadPointSchema, LoadFunctionSeriesSchema, NodeLoadSeriesSchema, GetLoadSeriesInputSchema, CpuBreakdownSchema, MemoryInfoSchema, DiskIoSnapshotSchema, NetworkIoSnapshotSchema, ProcessResourceInfoSchema, PressureInfoSchema, };
|
|
736
|
+
export { SystemMetricsSchema, SystemResourceSnapshotSchema, DiskSpaceInfoSchema, MetricsGpuInfoSchema, PidResourceStatsSchema, AddonInstanceSchema, NodeProcessSchema, DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, LoadPointSchema, LoadFunctionSeriesSchema, ContainerMemorySnapshotSchema, ContainerMemoryPointSchema, NodeLoadSeriesSchema, GetLoadSeriesInputSchema, CpuBreakdownSchema, MemoryInfoSchema, DiskIoSnapshotSchema, NetworkIoSnapshotSchema, ProcessResourceInfoSchema, PressureInfoSchema, };
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* recording config. NOTE on events (source of truth, R5/C3): this cap carries
|
|
4
4
|
* NO event surface — `getPlaybackManifest` returns playlist URLs only. Timeline
|
|
5
5
|
* events (motion/object/audio) come from `pipelineAnalytics` (durable SQLite
|
|
6
|
-
* rows)
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* (`interfaces/recording-config.ts`).
|
|
6
|
+
* rows) and are the ONLY event surface — the recorder has none. The in-RAM
|
|
7
|
+
* playback markers it used to build were deleted on 2026-08-29 because nothing
|
|
8
|
+
* ever read them. Event<->footage joins are by time, padded with the shared
|
|
9
|
+
* `EVENT_PAD_MS` (`interfaces/recording-config.ts`).
|
|
10
10
|
*/
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import { type InferProvider } from './capability-definition.js';
|
package/dist/index.js
CHANGED
|
@@ -1885,11 +1885,10 @@ var DetectionCatalogClassMapSchema = zod.z.object({
|
|
|
1885
1885
|
* timestamp + postMs]`). Matches the admin-ui clip window (−5s/+10s).
|
|
1886
1886
|
*
|
|
1887
1887
|
* Every consumer derives from this ONE constant so event↔footage boundaries
|
|
1888
|
-
* agree everywhere (C1):
|
|
1889
|
-
*
|
|
1890
|
-
*
|
|
1891
|
-
*
|
|
1892
|
-
* their `startMs/endMs` with it.
|
|
1888
|
+
* agree everywhere (C1): today that is the `videoclips` default provider
|
|
1889
|
+
* (addon-post-analysis), which pads its clip windows with it. The recorder used
|
|
1890
|
+
* to pad in-RAM playback markers with it too; those markers had no reader
|
|
1891
|
+
* anywhere in the repo and were deleted on 2026-08-29.
|
|
1893
1892
|
*
|
|
1894
1893
|
* NOTE: this is a UI/JOIN convention, NOT the `events`-band keep/discard gate —
|
|
1895
1894
|
* that uses the per-device `preBufferSec`/`postBufferSec` config.
|
|
@@ -11898,6 +11897,50 @@ var NodeProcessSchema = zod.z.object({
|
|
|
11898
11897
|
/** Wall-clock uptime (seconds). Parsed from `ps etime`. */
|
|
11899
11898
|
uptimeSec: zod.z.number()
|
|
11900
11899
|
});
|
|
11900
|
+
/**
|
|
11901
|
+
* One retained container-memory reading.
|
|
11902
|
+
*
|
|
11903
|
+
* `atMs` is the timestamp of the PROCESS snapshot taken in the same tick, not
|
|
11904
|
+
* a second clock: that is what makes "processes sum to X, container says Y"
|
|
11905
|
+
* subtractable per point rather than an eyeballed comparison of two series
|
|
11906
|
+
* sampled at different instants.
|
|
11907
|
+
*
|
|
11908
|
+
* A reduced window keeps the sample with the LARGEST `currentBytes` in each
|
|
11909
|
+
* bucket, WHOLE. Taking a per-field maximum would synthesise a row whose parts
|
|
11910
|
+
* never coexisted, and a mean would smear away the peak this exists to find.
|
|
11911
|
+
*/
|
|
11912
|
+
var ContainerMemoryPointSchema = zod.z.object({
|
|
11913
|
+
/** Which hierarchy answered, so a reading is never ambiguous. */
|
|
11914
|
+
source: zod.z.enum(["cgroup-v2", "cgroup-v1"]),
|
|
11915
|
+
/** `memory.current` (v2) / `memory.usage_in_bytes` (v1). Always known. */
|
|
11916
|
+
currentBytes: zod.z.number(),
|
|
11917
|
+
/** The cgroup's ceiling. `null` = NO LIMIT — never a sentinel, never zero. */
|
|
11918
|
+
limitBytes: zod.z.number().nullable(),
|
|
11919
|
+
/** Anonymous pages: the closest thing to "what the processes allocated". */
|
|
11920
|
+
anonBytes: zod.z.number().nullable(),
|
|
11921
|
+
/** Page cache. Charged to the cgroup, owned by no process. */
|
|
11922
|
+
fileBytes: zod.z.number().nullable(),
|
|
11923
|
+
/**
|
|
11924
|
+
* Shared memory — and the field that explained the largest single surprise.
|
|
11925
|
+
* The i915 driver backs GPU buffers with shmem, so an inference pool or a
|
|
11926
|
+
* hardware-decode session holding DRM objects is charged HERE and appears
|
|
11927
|
+
* nowhere in a `ps` scan.
|
|
11928
|
+
*/
|
|
11929
|
+
shmemBytes: zod.z.number().nullable(),
|
|
11930
|
+
/** Kernel slab charged to this cgroup. `null` on v1, which never publishes it. */
|
|
11931
|
+
slabBytes: zod.z.number().nullable(),
|
|
11932
|
+
/**
|
|
11933
|
+
* Shrinkable i915 GEM object bytes, from debugfs.
|
|
11934
|
+
*
|
|
11935
|
+
* **Host-wide across every DRM client, NOT cgroup-scoped.** It is not a
|
|
11936
|
+
* component of `currentBytes` and must not be subtracted from it; it says
|
|
11937
|
+
* what put the shmem there, where `shmemBytes` only says how much.
|
|
11938
|
+
*
|
|
11939
|
+
* `null` wherever debugfs is not mounted — which is inside every camstack
|
|
11940
|
+
* container today — and on any node with no Intel GPU.
|
|
11941
|
+
*/
|
|
11942
|
+
gpuShmemBytes: zod.z.number().nullable()
|
|
11943
|
+
}).extend({ atMs: zod.z.number() });
|
|
11901
11944
|
var DumpHeapSnapshotInputSchema = zod.z.object({
|
|
11902
11945
|
/** The addon whose runner should dump a heap snapshot. */
|
|
11903
11946
|
addonId: zod.z.string() });
|
|
@@ -11961,6 +12004,21 @@ var NodeLoadSeriesSchema = zod.z.object({
|
|
|
11961
12004
|
/** One entry per function seen in the window, heaviest-first. */
|
|
11962
12005
|
series: zod.z.array(LoadFunctionSeriesSchema).readonly(),
|
|
11963
12006
|
/**
|
|
12007
|
+
* The CONTAINER's memory over the same window, oldest-first.
|
|
12008
|
+
*
|
|
12009
|
+
* Sits next to `series` rather than in a method of its own because the whole
|
|
12010
|
+
* question is a subtraction: the per-process rows in `series` sum to one
|
|
12011
|
+
* number and this one is another, and an operator who has to issue two calls
|
|
12012
|
+
* to compare them will compare two different instants. Same reader, same
|
|
12013
|
+
* `sinceMs`, same `bucketMs`, same timestamps.
|
|
12014
|
+
*
|
|
12015
|
+
* **EMPTY means ABSENT, never zero.** A node with no cgroup — a developer
|
|
12016
|
+
* Mac, a bare-metal host, a container with the hierarchy hidden — reports no
|
|
12017
|
+
* points at all. A zero here would be indistinguishable from a healthy
|
|
12018
|
+
* container and is precisely the lie this field exists to avoid.
|
|
12019
|
+
*/
|
|
12020
|
+
containerMemory: zod.z.array(ContainerMemoryPointSchema).readonly(),
|
|
12021
|
+
/**
|
|
11964
12022
|
* Width of one returned bucket, in ms. Equals the sampling cadence when no
|
|
11965
12023
|
* reduction was needed — so a caller can always say what one point covers
|
|
11966
12024
|
* without having to know whether it was reduced.
|
|
@@ -26599,6 +26657,33 @@ var intercomCapability = {
|
|
|
26599
26657
|
deviceNative: true,
|
|
26600
26658
|
mode: "singleton",
|
|
26601
26659
|
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
26660
|
+
/**
|
|
26661
|
+
* **Auth tier: `protected` on every method — deliberate, and load-bearing.**
|
|
26662
|
+
*
|
|
26663
|
+
* Talking through a camera is an OPERATE action, not a CONFIGURE one. This
|
|
26664
|
+
* cap has no configuration surface at all: all six methods open, feed and
|
|
26665
|
+
* close one live audio session against one `deviceId`. That is the same
|
|
26666
|
+
* authority as `ptz.move` or `snapshot.getSnapshot`, both `protected` — and
|
|
26667
|
+
* the opposite of `ptz.savePreset` / `snapshot.invalidateCache`, which are
|
|
26668
|
+
* `admin` because they change what the device IS.
|
|
26669
|
+
*
|
|
26670
|
+
* `protected` does not mean ungated: `protectedProcedure` runs the
|
|
26671
|
+
* `METHOD_ACCESS_MAP` scope check, and every method here is `scope: 'device'`
|
|
26672
|
+
* with `access: 'create'` and a `deviceId` in its input. So a caller needs a
|
|
26673
|
+
* grant that covers THAT camera at `create` — a `camera-viewer` (`view`
|
|
26674
|
+
* only) still cannot talk, and a grant on camera 5 cannot talk through
|
|
26675
|
+
* camera 7.
|
|
26676
|
+
*
|
|
26677
|
+
* Every method was `auth: 'admin'` from the initial commit, which made the
|
|
26678
|
+
* cap unreachable by every non-admin principal — `adminProcedure` throws
|
|
26679
|
+
* `FORBIDDEN: Admin required` BEFORE the scope check runs, so the scope
|
|
26680
|
+
* machinery generated for this cap (`METHOD_ACCESS_MAP`,
|
|
26681
|
+
* `DEVICE_SCOPED_CAPS`, `METHOD_DEVICE_SELECTORS`) was complete and dead. The
|
|
26682
|
+
* `camera-operator` scope preset has promised "PTZ control, intercom,
|
|
26683
|
+
* snapshots" since that same commit; the promise could not be kept. Recorded
|
|
26684
|
+
* as D289; `scripts/check-scope-preset-promises.ts` now fails the build if a
|
|
26685
|
+
* preset promises a cap no row of that preset can reach.
|
|
26686
|
+
*/
|
|
26602
26687
|
methods: {
|
|
26603
26688
|
/**
|
|
26604
26689
|
* Open a server-side WebRTC audio-only session. Returns an SDP
|
|
@@ -26611,7 +26696,7 @@ var intercomCapability = {
|
|
|
26611
26696
|
sdpOffer: zod.z.string()
|
|
26612
26697
|
}), {
|
|
26613
26698
|
kind: "mutation",
|
|
26614
|
-
auth: "
|
|
26699
|
+
auth: "protected"
|
|
26615
26700
|
}),
|
|
26616
26701
|
handleAnswer: require_sleep.method(zod.z.object({
|
|
26617
26702
|
deviceId: zod.z.number(),
|
|
@@ -26619,7 +26704,7 @@ var intercomCapability = {
|
|
|
26619
26704
|
sdpAnswer: zod.z.string()
|
|
26620
26705
|
}), zod.z.void(), {
|
|
26621
26706
|
kind: "mutation",
|
|
26622
|
-
auth: "
|
|
26707
|
+
auth: "protected"
|
|
26623
26708
|
}),
|
|
26624
26709
|
/** Close explicitly. Server also auto-closes on 30s idle. */
|
|
26625
26710
|
stopSession: require_sleep.method(zod.z.object({
|
|
@@ -26627,7 +26712,7 @@ var intercomCapability = {
|
|
|
26627
26712
|
sessionId: zod.z.string()
|
|
26628
26713
|
}), zod.z.void(), {
|
|
26629
26714
|
kind: "mutation",
|
|
26630
|
-
auth: "
|
|
26715
|
+
auth: "protected"
|
|
26631
26716
|
}),
|
|
26632
26717
|
/**
|
|
26633
26718
|
* Open a raw-PCM talk session (no WebRTC SDP plumbing). Used by
|
|
@@ -26640,7 +26725,7 @@ var intercomCapability = {
|
|
|
26640
26725
|
*/
|
|
26641
26726
|
startTalkSession: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.object({ sessionId: zod.z.string() }), {
|
|
26642
26727
|
kind: "mutation",
|
|
26643
|
-
auth: "
|
|
26728
|
+
auth: "protected"
|
|
26644
26729
|
}),
|
|
26645
26730
|
/**
|
|
26646
26731
|
* Push one chunk of talk-back audio onto the active talk session.
|
|
@@ -26675,12 +26760,12 @@ var intercomCapability = {
|
|
|
26675
26760
|
sequenceNumber: zod.z.number().int()
|
|
26676
26761
|
}), zod.z.object({ accepted: zod.z.boolean() }), {
|
|
26677
26762
|
kind: "mutation",
|
|
26678
|
-
auth: "
|
|
26763
|
+
auth: "protected"
|
|
26679
26764
|
}),
|
|
26680
26765
|
/** Close the raw-PCM talk session. Idempotent. */
|
|
26681
26766
|
endTalkSession: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
|
|
26682
26767
|
kind: "mutation",
|
|
26683
|
-
auth: "
|
|
26768
|
+
auth: "protected"
|
|
26684
26769
|
})
|
|
26685
26770
|
},
|
|
26686
26771
|
events: { onStatusChanged: { data: zod.z.object({
|
|
@@ -29953,10 +30038,10 @@ var rebootCapability = {
|
|
|
29953
30038
|
* recording config. NOTE on events (source of truth, R5/C3): this cap carries
|
|
29954
30039
|
* NO event surface — `getPlaybackManifest` returns playlist URLs only. Timeline
|
|
29955
30040
|
* events (motion/object/audio) come from `pipelineAnalytics` (durable SQLite
|
|
29956
|
-
* rows)
|
|
29957
|
-
*
|
|
29958
|
-
*
|
|
29959
|
-
* (`interfaces/recording-config.ts`).
|
|
30041
|
+
* rows) and are the ONLY event surface — the recorder has none. The in-RAM
|
|
30042
|
+
* playback markers it used to build were deleted on 2026-08-29 because nothing
|
|
30043
|
+
* ever read them. Event<->footage joins are by time, padded with the shared
|
|
30044
|
+
* `EVENT_PAD_MS` (`interfaces/recording-config.ts`).
|
|
29960
30045
|
*/
|
|
29961
30046
|
var RecordingStatusSchema = zod.z.object({
|
|
29962
30047
|
deviceId: zod.z.number(),
|
|
@@ -45896,7 +45981,7 @@ var SCOPE_PRESETS = [
|
|
|
45896
45981
|
{
|
|
45897
45982
|
id: "camera-operator",
|
|
45898
45983
|
label: "Camera operator",
|
|
45899
|
-
description: "Everything `camera-viewer` does plus PTZ
|
|
45984
|
+
description: "Everything `camera-viewer` does plus live control of every granted camera — PTZ movement, intercom talk-back and on-demand snapshots. Cannot delete devices, and grants nothing on system-scope caps (recording control, users, addons).",
|
|
45900
45985
|
rows: [{
|
|
45901
45986
|
type: "category",
|
|
45902
45987
|
target: "device",
|
package/dist/index.mjs
CHANGED
|
@@ -1884,11 +1884,10 @@ var DetectionCatalogClassMapSchema = z.object({
|
|
|
1884
1884
|
* timestamp + postMs]`). Matches the admin-ui clip window (−5s/+10s).
|
|
1885
1885
|
*
|
|
1886
1886
|
* Every consumer derives from this ONE constant so event↔footage boundaries
|
|
1887
|
-
* agree everywhere (C1):
|
|
1888
|
-
*
|
|
1889
|
-
*
|
|
1890
|
-
*
|
|
1891
|
-
* their `startMs/endMs` with it.
|
|
1887
|
+
* agree everywhere (C1): today that is the `videoclips` default provider
|
|
1888
|
+
* (addon-post-analysis), which pads its clip windows with it. The recorder used
|
|
1889
|
+
* to pad in-RAM playback markers with it too; those markers had no reader
|
|
1890
|
+
* anywhere in the repo and were deleted on 2026-08-29.
|
|
1892
1891
|
*
|
|
1893
1892
|
* NOTE: this is a UI/JOIN convention, NOT the `events`-band keep/discard gate —
|
|
1894
1893
|
* that uses the per-device `preBufferSec`/`postBufferSec` config.
|
|
@@ -11897,6 +11896,50 @@ var NodeProcessSchema = z.object({
|
|
|
11897
11896
|
/** Wall-clock uptime (seconds). Parsed from `ps etime`. */
|
|
11898
11897
|
uptimeSec: z.number()
|
|
11899
11898
|
});
|
|
11899
|
+
/**
|
|
11900
|
+
* One retained container-memory reading.
|
|
11901
|
+
*
|
|
11902
|
+
* `atMs` is the timestamp of the PROCESS snapshot taken in the same tick, not
|
|
11903
|
+
* a second clock: that is what makes "processes sum to X, container says Y"
|
|
11904
|
+
* subtractable per point rather than an eyeballed comparison of two series
|
|
11905
|
+
* sampled at different instants.
|
|
11906
|
+
*
|
|
11907
|
+
* A reduced window keeps the sample with the LARGEST `currentBytes` in each
|
|
11908
|
+
* bucket, WHOLE. Taking a per-field maximum would synthesise a row whose parts
|
|
11909
|
+
* never coexisted, and a mean would smear away the peak this exists to find.
|
|
11910
|
+
*/
|
|
11911
|
+
var ContainerMemoryPointSchema = z.object({
|
|
11912
|
+
/** Which hierarchy answered, so a reading is never ambiguous. */
|
|
11913
|
+
source: z.enum(["cgroup-v2", "cgroup-v1"]),
|
|
11914
|
+
/** `memory.current` (v2) / `memory.usage_in_bytes` (v1). Always known. */
|
|
11915
|
+
currentBytes: z.number(),
|
|
11916
|
+
/** The cgroup's ceiling. `null` = NO LIMIT — never a sentinel, never zero. */
|
|
11917
|
+
limitBytes: z.number().nullable(),
|
|
11918
|
+
/** Anonymous pages: the closest thing to "what the processes allocated". */
|
|
11919
|
+
anonBytes: z.number().nullable(),
|
|
11920
|
+
/** Page cache. Charged to the cgroup, owned by no process. */
|
|
11921
|
+
fileBytes: z.number().nullable(),
|
|
11922
|
+
/**
|
|
11923
|
+
* Shared memory — and the field that explained the largest single surprise.
|
|
11924
|
+
* The i915 driver backs GPU buffers with shmem, so an inference pool or a
|
|
11925
|
+
* hardware-decode session holding DRM objects is charged HERE and appears
|
|
11926
|
+
* nowhere in a `ps` scan.
|
|
11927
|
+
*/
|
|
11928
|
+
shmemBytes: z.number().nullable(),
|
|
11929
|
+
/** Kernel slab charged to this cgroup. `null` on v1, which never publishes it. */
|
|
11930
|
+
slabBytes: z.number().nullable(),
|
|
11931
|
+
/**
|
|
11932
|
+
* Shrinkable i915 GEM object bytes, from debugfs.
|
|
11933
|
+
*
|
|
11934
|
+
* **Host-wide across every DRM client, NOT cgroup-scoped.** It is not a
|
|
11935
|
+
* component of `currentBytes` and must not be subtracted from it; it says
|
|
11936
|
+
* what put the shmem there, where `shmemBytes` only says how much.
|
|
11937
|
+
*
|
|
11938
|
+
* `null` wherever debugfs is not mounted — which is inside every camstack
|
|
11939
|
+
* container today — and on any node with no Intel GPU.
|
|
11940
|
+
*/
|
|
11941
|
+
gpuShmemBytes: z.number().nullable()
|
|
11942
|
+
}).extend({ atMs: z.number() });
|
|
11900
11943
|
var DumpHeapSnapshotInputSchema = z.object({
|
|
11901
11944
|
/** The addon whose runner should dump a heap snapshot. */
|
|
11902
11945
|
addonId: z.string() });
|
|
@@ -11960,6 +12003,21 @@ var NodeLoadSeriesSchema = z.object({
|
|
|
11960
12003
|
/** One entry per function seen in the window, heaviest-first. */
|
|
11961
12004
|
series: z.array(LoadFunctionSeriesSchema).readonly(),
|
|
11962
12005
|
/**
|
|
12006
|
+
* The CONTAINER's memory over the same window, oldest-first.
|
|
12007
|
+
*
|
|
12008
|
+
* Sits next to `series` rather than in a method of its own because the whole
|
|
12009
|
+
* question is a subtraction: the per-process rows in `series` sum to one
|
|
12010
|
+
* number and this one is another, and an operator who has to issue two calls
|
|
12011
|
+
* to compare them will compare two different instants. Same reader, same
|
|
12012
|
+
* `sinceMs`, same `bucketMs`, same timestamps.
|
|
12013
|
+
*
|
|
12014
|
+
* **EMPTY means ABSENT, never zero.** A node with no cgroup — a developer
|
|
12015
|
+
* Mac, a bare-metal host, a container with the hierarchy hidden — reports no
|
|
12016
|
+
* points at all. A zero here would be indistinguishable from a healthy
|
|
12017
|
+
* container and is precisely the lie this field exists to avoid.
|
|
12018
|
+
*/
|
|
12019
|
+
containerMemory: z.array(ContainerMemoryPointSchema).readonly(),
|
|
12020
|
+
/**
|
|
11963
12021
|
* Width of one returned bucket, in ms. Equals the sampling cadence when no
|
|
11964
12022
|
* reduction was needed — so a caller can always say what one point covers
|
|
11965
12023
|
* without having to know whether it was reduced.
|
|
@@ -26598,6 +26656,33 @@ var intercomCapability = {
|
|
|
26598
26656
|
deviceNative: true,
|
|
26599
26657
|
mode: "singleton",
|
|
26600
26658
|
deviceTypes: [DeviceType.Camera],
|
|
26659
|
+
/**
|
|
26660
|
+
* **Auth tier: `protected` on every method — deliberate, and load-bearing.**
|
|
26661
|
+
*
|
|
26662
|
+
* Talking through a camera is an OPERATE action, not a CONFIGURE one. This
|
|
26663
|
+
* cap has no configuration surface at all: all six methods open, feed and
|
|
26664
|
+
* close one live audio session against one `deviceId`. That is the same
|
|
26665
|
+
* authority as `ptz.move` or `snapshot.getSnapshot`, both `protected` — and
|
|
26666
|
+
* the opposite of `ptz.savePreset` / `snapshot.invalidateCache`, which are
|
|
26667
|
+
* `admin` because they change what the device IS.
|
|
26668
|
+
*
|
|
26669
|
+
* `protected` does not mean ungated: `protectedProcedure` runs the
|
|
26670
|
+
* `METHOD_ACCESS_MAP` scope check, and every method here is `scope: 'device'`
|
|
26671
|
+
* with `access: 'create'` and a `deviceId` in its input. So a caller needs a
|
|
26672
|
+
* grant that covers THAT camera at `create` — a `camera-viewer` (`view`
|
|
26673
|
+
* only) still cannot talk, and a grant on camera 5 cannot talk through
|
|
26674
|
+
* camera 7.
|
|
26675
|
+
*
|
|
26676
|
+
* Every method was `auth: 'admin'` from the initial commit, which made the
|
|
26677
|
+
* cap unreachable by every non-admin principal — `adminProcedure` throws
|
|
26678
|
+
* `FORBIDDEN: Admin required` BEFORE the scope check runs, so the scope
|
|
26679
|
+
* machinery generated for this cap (`METHOD_ACCESS_MAP`,
|
|
26680
|
+
* `DEVICE_SCOPED_CAPS`, `METHOD_DEVICE_SELECTORS`) was complete and dead. The
|
|
26681
|
+
* `camera-operator` scope preset has promised "PTZ control, intercom,
|
|
26682
|
+
* snapshots" since that same commit; the promise could not be kept. Recorded
|
|
26683
|
+
* as D289; `scripts/check-scope-preset-promises.ts` now fails the build if a
|
|
26684
|
+
* preset promises a cap no row of that preset can reach.
|
|
26685
|
+
*/
|
|
26601
26686
|
methods: {
|
|
26602
26687
|
/**
|
|
26603
26688
|
* Open a server-side WebRTC audio-only session. Returns an SDP
|
|
@@ -26610,7 +26695,7 @@ var intercomCapability = {
|
|
|
26610
26695
|
sdpOffer: z.string()
|
|
26611
26696
|
}), {
|
|
26612
26697
|
kind: "mutation",
|
|
26613
|
-
auth: "
|
|
26698
|
+
auth: "protected"
|
|
26614
26699
|
}),
|
|
26615
26700
|
handleAnswer: method(z.object({
|
|
26616
26701
|
deviceId: z.number(),
|
|
@@ -26618,7 +26703,7 @@ var intercomCapability = {
|
|
|
26618
26703
|
sdpAnswer: z.string()
|
|
26619
26704
|
}), z.void(), {
|
|
26620
26705
|
kind: "mutation",
|
|
26621
|
-
auth: "
|
|
26706
|
+
auth: "protected"
|
|
26622
26707
|
}),
|
|
26623
26708
|
/** Close explicitly. Server also auto-closes on 30s idle. */
|
|
26624
26709
|
stopSession: method(z.object({
|
|
@@ -26626,7 +26711,7 @@ var intercomCapability = {
|
|
|
26626
26711
|
sessionId: z.string()
|
|
26627
26712
|
}), z.void(), {
|
|
26628
26713
|
kind: "mutation",
|
|
26629
|
-
auth: "
|
|
26714
|
+
auth: "protected"
|
|
26630
26715
|
}),
|
|
26631
26716
|
/**
|
|
26632
26717
|
* Open a raw-PCM talk session (no WebRTC SDP plumbing). Used by
|
|
@@ -26639,7 +26724,7 @@ var intercomCapability = {
|
|
|
26639
26724
|
*/
|
|
26640
26725
|
startTalkSession: method(z.object({ deviceId: z.number() }), z.object({ sessionId: z.string() }), {
|
|
26641
26726
|
kind: "mutation",
|
|
26642
|
-
auth: "
|
|
26727
|
+
auth: "protected"
|
|
26643
26728
|
}),
|
|
26644
26729
|
/**
|
|
26645
26730
|
* Push one chunk of talk-back audio onto the active talk session.
|
|
@@ -26674,12 +26759,12 @@ var intercomCapability = {
|
|
|
26674
26759
|
sequenceNumber: z.number().int()
|
|
26675
26760
|
}), z.object({ accepted: z.boolean() }), {
|
|
26676
26761
|
kind: "mutation",
|
|
26677
|
-
auth: "
|
|
26762
|
+
auth: "protected"
|
|
26678
26763
|
}),
|
|
26679
26764
|
/** Close the raw-PCM talk session. Idempotent. */
|
|
26680
26765
|
endTalkSession: method(z.object({ deviceId: z.number() }), z.void(), {
|
|
26681
26766
|
kind: "mutation",
|
|
26682
|
-
auth: "
|
|
26767
|
+
auth: "protected"
|
|
26683
26768
|
})
|
|
26684
26769
|
},
|
|
26685
26770
|
events: { onStatusChanged: { data: z.object({
|
|
@@ -29952,10 +30037,10 @@ var rebootCapability = {
|
|
|
29952
30037
|
* recording config. NOTE on events (source of truth, R5/C3): this cap carries
|
|
29953
30038
|
* NO event surface — `getPlaybackManifest` returns playlist URLs only. Timeline
|
|
29954
30039
|
* events (motion/object/audio) come from `pipelineAnalytics` (durable SQLite
|
|
29955
|
-
* rows)
|
|
29956
|
-
*
|
|
29957
|
-
*
|
|
29958
|
-
* (`interfaces/recording-config.ts`).
|
|
30040
|
+
* rows) and are the ONLY event surface — the recorder has none. The in-RAM
|
|
30041
|
+
* playback markers it used to build were deleted on 2026-08-29 because nothing
|
|
30042
|
+
* ever read them. Event<->footage joins are by time, padded with the shared
|
|
30043
|
+
* `EVENT_PAD_MS` (`interfaces/recording-config.ts`).
|
|
29959
30044
|
*/
|
|
29960
30045
|
var RecordingStatusSchema = z.object({
|
|
29961
30046
|
deviceId: z.number(),
|
|
@@ -45888,7 +45973,7 @@ var SCOPE_PRESETS = [
|
|
|
45888
45973
|
{
|
|
45889
45974
|
id: "camera-operator",
|
|
45890
45975
|
label: "Camera operator",
|
|
45891
|
-
description: "Everything `camera-viewer` does plus PTZ
|
|
45976
|
+
description: "Everything `camera-viewer` does plus live control of every granted camera — PTZ movement, intercom talk-back and on-demand snapshots. Cannot delete devices, and grants nothing on system-scope caps (recording control, users, addons).",
|
|
45892
45977
|
rows: [{
|
|
45893
45978
|
type: "category",
|
|
45894
45979
|
target: "device",
|
|
@@ -7,7 +7,7 @@ import type { PipelineEngineChoice } from '../types/pipeline.js';
|
|
|
7
7
|
import type { PipelineExecutionTrace, StepCadence } from '../types/pipeline-step.js';
|
|
8
8
|
import type { CameraMetrics } from './api-shared.js';
|
|
9
9
|
import type { FrameHandle } from './frame-handle.js';
|
|
10
|
-
import type { NodeProcess, SystemResourceSnapshot } from './metrics-provider.js';
|
|
10
|
+
import type { ContainerMemorySnapshot, NodeProcess, SystemResourceSnapshot } from './metrics-provider.js';
|
|
11
11
|
import type { RunnerLocalLoad } from './pipeline-runner-capability.js';
|
|
12
12
|
import type { BrokerStats } from './stream-broker.js';
|
|
13
13
|
export interface EventSource {
|
|
@@ -1198,6 +1198,16 @@ export interface EventCatalog {
|
|
|
1198
1198
|
readonly nodeId: string;
|
|
1199
1199
|
readonly processes: ReadonlyArray<NodeProcess>;
|
|
1200
1200
|
readonly timestamp: number;
|
|
1201
|
+
/**
|
|
1202
|
+
* The CONTAINER's memory at the SAME instant as `processes`, or `null`
|
|
1203
|
+
* when this node has no cgroup.
|
|
1204
|
+
*
|
|
1205
|
+
* It rides this event rather than one of its own for a single reason: the
|
|
1206
|
+
* question is a subtraction. The processes above sum to one number and
|
|
1207
|
+
* this is another, and two events would carry two timestamps that never
|
|
1208
|
+
* quite line up. `null` is ABSENT — never a zeroed reading.
|
|
1209
|
+
*/
|
|
1210
|
+
readonly containerMemory: ContainerMemorySnapshot | null;
|
|
1201
1211
|
};
|
|
1202
1212
|
/**
|
|
1203
1213
|
* Per-agent hwaccel override changed (set / cleared / re-probed). Payload
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
-
import type { CpuBreakdownSchema, MemoryInfoSchema, DiskIoSnapshotSchema, NetworkIoSnapshotSchema, MetricsGpuInfoSchema, ProcessResourceInfoSchema, PressureInfoSchema, SystemResourceSnapshotSchema, DiskSpaceInfoSchema, PidResourceStatsSchema, AddonInstanceSchema, NodeProcessSchema, DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, LoadPointSchema, LoadFunctionSeriesSchema, NodeLoadSeriesSchema, GetLoadSeriesInputSchema } from '../capabilities/metrics-provider.cap.js';
|
|
2
|
+
import type { CpuBreakdownSchema, MemoryInfoSchema, DiskIoSnapshotSchema, NetworkIoSnapshotSchema, MetricsGpuInfoSchema, ProcessResourceInfoSchema, PressureInfoSchema, SystemResourceSnapshotSchema, DiskSpaceInfoSchema, PidResourceStatsSchema, AddonInstanceSchema, NodeProcessSchema, DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, LoadPointSchema, LoadFunctionSeriesSchema, ContainerMemorySnapshotSchema, ContainerMemoryPointSchema, NodeLoadSeriesSchema, GetLoadSeriesInputSchema } from '../capabilities/metrics-provider.cap.js';
|
|
3
3
|
export type CpuBreakdown = z.infer<typeof CpuBreakdownSchema>;
|
|
4
4
|
export type MemoryInfo = z.infer<typeof MemoryInfoSchema>;
|
|
5
5
|
export type DiskIoSnapshot = z.infer<typeof DiskIoSnapshotSchema>;
|
|
@@ -16,5 +16,7 @@ export type DumpHeapSnapshotInput = z.infer<typeof DumpHeapSnapshotInputSchema>;
|
|
|
16
16
|
export type DumpHeapSnapshotResult = z.infer<typeof DumpHeapSnapshotResultSchema>;
|
|
17
17
|
export type LoadSeriesPoint = z.infer<typeof LoadPointSchema>;
|
|
18
18
|
export type LoadFunctionSeries = z.infer<typeof LoadFunctionSeriesSchema>;
|
|
19
|
+
export type ContainerMemorySnapshot = z.infer<typeof ContainerMemorySnapshotSchema>;
|
|
20
|
+
export type ContainerMemoryPoint = z.infer<typeof ContainerMemoryPointSchema>;
|
|
19
21
|
export type NodeLoadSeries = z.infer<typeof NodeLoadSeriesSchema>;
|
|
20
22
|
export type GetLoadSeriesInput = z.infer<typeof GetLoadSeriesInputSchema>;
|
|
@@ -6,11 +6,10 @@ import { type CamProfile } from '../capabilities/schemas/streaming-shared.js';
|
|
|
6
6
|
* timestamp + postMs]`). Matches the admin-ui clip window (−5s/+10s).
|
|
7
7
|
*
|
|
8
8
|
* Every consumer derives from this ONE constant so event↔footage boundaries
|
|
9
|
-
* agree everywhere (C1):
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* their `startMs/endMs` with it.
|
|
9
|
+
* agree everywhere (C1): today that is the `videoclips` default provider
|
|
10
|
+
* (addon-post-analysis), which pads its clip windows with it. The recorder used
|
|
11
|
+
* to pad in-RAM playback markers with it too; those markers had no reader
|
|
12
|
+
* anywhere in the repo and were deleted on 2026-08-29.
|
|
14
13
|
*
|
|
15
14
|
* NOTE: this is a UI/JOIN convention, NOT the `events`-band keep/discard gate —
|
|
16
15
|
* that uses the per-device `preBufferSec`/`postBufferSec` config.
|