@camstack/addon-pipeline 1.2.40 → 1.2.41
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +2 -2
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-DcMBfoCg.js → dist-BS7wLqoV.js} +264 -5
- package/dist/{dist-C6p8jcji.mjs → dist-DvUTPZ8J.mjs} +264 -5
- package/dist/{event-loop-stall-monitor-oL9xanvX.js → event-loop-stall-monitor-C5P2bcwP.js} +1 -1
- package/dist/{event-loop-stall-monitor-BHqCesa1.mjs → event-loop-stall-monitor-a2u9e1qx.mjs} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +2 -2
- package/dist/pipeline-runner/index.mjs +2 -2
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/session-decode/decode-worker-child.js +39 -2
- package/dist/session-decode/decode-worker-child.mjs +39 -2
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Bt1YkfUW.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CS82x0lt.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CDzxDzcv.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CciPNnL7.mjs +26 -0
- package/dist/stream-broker/{hostInit-Dyj8Vaql.mjs → hostInit-lj4kKHrb.mjs} +3 -3
- package/dist/stream-broker/index.js +1 -1
- package/dist/stream-broker/index.mjs +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-m1RaK_7F.js → MaskShapeCanvas-DI4BY7W2-BRQ5u_mo.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-C00UIgFo.js → MotionZonesSettings-NcxxQN8r-KbOg5nD9.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-DWYllToj.js → PrivacyMaskSettings-APgPLF7p-CKSPn3_D.js} +1 -1
- package/embed-dist/assets/index-CGdwTcwE.css +2 -0
- package/embed-dist/assets/{index-BaUgbxWl.js → index-CbrEyYGW.js} +12 -12
- package/embed-dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DJnh97n9.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BsNhZnfZ.mjs +0 -26
- package/embed-dist/assets/index-4fJzjj4H.css +0 -2
|
@@ -9666,7 +9666,68 @@ var NcZoneConditionSchema = object({
|
|
|
9666
9666
|
* The P1 condition set — a flat AND of groups; absent group = pass;
|
|
9667
9667
|
* membership lists are OR within the list (spec §2.3).
|
|
9668
9668
|
*/
|
|
9669
|
+
/**
|
|
9670
|
+
* What a rule may actuate.
|
|
9671
|
+
*
|
|
9672
|
+
* **No hand-maintained allowlist** (operator decision, and the right one — a
|
|
9673
|
+
* written list of methods is a third parallel map to keep aligned, and this
|
|
9674
|
+
* repo has paid for those). The boundary instead comes from a property the
|
|
9675
|
+
* capabilities already carry: an action may target only a **device-scoped**
|
|
9676
|
+
* capability method.
|
|
9677
|
+
*
|
|
9678
|
+
* That is not decoration. A rule can be authored by a NON-ADMIN — personal
|
|
9679
|
+
* rules are a supported flow — and the executor runs with the addon's
|
|
9680
|
+
* privileges, so an unbounded action is an arbitrary RPC channel with a
|
|
9681
|
+
* privilege escalation attached. Restricting to device scope excludes the
|
|
9682
|
+
* system caps (`device-manager.removeDevice` and friends) by construction,
|
|
9683
|
+
* costs nothing to maintain, and cannot rot: a cap that stops being
|
|
9684
|
+
* device-scoped stops being actuatable in the same change.
|
|
9685
|
+
*
|
|
9686
|
+
* The executor enforces it; {@link NcRuleActionSchema} carries the intent.
|
|
9687
|
+
*/
|
|
9688
|
+
/**
|
|
9689
|
+
* One step of a sequence.
|
|
9690
|
+
*
|
|
9691
|
+
* `wait` is a first-class step rather than a property of the next action: it is
|
|
9692
|
+
* what makes a sequence a SEQUENCE and not a list — "unlock, wait 5s, open"
|
|
9693
|
+
* cannot be expressed otherwise.
|
|
9694
|
+
*/
|
|
9695
|
+
var NcRuleActionSchema = discriminatedUnion("kind", [object({
|
|
9696
|
+
kind: literal("wait"),
|
|
9697
|
+
seconds: number().min(0).max(300)
|
|
9698
|
+
}), object({
|
|
9699
|
+
kind: literal("cap"),
|
|
9700
|
+
deviceId: number().int(),
|
|
9701
|
+
/** Capability name, e.g. `alarm-panel`. */
|
|
9702
|
+
cap: string().min(1),
|
|
9703
|
+
/** Method on it. The executor refuses a non-device-scoped cap. */
|
|
9704
|
+
method: string().min(1),
|
|
9705
|
+
/** Method arguments, minus `deviceId` (the executor injects it). */
|
|
9706
|
+
args: record(string(), unknown()).optional()
|
|
9707
|
+
})]);
|
|
9708
|
+
/**
|
|
9709
|
+
* Sequences a rule runs, by hook point.
|
|
9710
|
+
*
|
|
9711
|
+
* ONLY `onTrigger` is here, deliberately. The reference also has activation /
|
|
9712
|
+
* deactivation / reset / post-generation hooks, and they are wanted — but this
|
|
9713
|
+
* repo's expensive failure mode is declaring a surface nothing produces, so a
|
|
9714
|
+
* hook appears here in the same change that produces its edge, never before.
|
|
9715
|
+
*/
|
|
9716
|
+
var NcRuleActionsSchema = object({
|
|
9717
|
+
/** Runs when the rule MATCHES. */
|
|
9718
|
+
onTrigger: array(object({
|
|
9719
|
+
name: string().min(1).max(120),
|
|
9720
|
+
enabled: boolean(),
|
|
9721
|
+
minDelaySec: number().int().min(0).max(86400).optional(),
|
|
9722
|
+
actions: array(NcRuleActionSchema).min(1)
|
|
9723
|
+
})).optional() });
|
|
9669
9724
|
var NcConditionsSchema = object({
|
|
9725
|
+
/** Gate on ANOTHER device's current state (the alarm armed, a switch on). */
|
|
9726
|
+
deviceState: object({
|
|
9727
|
+
deviceId: number().int(),
|
|
9728
|
+
/** Any of these matches. */
|
|
9729
|
+
states: array(string().min(1)).min(1)
|
|
9730
|
+
}).optional(),
|
|
9670
9731
|
/** Device scope — absent = all devices. */
|
|
9671
9732
|
devices: array(number()).optional(),
|
|
9672
9733
|
/** Detector class names (any overlap with the record's class set). */
|
|
@@ -9960,7 +10021,16 @@ var NcRuleInputSchema = object({
|
|
|
9960
10021
|
* read as `false` by {@link canSetGlobal} in the engine. Admins are not bound
|
|
9961
10022
|
* by this flag — see the scope rules on that function.
|
|
9962
10023
|
*/
|
|
9963
|
-
snoozeAllowGlobal: boolean().optional()
|
|
10024
|
+
snoozeAllowGlobal: boolean().optional(),
|
|
10025
|
+
/**
|
|
10026
|
+
* Devices this rule ACTUATES — arm the alarm, open a gate, turn on a light.
|
|
10027
|
+
*
|
|
10028
|
+
* This is what makes the rule set the alarm's trigger set without the alarm
|
|
10029
|
+
* being a special case: arming is
|
|
10030
|
+
* `{ cap: 'alarm-panel', method: 'arm', args: { mode: 'away' } }`, the same
|
|
10031
|
+
* shape as every other actuation.
|
|
10032
|
+
*/
|
|
10033
|
+
actions: NcRuleActionsSchema.optional()
|
|
9964
10034
|
});
|
|
9965
10035
|
/**
|
|
9966
10036
|
* Partial patch for `updateRule` — any subset of the input fields, plus the
|
|
@@ -10031,7 +10101,8 @@ var NcConditionDescriptorSchema = object({
|
|
|
10031
10101
|
"packagePhase",
|
|
10032
10102
|
"crossingSelect",
|
|
10033
10103
|
"polygonDraw",
|
|
10034
|
-
"occupancy"
|
|
10104
|
+
"occupancy",
|
|
10105
|
+
"deviceState"
|
|
10035
10106
|
]),
|
|
10036
10107
|
operator: _enum([
|
|
10037
10108
|
"in",
|
|
@@ -17316,7 +17387,20 @@ method(object({
|
|
|
17316
17387
|
}), _void(), {
|
|
17317
17388
|
kind: "mutation",
|
|
17318
17389
|
auth: "admin"
|
|
17319
|
-
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({
|
|
17390
|
+
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({
|
|
17391
|
+
addonId: string().optional(),
|
|
17392
|
+
/**
|
|
17393
|
+
* `slim` omits `config` (returned `{}`), `metadata` (null) and the
|
|
17394
|
+
* `sourceInfo` derived from config — and skips the per-device settings
|
|
17395
|
+
* read that produces them. Everything identifying a device (id, name,
|
|
17396
|
+
* type, online, features, isCamera, parent/link ids) is unchanged.
|
|
17397
|
+
* Do not use it for dispatch routing, which needs `sourceInfo`.
|
|
17398
|
+
*/
|
|
17399
|
+
projection: _enum(["full", "slim"]).optional(),
|
|
17400
|
+
/** Return only camera devices. Filtering server-side instead of
|
|
17401
|
+
* shipping 293 rows to find 12. */
|
|
17402
|
+
isCamera: boolean().optional()
|
|
17403
|
+
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
17320
17404
|
mode: DeviceLinkModeSchema,
|
|
17321
17405
|
devices: array(LinkedDeviceSchema)
|
|
17322
17406
|
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
@@ -18515,6 +18599,103 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
18515
18599
|
enabled: boolean()
|
|
18516
18600
|
}), _void(), { kind: "mutation" });
|
|
18517
18601
|
/**
|
|
18602
|
+
* core-blocks — user-authored TypeScript, stored in the kernel and executed in
|
|
18603
|
+
* its own process.
|
|
18604
|
+
*
|
|
18605
|
+
* Spec: `docs/superpowers/specs/2026-08-04-core-blocks-and-synthetic-devices-design.md`.
|
|
18606
|
+
*
|
|
18607
|
+
* The first use is **owning devices without being a device provider**: a block
|
|
18608
|
+
* declares devices under a system or custom integration and drives their state,
|
|
18609
|
+
* with the same `ctx` an addon gets. Automations come later; nothing here
|
|
18610
|
+
* models a trigger.
|
|
18611
|
+
*
|
|
18612
|
+
* **Stated plainly, because it does not change by being true:** a block has an
|
|
18613
|
+
* addon's powers — devices, storage, the event bus, `ctx.api`. It is a plugin
|
|
18614
|
+
* with no review step. What makes that survivable is not a sandbox, it is
|
|
18615
|
+
* PROCESS ISOLATION: one process per block, supervised by `CrashSupervisor`,
|
|
18616
|
+
* so a block that throws or never returns is marked `failed` and visible
|
|
18617
|
+
* instead of taking the hub with it (D6). Every method here is admin-only, and
|
|
18618
|
+
* must stay so.
|
|
18619
|
+
*/
|
|
18620
|
+
/** Where a block runs. The operator chooses — a block driving a device on an
|
|
18621
|
+
* agent is the reason placement is not fixed to the hub. */
|
|
18622
|
+
var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
|
|
18623
|
+
/** What a block's process is doing. Mirrors the addon runner's own lifecycle so
|
|
18624
|
+
* a failing block reads the same way a failing addon does. */
|
|
18625
|
+
var CoreBlockStatusSchema = _enum([
|
|
18626
|
+
"stopped",
|
|
18627
|
+
"starting",
|
|
18628
|
+
"running",
|
|
18629
|
+
"failed"
|
|
18630
|
+
]);
|
|
18631
|
+
/** Client-authored fields. */
|
|
18632
|
+
var CoreBlockInputSchema = object({
|
|
18633
|
+
name: string().min(1).max(120),
|
|
18634
|
+
/** TypeScript source. Compiled server-side before it is ever stored — a
|
|
18635
|
+
* block that does not compile is a fork failure the operator would meet
|
|
18636
|
+
* minutes later, in a log, instead of in the editor. */
|
|
18637
|
+
code: string().max(2e5),
|
|
18638
|
+
enabled: boolean(),
|
|
18639
|
+
placement: CoreBlockPlacementSchema,
|
|
18640
|
+
/**
|
|
18641
|
+
* Integration the block's devices hang from. Absent = the system integration
|
|
18642
|
+
* blocks share. A block may declare its own instead.
|
|
18643
|
+
*/
|
|
18644
|
+
integrationId: string().optional()
|
|
18645
|
+
});
|
|
18646
|
+
/** A stored block. */
|
|
18647
|
+
var CoreBlockSchema = CoreBlockInputSchema.extend({
|
|
18648
|
+
id: string(),
|
|
18649
|
+
createdAt: number(),
|
|
18650
|
+
updatedAt: number(),
|
|
18651
|
+
/** Server-stamped author. */
|
|
18652
|
+
createdBy: string(),
|
|
18653
|
+
status: CoreBlockStatusSchema,
|
|
18654
|
+
/**
|
|
18655
|
+
* Why the block is not running, when it is not. The operator's ONLY window
|
|
18656
|
+
* into a block that failed at load — a block that is silently absent is the
|
|
18657
|
+
* failure mode this whole feature has to avoid.
|
|
18658
|
+
*/
|
|
18659
|
+
lastError: string().optional(),
|
|
18660
|
+
/** Ms epoch of the last state change. */
|
|
18661
|
+
lastChangedAt: number()
|
|
18662
|
+
});
|
|
18663
|
+
/** What a compile attempt produced. */
|
|
18664
|
+
var CoreBlockCompileResultSchema = object({
|
|
18665
|
+
ok: boolean(),
|
|
18666
|
+
/** Present when `ok` is false — the first error, in the author's words. */
|
|
18667
|
+
error: string().optional(),
|
|
18668
|
+
line: number().optional(),
|
|
18669
|
+
column: number().optional()
|
|
18670
|
+
});
|
|
18671
|
+
method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }), method(object({ blockId: string() }), object({ block: CoreBlockSchema.nullable() }), { auth: "admin" }), method(object({ block: CoreBlockInputSchema }), object({ block: CoreBlockSchema }), {
|
|
18672
|
+
kind: "mutation",
|
|
18673
|
+
auth: "admin",
|
|
18674
|
+
caller: "required"
|
|
18675
|
+
}), method(object({
|
|
18676
|
+
blockId: string(),
|
|
18677
|
+
block: CoreBlockInputSchema.partial()
|
|
18678
|
+
}), object({ block: CoreBlockSchema }), {
|
|
18679
|
+
kind: "mutation",
|
|
18680
|
+
auth: "admin",
|
|
18681
|
+
caller: "required"
|
|
18682
|
+
}), method(object({ blockId: string() }), object({ success: literal(true) }), {
|
|
18683
|
+
kind: "mutation",
|
|
18684
|
+
auth: "admin"
|
|
18685
|
+
}), method(object({
|
|
18686
|
+
blockId: string(),
|
|
18687
|
+
enabled: boolean()
|
|
18688
|
+
}), object({ block: CoreBlockSchema }), {
|
|
18689
|
+
kind: "mutation",
|
|
18690
|
+
auth: "admin"
|
|
18691
|
+
}), method(object({ code: string() }), CoreBlockCompileResultSchema, {
|
|
18692
|
+
kind: "mutation",
|
|
18693
|
+
auth: "admin"
|
|
18694
|
+
}), method(object({}), object({ libs: array(object({
|
|
18695
|
+
filePath: string(),
|
|
18696
|
+
content: string()
|
|
18697
|
+
})) }), { auth: "admin" });
|
|
18698
|
+
/**
|
|
18518
18699
|
* Zod schemas for persisted record types.
|
|
18519
18700
|
*
|
|
18520
18701
|
* These schemas serve as the single source of truth for types that are
|
|
@@ -18761,6 +18942,11 @@ var EventKindDescriptorSchema = object({
|
|
|
18761
18942
|
deviceId: number()
|
|
18762
18943
|
})
|
|
18763
18944
|
});
|
|
18945
|
+
/** One camera's event vocabulary, as returned by `listEventKindsBatch`. */
|
|
18946
|
+
var EventKindsForDeviceSchema = object({
|
|
18947
|
+
deviceId: number(),
|
|
18948
|
+
kinds: array(EventKindDescriptorSchema).readonly()
|
|
18949
|
+
});
|
|
18764
18950
|
var SensorEventSchema = object({
|
|
18765
18951
|
id: string(),
|
|
18766
18952
|
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
@@ -19017,6 +19203,19 @@ var MediaFileSchema = object({
|
|
|
19017
19203
|
sizeBytes: number(),
|
|
19018
19204
|
timestamp: number()
|
|
19019
19205
|
});
|
|
19206
|
+
/**
|
|
19207
|
+
* One media row WITHOUT its bytes.
|
|
19208
|
+
*
|
|
19209
|
+
* A track's media is 5-8 MB of base64 (measured: 7.67 MB across 23 files for a
|
|
19210
|
+
* 140 s track), and a client that renders tiles from the media data plane needs
|
|
19211
|
+
* to know only WHAT EXISTS — the bytes then arrive per tile, lazily, over HTTP
|
|
19212
|
+
* with an immutable cache, instead of all at once inside a tRPC response that
|
|
19213
|
+
* blocks the whole view.
|
|
19214
|
+
*
|
|
19215
|
+
* `sizeBytes` is carried because it is what lets a client decide between the
|
|
19216
|
+
* stored blob and a `?variant=thumb` rendering without fetching either.
|
|
19217
|
+
*/
|
|
19218
|
+
var MediaFileInfoSchema = MediaFileSchema.omit({ base64: true });
|
|
19020
19219
|
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
19021
19220
|
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
19022
19221
|
var DeviceEventQueryInput = object({
|
|
@@ -19166,7 +19365,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19166
19365
|
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
19167
19366
|
kind: "mutation",
|
|
19168
19367
|
auth: "admin"
|
|
19169
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19368
|
+
}), 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({
|
|
19170
19369
|
deviceId: number(),
|
|
19171
19370
|
since: number().optional(),
|
|
19172
19371
|
until: number().optional(),
|
|
@@ -19240,7 +19439,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19240
19439
|
}), array(MediaFileSchema).readonly()), method(object({
|
|
19241
19440
|
trackId: string(),
|
|
19242
19441
|
kinds: array(MediaFileKindEnum).optional()
|
|
19243
|
-
}), array(MediaFileSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), object({
|
|
19442
|
+
}), array(MediaFileSchema).readonly()), method(object({ trackId: string() }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), object({
|
|
19244
19443
|
deviceId: number(),
|
|
19245
19444
|
timestamp: number(),
|
|
19246
19445
|
frameWidth: number(),
|
|
@@ -24021,6 +24220,54 @@ Object.freeze({
|
|
|
24021
24220
|
addonId: null,
|
|
24022
24221
|
access: "create"
|
|
24023
24222
|
},
|
|
24223
|
+
"coreBlocks.compile": {
|
|
24224
|
+
capName: "core-blocks",
|
|
24225
|
+
capScope: "system",
|
|
24226
|
+
addonId: null,
|
|
24227
|
+
access: "create"
|
|
24228
|
+
},
|
|
24229
|
+
"coreBlocks.create": {
|
|
24230
|
+
capName: "core-blocks",
|
|
24231
|
+
capScope: "system",
|
|
24232
|
+
addonId: null,
|
|
24233
|
+
access: "create"
|
|
24234
|
+
},
|
|
24235
|
+
"coreBlocks.delete": {
|
|
24236
|
+
capName: "core-blocks",
|
|
24237
|
+
capScope: "system",
|
|
24238
|
+
addonId: null,
|
|
24239
|
+
access: "delete"
|
|
24240
|
+
},
|
|
24241
|
+
"coreBlocks.get": {
|
|
24242
|
+
capName: "core-blocks",
|
|
24243
|
+
capScope: "system",
|
|
24244
|
+
addonId: null,
|
|
24245
|
+
access: "view"
|
|
24246
|
+
},
|
|
24247
|
+
"coreBlocks.getTypeDefs": {
|
|
24248
|
+
capName: "core-blocks",
|
|
24249
|
+
capScope: "system",
|
|
24250
|
+
addonId: null,
|
|
24251
|
+
access: "view"
|
|
24252
|
+
},
|
|
24253
|
+
"coreBlocks.list": {
|
|
24254
|
+
capName: "core-blocks",
|
|
24255
|
+
capScope: "system",
|
|
24256
|
+
addonId: null,
|
|
24257
|
+
access: "view"
|
|
24258
|
+
},
|
|
24259
|
+
"coreBlocks.setEnabled": {
|
|
24260
|
+
capName: "core-blocks",
|
|
24261
|
+
capScope: "system",
|
|
24262
|
+
addonId: null,
|
|
24263
|
+
access: "create"
|
|
24264
|
+
},
|
|
24265
|
+
"coreBlocks.update": {
|
|
24266
|
+
capName: "core-blocks",
|
|
24267
|
+
capScope: "system",
|
|
24268
|
+
addonId: null,
|
|
24269
|
+
access: "create"
|
|
24270
|
+
},
|
|
24024
24271
|
"cover.close": {
|
|
24025
24272
|
capName: "cover",
|
|
24026
24273
|
capScope: "device",
|
|
@@ -26187,6 +26434,12 @@ Object.freeze({
|
|
|
26187
26434
|
addonId: null,
|
|
26188
26435
|
access: "view"
|
|
26189
26436
|
},
|
|
26437
|
+
"pipelineAnalytics.listEventKindsBatch": {
|
|
26438
|
+
capName: "pipeline-analytics",
|
|
26439
|
+
capScope: "device",
|
|
26440
|
+
addonId: null,
|
|
26441
|
+
access: "view"
|
|
26442
|
+
},
|
|
26190
26443
|
"pipelineAnalytics.listOpsLog": {
|
|
26191
26444
|
capName: "pipeline-analytics",
|
|
26192
26445
|
capScope: "device",
|
|
@@ -26199,6 +26452,12 @@ Object.freeze({
|
|
|
26199
26452
|
addonId: null,
|
|
26200
26453
|
access: "view"
|
|
26201
26454
|
},
|
|
26455
|
+
"pipelineAnalytics.listTrackMedia": {
|
|
26456
|
+
capName: "pipeline-analytics",
|
|
26457
|
+
capScope: "device",
|
|
26458
|
+
addonId: null,
|
|
26459
|
+
access: "view"
|
|
26460
|
+
},
|
|
26202
26461
|
"pipelineAnalytics.listTracks": {
|
|
26203
26462
|
capName: "pipeline-analytics",
|
|
26204
26463
|
capScope: "device",
|
package/dist/{event-loop-stall-monitor-BHqCesa1.mjs → event-loop-stall-monitor-a2u9e1qx.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-
|
|
1
|
+
import { D as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-DvUTPZ8J.mjs";
|
|
2
2
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
3
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
4
|
var HF_REPO = "camstack/camstack-models";
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-BS7wLqoV.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as motionDetectionCapability, E as evaluateZoneRules, K as hydrateSchema, V as BaseAddon, W as DeviceType } from "../dist-
|
|
1
|
+
import { A as motionDetectionCapability, E as evaluateZoneRules, K as hydrateSchema, V as BaseAddon, W as DeviceType } from "../dist-DvUTPZ8J.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-
|
|
6
|
+
const require_dist = require("../dist-BS7wLqoV.js");
|
|
7
|
+
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-C5P2bcwP.js");
|
|
8
8
|
const require_worker_protocol = require("../worker-protocol-DextwlTX.js");
|
|
9
9
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
10
10
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as errMsg, G as createEvent, M as pipelineRunnerCapability, S as defineCustomActions, V as BaseAddon, X as nodePin, at as lazy, b as customAction, ct as object, ft as EventCategory, nt as array, ot as literal, rt as boolean, s as DEVICE_BACKEND_TO_FORMAT, st as number, tt as _enum, ut as string } from "../dist-
|
|
2
|
-
import { c as getStepDefinition, t as attributeStall } from "../event-loop-stall-monitor-
|
|
1
|
+
import { B as errMsg, G as createEvent, M as pipelineRunnerCapability, S as defineCustomActions, V as BaseAddon, X as nodePin, at as lazy, b as customAction, ct as object, ft as EventCategory, nt as array, ot as literal, rt as boolean, s as DEVICE_BACKEND_TO_FORMAT, st as number, tt as _enum, ut as string } from "../dist-DvUTPZ8J.mjs";
|
|
2
|
+
import { c as getStepDefinition, t as attributeStall } from "../event-loop-stall-monitor-a2u9e1qx.mjs";
|
|
3
3
|
import { t as isWorkerReply } from "../worker-protocol-D7RzZIla.mjs";
|
|
4
4
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
5
5
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-BS7wLqoV.js");
|
|
3
3
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
4
4
|
const require_model_download_service_Cp9f4dk6 = require("../model-download-service-Cp9f4dk6-fsdDExML.js");
|
|
5
5
|
let node_child_process = require("node:child_process");
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as selectAssignedProfileSlots, B as errMsg, C as deriveRecordingMode, I as storageEvictableCapability, K as hydrateSchema, N as recordingCapability, P as recordingExportCapability, V as BaseAddon, W as DeviceType, X as nodePin, c as EVENT_PAD_MS, f as OpsLogEntrySchema, ft as EventCategory, lt as record, nt as array, p as RecordingConfigSchema, u as ExportRecordSchema, ut as string } from "../dist-
|
|
1
|
+
import { $ as selectAssignedProfileSlots, B as errMsg, C as deriveRecordingMode, I as storageEvictableCapability, K as hydrateSchema, N as recordingCapability, P as recordingExportCapability, V as BaseAddon, W as DeviceType, X as nodePin, c as EVENT_PAD_MS, f as OpsLogEntrySchema, ft as EventCategory, lt as record, nt as array, p as RecordingConfigSchema, u as ExportRecordSchema, ut as string } from "../dist-DvUTPZ8J.mjs";
|
|
2
2
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
3
3
|
import { n as createFileDataPlaneHandler, s as parseRangeHeader, t as contentTypeFor } from "../model-download-service-Cp9f4dk6-CwUb5v3Y.mjs";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
@@ -682,6 +682,15 @@ function toLeasedRgbNavFrame(frame) {
|
|
|
682
682
|
};
|
|
683
683
|
}
|
|
684
684
|
/** Re-dial backoff on a transient dial error/EOF (mirrors the decoder's PULL_REDIAL_MS). */
|
|
685
|
+
/**
|
|
686
|
+
* RSS at which a decode worker is reported anomalous.
|
|
687
|
+
*
|
|
688
|
+
* Chosen from the incident rather than from theory: on 2026-08-05 the healthy
|
|
689
|
+
* fleet sat at 1.1-1.3 GB per worker while the one that broke the host reached
|
|
690
|
+
* 4.9 GB. 2 GB is clear of the normal band and well below the point where it
|
|
691
|
+
* costs anyone anything.
|
|
692
|
+
*/
|
|
693
|
+
var WORKER_RSS_WARN_MB = 2048;
|
|
685
694
|
var REDIAL_MS = 3e3;
|
|
686
695
|
/** How often the worker emits its `framesDecoded/framesSkipped/deliveredFps` line. */
|
|
687
696
|
var METRICS_INTERVAL_MS = 1e4;
|
|
@@ -1079,6 +1088,12 @@ var DecodeWorkerChild = class {
|
|
|
1079
1088
|
/** Frames actually handed to the parent as a `frame` reply. */
|
|
1080
1089
|
framesDelivered = 0;
|
|
1081
1090
|
lastMetricsAt = 0;
|
|
1091
|
+
/** Process start, for the `ageS` field. A worker that outlives its siblings
|
|
1092
|
+
* by two orders of magnitude is the signal this exists to surface. */
|
|
1093
|
+
startedAt = Date.now();
|
|
1094
|
+
/** One-shot, so a legitimately long session does not repeat the warning
|
|
1095
|
+
* every ten seconds. */
|
|
1096
|
+
warnedLarge = false;
|
|
1082
1097
|
lastDeliveredSnapshot = 0;
|
|
1083
1098
|
metricsTimer = null;
|
|
1084
1099
|
demuxer = null;
|
|
@@ -1170,16 +1185,38 @@ var DecodeWorkerChild = class {
|
|
|
1170
1185
|
this.send({ kind: "ended" });
|
|
1171
1186
|
}
|
|
1172
1187
|
}
|
|
1173
|
-
/**
|
|
1188
|
+
/**
|
|
1189
|
+
* Emit the compact throughput line (window `deliveredFps`); cheap,
|
|
1190
|
+
* integer-only.
|
|
1191
|
+
*
|
|
1192
|
+
* **`rssMb` and `ageS` are here because their absence cost a Home Assistant
|
|
1193
|
+
* outage.** On 2026-08-05 one worker stayed alive 1h58m and grew to 4.9 GiB
|
|
1194
|
+
* at ~46 MB/min while its eleven siblings recycled every ~30 s; the host ran
|
|
1195
|
+
* out of memory and the kernel killed the largest process on the box, which
|
|
1196
|
+
* was somebody else's VM. Nothing in any log said a decode worker was large,
|
|
1197
|
+
* or old — the leak was only found by sampling `ps` by hand.
|
|
1198
|
+
*
|
|
1199
|
+
* This line already runs every 10 s per session and is already grouped by
|
|
1200
|
+
* device in Loki, so carrying the worker's own RSS and age turns "a runner
|
|
1201
|
+
* is big" into "THIS camera's worker has been climbing for an hour", which
|
|
1202
|
+
* is the question that was unanswerable. Retained-store sizes ride along
|
|
1203
|
+
* because they are the first thing to suspect and they are free to read.
|
|
1204
|
+
*/
|
|
1174
1205
|
logMetrics(final) {
|
|
1175
1206
|
const now = Date.now();
|
|
1176
1207
|
const windowMs = Math.max(1, now - this.lastMetricsAt);
|
|
1177
1208
|
const deliveredDelta = this.framesDelivered - this.lastDeliveredSnapshot;
|
|
1178
1209
|
const deliveredFps = Math.round(deliveredDelta / windowMs * 1e3 * 10) / 10;
|
|
1179
1210
|
const skipped = this.framesSkipped + this.frames.droppedCount;
|
|
1180
|
-
|
|
1211
|
+
const rssMb = Math.round(process.memoryUsage().rss / 1048576);
|
|
1212
|
+
const ageS = Math.round((now - this.startedAt) / 1e3);
|
|
1213
|
+
this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, rssMb:${rssMb}, ageS:${ageS}}${final ? " (final)" : ""}\n`);
|
|
1181
1214
|
this.lastMetricsAt = now;
|
|
1182
1215
|
this.lastDeliveredSnapshot = this.framesDelivered;
|
|
1216
|
+
if (!this.warnedLarge && rssMb >= WORKER_RSS_WARN_MB) {
|
|
1217
|
+
this.warnedLarge = true;
|
|
1218
|
+
this.emitStderr(`decode-worker-child: WORKER IS LARGE — rssMb=${rssMb} ageS=${ageS} framesDecoded=${this.framesDecoded}. Siblings normally recycle in ~30s; a worker this size at this age is how the host ran out of memory on 2026-08-05.\n`);
|
|
1219
|
+
}
|
|
1183
1220
|
}
|
|
1184
1221
|
handleStart(source, opts) {
|
|
1185
1222
|
if (this.started) {
|
|
@@ -678,6 +678,15 @@ function toLeasedRgbNavFrame(frame) {
|
|
|
678
678
|
};
|
|
679
679
|
}
|
|
680
680
|
/** Re-dial backoff on a transient dial error/EOF (mirrors the decoder's PULL_REDIAL_MS). */
|
|
681
|
+
/**
|
|
682
|
+
* RSS at which a decode worker is reported anomalous.
|
|
683
|
+
*
|
|
684
|
+
* Chosen from the incident rather than from theory: on 2026-08-05 the healthy
|
|
685
|
+
* fleet sat at 1.1-1.3 GB per worker while the one that broke the host reached
|
|
686
|
+
* 4.9 GB. 2 GB is clear of the normal band and well below the point where it
|
|
687
|
+
* costs anyone anything.
|
|
688
|
+
*/
|
|
689
|
+
var WORKER_RSS_WARN_MB = 2048;
|
|
681
690
|
var REDIAL_MS = 3e3;
|
|
682
691
|
/** How often the worker emits its `framesDecoded/framesSkipped/deliveredFps` line. */
|
|
683
692
|
var METRICS_INTERVAL_MS = 1e4;
|
|
@@ -1075,6 +1084,12 @@ var DecodeWorkerChild = class {
|
|
|
1075
1084
|
/** Frames actually handed to the parent as a `frame` reply. */
|
|
1076
1085
|
framesDelivered = 0;
|
|
1077
1086
|
lastMetricsAt = 0;
|
|
1087
|
+
/** Process start, for the `ageS` field. A worker that outlives its siblings
|
|
1088
|
+
* by two orders of magnitude is the signal this exists to surface. */
|
|
1089
|
+
startedAt = Date.now();
|
|
1090
|
+
/** One-shot, so a legitimately long session does not repeat the warning
|
|
1091
|
+
* every ten seconds. */
|
|
1092
|
+
warnedLarge = false;
|
|
1078
1093
|
lastDeliveredSnapshot = 0;
|
|
1079
1094
|
metricsTimer = null;
|
|
1080
1095
|
demuxer = null;
|
|
@@ -1166,16 +1181,38 @@ var DecodeWorkerChild = class {
|
|
|
1166
1181
|
this.send({ kind: "ended" });
|
|
1167
1182
|
}
|
|
1168
1183
|
}
|
|
1169
|
-
/**
|
|
1184
|
+
/**
|
|
1185
|
+
* Emit the compact throughput line (window `deliveredFps`); cheap,
|
|
1186
|
+
* integer-only.
|
|
1187
|
+
*
|
|
1188
|
+
* **`rssMb` and `ageS` are here because their absence cost a Home Assistant
|
|
1189
|
+
* outage.** On 2026-08-05 one worker stayed alive 1h58m and grew to 4.9 GiB
|
|
1190
|
+
* at ~46 MB/min while its eleven siblings recycled every ~30 s; the host ran
|
|
1191
|
+
* out of memory and the kernel killed the largest process on the box, which
|
|
1192
|
+
* was somebody else's VM. Nothing in any log said a decode worker was large,
|
|
1193
|
+
* or old — the leak was only found by sampling `ps` by hand.
|
|
1194
|
+
*
|
|
1195
|
+
* This line already runs every 10 s per session and is already grouped by
|
|
1196
|
+
* device in Loki, so carrying the worker's own RSS and age turns "a runner
|
|
1197
|
+
* is big" into "THIS camera's worker has been climbing for an hour", which
|
|
1198
|
+
* is the question that was unanswerable. Retained-store sizes ride along
|
|
1199
|
+
* because they are the first thing to suspect and they are free to read.
|
|
1200
|
+
*/
|
|
1170
1201
|
logMetrics(final) {
|
|
1171
1202
|
const now = Date.now();
|
|
1172
1203
|
const windowMs = Math.max(1, now - this.lastMetricsAt);
|
|
1173
1204
|
const deliveredDelta = this.framesDelivered - this.lastDeliveredSnapshot;
|
|
1174
1205
|
const deliveredFps = Math.round(deliveredDelta / windowMs * 1e3 * 10) / 10;
|
|
1175
1206
|
const skipped = this.framesSkipped + this.frames.droppedCount;
|
|
1176
|
-
|
|
1207
|
+
const rssMb = Math.round(process.memoryUsage().rss / 1048576);
|
|
1208
|
+
const ageS = Math.round((now - this.startedAt) / 1e3);
|
|
1209
|
+
this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, rssMb:${rssMb}, ageS:${ageS}}${final ? " (final)" : ""}\n`);
|
|
1177
1210
|
this.lastMetricsAt = now;
|
|
1178
1211
|
this.lastDeliveredSnapshot = this.framesDelivered;
|
|
1212
|
+
if (!this.warnedLarge && rssMb >= WORKER_RSS_WARN_MB) {
|
|
1213
|
+
this.warnedLarge = true;
|
|
1214
|
+
this.emitStderr(`decode-worker-child: WORKER IS LARGE — rssMb=${rssMb} ageS=${ageS} framesDecoded=${this.framesDecoded}. Siblings normally recycle in ~30s; a worker this size at this age is how the host ran out of memory on 2026-08-05.\n`);
|
|
1215
|
+
}
|
|
1179
1216
|
}
|
|
1180
1217
|
handleStart(source, opts) {
|
|
1181
1218
|
if (this.started) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-
|
|
1
|
+
import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CciPNnL7.mjs";
|
|
2
2
|
import { a as d, i as f, n as p, o as m, r as h, t as g } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.js-C9j-2lBe.mjs";
|
|
3
3
|
import { n as _, r as v, t as y } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-XO0-Pyu6.mjs";
|
|
4
4
|
import { n as b, t as x } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BO7TIbJV.mjs";
|
|
5
|
-
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-
|
|
5
|
+
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CDzxDzcv.mjs";
|
|
6
6
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
|
|
7
7
|
var C = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), w = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), T = (e) => {
|
|
8
8
|
let t = w(e);
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.10",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.31",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.25",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|