@camstack/addon-pipeline 1.2.307 → 1.2.309

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.
Files changed (33) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-DgdiQtQb.js → default-detection-model-BZMS04Wn.js} +1 -1
  4. package/dist/{default-detection-model-BV9bIuOo.mjs → default-detection-model-ClQ1gcZ9.mjs} +1 -1
  5. package/dist/detection-pipeline/index.js +4 -4
  6. package/dist/detection-pipeline/index.mjs +4 -4
  7. package/dist/{dist-DdVMFlJ6.mjs → dist-B3_sbBDM.mjs} +305 -48
  8. package/dist/{dist-CyJWk-_f.js → dist-BLf0YjAa.js} +310 -47
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-COu_tHy4.mjs → node-DJFKTJ0B.mjs} +1 -53
  12. package/dist/{node-HsWG5fGp.js → node-Vwf2PuIT.js} +1 -53
  13. package/dist/pipeline-runner/index.js +3 -3
  14. package/dist/pipeline-runner/index.mjs +3 -3
  15. package/dist/{process-memory-Bz3oIMzl.mjs → process-memory-BvwauBlX.mjs} +1 -1
  16. package/dist/{process-memory-TQXG7qrJ.js → process-memory-DGTVVYlX.js} +1 -1
  17. package/dist/recorder/index.js +147 -22
  18. package/dist/recorder/index.mjs +147 -22
  19. package/dist/{segment-demux-js-BrKa7tpr.js → segment-demux-js-BUAAuSVF.js} +22 -4
  20. package/dist/{segment-demux-js-CEJn4BR0.mjs → segment-demux-js-C0oz7IVm.mjs} +17 -5
  21. package/dist/stream-broker/_stub.js +2 -2
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DdYUVQSA.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-7H0Oxf23.mjs} +2 -2
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C6EaWavG.mjs +26 -0
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BhO-szf8.mjs +26 -0
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-D--a9rVM.mjs → hostInit-DEY-Dqqo.mjs} +2 -2
  28. package/dist/stream-broker/index.js +434 -111
  29. package/dist/stream-broker/index.mjs +434 -111
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DPHv0v3Q.mjs +0 -26
  33. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CdKbuxqG.mjs +0 -26
@@ -5370,7 +5370,7 @@ var ZodIssueCode = {
5370
5370
  var ZodFirstPartyTypeKind;
5371
5371
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5372
5372
  //#endregion
5373
- //#region ../types/dist/sleep-C-v96WpE.mjs
5373
+ //#region ../types/dist/sleep-gU6hqv4_.mjs
5374
5374
  /**
5375
5375
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5376
5376
  * window to float samples (D455).
@@ -7684,7 +7684,7 @@ function errMsg(err) {
7684
7684
  return String(err);
7685
7685
  }
7686
7686
  //#endregion
7687
- //#region ../types/dist/composition-BK-GTFYb.mjs
7687
+ //#region ../types/dist/composition-Dq42XWp0.mjs
7688
7688
  var AUDIO_ENCODER_BY_CODEC = {
7689
7689
  opus: "libopus",
7690
7690
  aac: "aac",
@@ -8393,6 +8393,58 @@ function replaceWithSortedKeys(_key, value) {
8393
8393
  return value;
8394
8394
  }
8395
8395
  /**
8396
+ * The ffmpeg build every CamStack node downloads, per platform and arch.
8397
+ *
8398
+ * ## Why a download, on every node, including the container
8399
+ *
8400
+ * The version of ffmpeg used to be CODE: baked into the image, changeable only
8401
+ * by rebuilding and rolling it. Now it is DATA — this file states the release,
8402
+ * and a node that boots with a different one downloads it. Changing ffmpeg is a
8403
+ * framework bump, not an image rebuild.
8404
+ *
8405
+ * It also settles the licence question by removing it. FFmpeg's licence is
8406
+ * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
8407
+ * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
8408
+ * makes the result undistributable. These are GPL v3 builds, and we do not
8409
+ * distribute them: the user's own node fetches the archive from the project
8410
+ * that publishes it, so we convey no GPL work and inherit none of the
8411
+ * obligations that come with conveying one. That is the whole reason the image
8412
+ * no longer installs ffmpeg at all — not a technical preference.
8413
+ *
8414
+ * ## Why jellyfin-ffmpeg
8415
+ *
8416
+ * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
8417
+ * from one release, with the widest hardware surface of anything maintained:
8418
+ * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
8419
+ * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
8420
+ * so the binary is not linked against a driver stack it may not find.
8421
+ *
8422
+ * **What it still needs from the host, measured 2026-09-19.** On the Unraid
8423
+ * HOST, which has no libva, `-vaapi_device` aborts the process outright —
8424
+ * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
8425
+ * "Assertion in generated code"' failed`. Inside our container, which installs
8426
+ * libva plus the iHD driver, the same command encodes: verified end to end with
8427
+ * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
8428
+ * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
8429
+ *
8430
+ * ## Why each artifact carries a checksum and a claim
8431
+ *
8432
+ * The download is now the only source, so `sha256` is verified before anything
8433
+ * is extracted — jellyfin publishes no checksums on its release assets, so
8434
+ * these are ours, taken at the version bump. And `expectedHwaccels` is what the
8435
+ * build is supposed to be able to do: a binary that probes short of its own
8436
+ * claim is a source that changed under us, which is precisely what went
8437
+ * unnoticed for months when a static build turned out to carry no VAAPI at all
8438
+ * (D536).
8439
+ */
8440
+ /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
8441
+ var FFMPEG_RELEASE = "8.1.2-5";
8442
+ var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
8443
+ function portable(target) {
8444
+ return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
8445
+ }
8446
+ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
8447
+ /**
8396
8448
  * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
8397
8449
  * valutatore puro del suo FRONTE.
8398
8450
  *
@@ -9777,6 +9829,26 @@ function egressTranscodeSharingKey(request, delivery = egressTransportFromReques
9777
9829
  return `egress:${canonicalHash(canonicalEgressPlan(request, delivery))}`;
9778
9830
  }
9779
9831
  /**
9832
+ * Memoize `ensure` on SUCCESS only.
9833
+ *
9834
+ * A failure is not remembered: the next caller asks again, so a node whose
9835
+ * first download failed (no network at boot) recovers on the next spawn that
9836
+ * needs it — with no timer and no retry loop, because the ask is driven by
9837
+ * work that actually wants the binary.
9838
+ */
9839
+ function memoizePinnedFfmpeg(ensure) {
9840
+ let pending = null;
9841
+ return () => {
9842
+ if (pending !== null) return pending;
9843
+ const attempt = ensure();
9844
+ pending = attempt;
9845
+ attempt.catch(() => {
9846
+ if (pending === attempt) pending = null;
9847
+ });
9848
+ return attempt;
9849
+ };
9850
+ }
9851
+ /**
9780
9852
  * Deep wiring healthcheck — snapshot of active reachability probes across
9781
9853
  * every declared capability + widget of every installed plugin, on every
9782
9854
  * node. Produced by the backend `WiringHealthService` and surfaced via
@@ -10306,6 +10378,82 @@ var ArchivedDebugNoteQueryInputSchema = object({
10306
10378
  /** Max rows returned, newest-first. */
10307
10379
  limit: number().int().min(1).max(1e3).optional()
10308
10380
  });
10381
+ var TrackRelationKindSchema = _enum(["same-subject", "different-subjects"]);
10382
+ var TrackSideSchema = _enum(["before", "after"]);
10383
+ var TrackPurityValueSchema = _enum(["mixed", "not-a-subject"]);
10384
+ var TrackRelationSchema = object({
10385
+ id: string(),
10386
+ deviceId: number().int(),
10387
+ leftTrackId: string(),
10388
+ rightTrackId: string(),
10389
+ leftSide: TrackSideSchema.nullable(),
10390
+ rightSide: TrackSideSchema.nullable(),
10391
+ relation: TrackRelationKindSchema,
10392
+ presence: literal("continuous").nullable(),
10393
+ leftStartedAt: number().int().nullable(),
10394
+ rightStartedAt: number().int().nullable(),
10395
+ createdAt: number().int(),
10396
+ updatedAt: number().int(),
10397
+ author: string().nullable()
10398
+ });
10399
+ var TrackPuritySchema = object({
10400
+ id: string(),
10401
+ deviceId: number().int(),
10402
+ sourceTrackId: string(),
10403
+ purity: TrackPurityValueSchema,
10404
+ switchAtMs: number().int().nullable(),
10405
+ startedAt: number().int().nullable(),
10406
+ createdAt: number().int(),
10407
+ updatedAt: number().int(),
10408
+ author: string().nullable()
10409
+ });
10410
+ var SetTrackRelationInputSchema = object({
10411
+ deviceId: number().int(),
10412
+ trackId: string().min(1),
10413
+ otherTrackId: string().min(1),
10414
+ relation: TrackRelationKindSchema,
10415
+ presence: literal("continuous").optional(),
10416
+ trackSide: TrackSideSchema.optional(),
10417
+ otherSide: TrackSideSchema.optional()
10418
+ });
10419
+ var ClearTrackRelationInputSchema = object({
10420
+ deviceId: number().int(),
10421
+ trackId: string().min(1),
10422
+ otherTrackId: string().min(1)
10423
+ });
10424
+ var ClearTrackRelationResultSchema = object({ cleared: boolean() });
10425
+ var SetTrackPurityInputSchema = object({
10426
+ deviceId: number().int(),
10427
+ trackId: string().min(1),
10428
+ purity: _enum([
10429
+ "pure",
10430
+ "mixed",
10431
+ "not-a-subject"
10432
+ ]),
10433
+ switchAtMs: number().int().optional()
10434
+ });
10435
+ /** `null` when `pure` cleared the row. */
10436
+ var SetTrackPurityResultSchema = object({ purity: TrackPuritySchema.nullable() });
10437
+ var ListTrackRelationsInputSchema = object({
10438
+ deviceId: number().int(),
10439
+ trackId: string().optional(),
10440
+ since: number().int().optional(),
10441
+ until: number().int().optional(),
10442
+ limit: number().int().min(1).max(5e3).optional()
10443
+ });
10444
+ var ListTrackRelationsResultSchema = object({
10445
+ relations: array(TrackRelationSchema).readonly(),
10446
+ purities: array(TrackPuritySchema).readonly(),
10447
+ truncated: boolean()
10448
+ });
10449
+ _enum([
10450
+ "unknown-track",
10451
+ "cross-device",
10452
+ "self-relation",
10453
+ "contradiction",
10454
+ "switch-outside-track",
10455
+ "switch-needs-mixed"
10456
+ ]);
10309
10457
  /**
10310
10458
  * Ops-log — the durable, append-only operations audit shared by the
10311
10459
  * recordings and events management surfaces.
@@ -15564,6 +15712,70 @@ var CompositionBlockStateSchema = object({
15564
15712
  reason: string().optional(),
15565
15713
  fields: array(CompositionFieldStateSchema)
15566
15714
  });
15715
+ var NUMBER = {
15716
+ kind: "fixed",
15717
+ result: ["number"]
15718
+ };
15719
+ var BOOLEAN = {
15720
+ kind: "fixed",
15721
+ result: ["boolean"]
15722
+ };
15723
+ Object.freeze({
15724
+ min: NUMBER,
15725
+ max: NUMBER,
15726
+ abs: NUMBER,
15727
+ floor: NUMBER,
15728
+ ceil: NUMBER,
15729
+ sqrt: NUMBER,
15730
+ round: NUMBER,
15731
+ pow: NUMBER,
15732
+ clamp: NUMBER,
15733
+ avg: NUMBER,
15734
+ sum: NUMBER,
15735
+ age: NUMBER,
15736
+ convert: NUMBER,
15737
+ coalesce: { kind: "coalesce" },
15738
+ any: BOOLEAN,
15739
+ all: BOOLEAN,
15740
+ within: BOOLEAN,
15741
+ latest: {
15742
+ kind: "fixed",
15743
+ result: ["number", "null"]
15744
+ },
15745
+ number: {
15746
+ kind: "fixed",
15747
+ result: ["number", "null"]
15748
+ },
15749
+ rose: {
15750
+ kind: "fixed",
15751
+ result: ["number", "null"]
15752
+ },
15753
+ count: NUMBER
15754
+ });
15755
+ `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
15756
+ /**
15757
+ * What a composition may BUILD on a device type (G2, D676): the caps a new
15758
+ * device of that type, or an existing one that lacks them, can be given. The
15759
+ * blockers are the validator's own refusal codes, and a spec compares this
15760
+ * listing with `planComposition` for every capability — the editor can never
15761
+ * offer a feature the save would refuse for the same reason.
15762
+ */
15763
+ var ComposableFieldSchema = object({
15764
+ path: string(),
15765
+ kind: CompositionFieldKindSchema,
15766
+ nullable: boolean(),
15767
+ required: boolean(),
15768
+ enumValues: array(string()).optional()
15769
+ });
15770
+ var ComposableCapabilitiesSchema = object({ caps: array(object({
15771
+ cap: string(),
15772
+ fields: array(ComposableFieldSchema),
15773
+ /** Present for an item-array cap (`consumables.items`). */
15774
+ itemArray: object({
15775
+ path: string(),
15776
+ keyField: string()
15777
+ }).optional()
15778
+ })) });
15567
15779
  /** Where a block runs. The operator chooses — a block driving a device on an
15568
15780
  * agent is the reason placement is not fixed to the hub. */
15569
15781
  var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
@@ -15728,7 +15940,7 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
15728
15940
  }), method(object({ blockId: string() }), CompositionGetReadSchema, { auth: "admin" }), method(object({}), CompositionListReadSchema, { auth: "admin" }), method(object({
15729
15941
  addonId: string().min(1),
15730
15942
  stableId: string().min(1)
15731
- }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({
15943
+ }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }), method(object({
15732
15944
  composition: CompositionSchema,
15733
15945
  blockId: string().optional()
15734
15946
  }), CompositionValidationSchema, {
@@ -23056,7 +23268,7 @@ function cameraSensorRefKey(ref) {
23056
23268
  }
23057
23269
  /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
23058
23270
  var CameraSensorsModeSchema = _enum(["in-addition"]);
23059
- object({
23271
+ var CameraSensorsConfigSchema = object({
23060
23272
  mode: CameraSensorsModeSchema,
23061
23273
  sensors: array(CameraSensorRefSchema).min(1).max(8)
23062
23274
  }).superRefine((value, ctx) => {
@@ -25017,7 +25229,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25017
25229
  deviceId: number(),
25018
25230
  trackId: string(),
25019
25231
  flags: TrackFlagsPatchSchema
25020
- }), TrackFlagsSchema, { kind: "mutation" }), method(ArchivedDebugNoteQueryInputSchema, array(ArchivedDebugNoteSchema).readonly(), { kind: "query" }), method(BirthDecisionQueryInputSchema, array(BirthDecisionRecordSchema).readonly(), { kind: "query" }), method(object({}), EventStoreFootprintSchema, {
25232
+ }), TrackFlagsSchema, { kind: "mutation" }), method(ArchivedDebugNoteQueryInputSchema, array(ArchivedDebugNoteSchema).readonly(), { kind: "query" }), method(SetTrackRelationInputSchema, TrackRelationSchema, { kind: "mutation" }), method(ClearTrackRelationInputSchema, ClearTrackRelationResultSchema, { kind: "mutation" }), method(SetTrackPurityInputSchema, SetTrackPurityResultSchema, { kind: "mutation" }), method(ListTrackRelationsInputSchema, ListTrackRelationsResultSchema, { kind: "query" }), method(BirthDecisionQueryInputSchema, array(BirthDecisionRecordSchema).readonly(), { kind: "query" }), method(object({}), EventStoreFootprintSchema, {
25021
25233
  kind: "query",
25022
25234
  auth: "admin"
25023
25235
  }), method(object({ deviceId: number().int().optional() }), EventMediaKindBreakdownSchema, {
@@ -27563,6 +27775,28 @@ var NodeInferenceDevicesSchema = object({
27563
27775
  reachable: boolean(),
27564
27776
  devices: array(NodeInferenceDeviceSchema).readonly()
27565
27777
  });
27778
+ /**
27779
+ * Pipeline Orchestrator capability — global load balancer + camera dispatcher.
27780
+ *
27781
+ * Lives on the hub. Tracks the camera-to-agent assignment map, listens to
27782
+ * device lifecycle events, queries each runner's capacity + hardware
27783
+ * profile, and dispatches `attachCamera` / `detachCamera` cap calls to the
27784
+ * appropriate runner instances. Persists assignments via the multi-level
27785
+ * settings store so they survive hub restarts.
27786
+ *
27787
+ * Strictly the control plane: never sees a frame, never calls inference,
27788
+ * never drains queues. The runner does that work locally on each agent.
27789
+ */
27790
+ /**
27791
+ * The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
27792
+ * camera's attached sensors (D672). `config: null` removes the attachment —
27793
+ * the camera reads `not-configured` again, never `unreadable`.
27794
+ */
27795
+ var SetCameraSensorsInputSchema = object({
27796
+ deviceId: number().int().nonnegative(),
27797
+ /** `null` removes the attachment: the camera goes back to `not-configured`. */
27798
+ config: CameraSensorsConfigSchema.nullable()
27799
+ });
27566
27800
  method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
27567
27801
  kind: "mutation",
27568
27802
  auth: "admin"
@@ -27717,7 +27951,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
27717
27951
  }), CameraSwitchGroupSchema, {
27718
27952
  kind: "mutation",
27719
27953
  auth: "admin"
27720
- }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), DiskReconcileJobSchema, {
27954
+ }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
27955
+ kind: "mutation",
27956
+ auth: "admin"
27957
+ }), method(_void(), DiskReconcileJobSchema, {
27721
27958
  kind: "mutation",
27722
27959
  auth: "admin"
27723
27960
  }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
@@ -39638,47 +39875,6 @@ DeviceType.Camera, method(object({
39638
39875
  detection: array(ZoneRuleSchema).readonly(),
39639
39876
  package: array(ZoneRuleSchema).readonly()
39640
39877
  });
39641
- var NUMBER = {
39642
- kind: "fixed",
39643
- result: ["number"]
39644
- };
39645
- var BOOLEAN = {
39646
- kind: "fixed",
39647
- result: ["boolean"]
39648
- };
39649
- Object.freeze({
39650
- min: NUMBER,
39651
- max: NUMBER,
39652
- abs: NUMBER,
39653
- floor: NUMBER,
39654
- ceil: NUMBER,
39655
- sqrt: NUMBER,
39656
- round: NUMBER,
39657
- pow: NUMBER,
39658
- clamp: NUMBER,
39659
- avg: NUMBER,
39660
- sum: NUMBER,
39661
- age: NUMBER,
39662
- convert: NUMBER,
39663
- coalesce: { kind: "coalesce" },
39664
- any: BOOLEAN,
39665
- all: BOOLEAN,
39666
- within: BOOLEAN,
39667
- latest: {
39668
- kind: "fixed",
39669
- result: ["number", "null"]
39670
- },
39671
- number: {
39672
- kind: "fixed",
39673
- result: ["number", "null"]
39674
- },
39675
- rose: {
39676
- kind: "fixed",
39677
- result: ["number", "null"]
39678
- },
39679
- count: NUMBER
39680
- });
39681
- `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
39682
39878
  var HF_BASE_URL = `https://huggingface.co/camstack/camstack-models/resolve/main`;
39683
39879
  /**
39684
39880
  * Accessory device helpers — shared across drivers.
@@ -42120,6 +42316,12 @@ Object.freeze({
42120
42316
  addonId: null,
42121
42317
  access: "view"
42122
42318
  },
42319
+ "coreBlocks.listComposableCaps": {
42320
+ capName: "core-blocks",
42321
+ capScope: "system",
42322
+ addonId: null,
42323
+ access: "view"
42324
+ },
42123
42325
  "coreBlocks.listCompositions": {
42124
42326
  capName: "core-blocks",
42125
42327
  capScope: "system",
@@ -44934,6 +45136,12 @@ Object.freeze({
44934
45136
  addonId: null,
44935
45137
  access: "create"
44936
45138
  },
45139
+ "pipelineAnalytics.clearTrackRelation": {
45140
+ capName: "pipeline-analytics",
45141
+ capScope: "device",
45142
+ addonId: null,
45143
+ access: "delete"
45144
+ },
44937
45145
  "pipelineAnalytics.clearTracks": {
44938
45146
  capName: "pipeline-analytics",
44939
45147
  capScope: "device",
@@ -45186,6 +45394,12 @@ Object.freeze({
45186
45394
  addonId: null,
45187
45395
  access: "view"
45188
45396
  },
45397
+ "pipelineAnalytics.listTrackRelations": {
45398
+ capName: "pipeline-analytics",
45399
+ capScope: "device",
45400
+ addonId: null,
45401
+ access: "view"
45402
+ },
45189
45403
  "pipelineAnalytics.listTracks": {
45190
45404
  capName: "pipeline-analytics",
45191
45405
  capScope: "device",
@@ -45300,6 +45514,18 @@ Object.freeze({
45300
45514
  addonId: null,
45301
45515
  access: "create"
45302
45516
  },
45517
+ "pipelineAnalytics.setTrackPurity": {
45518
+ capName: "pipeline-analytics",
45519
+ capScope: "device",
45520
+ addonId: null,
45521
+ access: "create"
45522
+ },
45523
+ "pipelineAnalytics.setTrackRelation": {
45524
+ capName: "pipeline-analytics",
45525
+ capScope: "device",
45526
+ addonId: null,
45527
+ access: "create"
45528
+ },
45303
45529
  "pipelineAnalytics.startStorageMigrationMove": {
45304
45530
  capName: "pipeline-analytics",
45305
45531
  capScope: "device",
@@ -45804,6 +46030,12 @@ Object.freeze({
45804
46030
  addonId: null,
45805
46031
  access: "create"
45806
46032
  },
46033
+ "pipelineOrchestrator.setCameraSensors": {
46034
+ capName: "pipeline-orchestrator",
46035
+ capScope: "system",
46036
+ addonId: null,
46037
+ access: "create"
46038
+ },
45807
46039
  "pipelineOrchestrator.setCameraStepOverride": {
45808
46040
  capName: "pipeline-orchestrator",
45809
46041
  capScope: "system",
@@ -49214,6 +49446,11 @@ Object.freeze({
49214
49446
  form: "single",
49215
49447
  optional: false
49216
49448
  }],
49449
+ "pipelineAnalytics.clearTrackRelation": [{
49450
+ name: "deviceId",
49451
+ form: "single",
49452
+ optional: false
49453
+ }],
49217
49454
  "pipelineAnalytics.clearTracks": [{
49218
49455
  name: "deviceId",
49219
49456
  form: "single",
@@ -49364,6 +49601,11 @@ Object.freeze({
49364
49601
  form: "single",
49365
49602
  optional: false
49366
49603
  }],
49604
+ "pipelineAnalytics.listTrackRelations": [{
49605
+ name: "deviceId",
49606
+ form: "single",
49607
+ optional: false
49608
+ }],
49367
49609
  "pipelineAnalytics.listTracks": [{
49368
49610
  name: "deviceId",
49369
49611
  form: "single",
@@ -49434,6 +49676,16 @@ Object.freeze({
49434
49676
  form: "single",
49435
49677
  optional: false
49436
49678
  }],
49679
+ "pipelineAnalytics.setTrackPurity": [{
49680
+ name: "deviceId",
49681
+ form: "single",
49682
+ optional: false
49683
+ }],
49684
+ "pipelineAnalytics.setTrackRelation": [{
49685
+ name: "deviceId",
49686
+ form: "single",
49687
+ optional: false
49688
+ }],
49437
49689
  "pipelineAnalytics.wipeAllAnalytics": [{
49438
49690
  name: "deviceId",
49439
49691
  form: "single",
@@ -49514,6 +49766,11 @@ Object.freeze({
49514
49766
  form: "single",
49515
49767
  optional: false
49516
49768
  }],
49769
+ "pipelineOrchestrator.setCameraSensors": [{
49770
+ name: "deviceId",
49771
+ form: "single",
49772
+ optional: false
49773
+ }],
49517
49774
  "pipelineOrchestrator.setCameraStepOverride": [{
49518
49775
  name: "deviceId",
49519
49776
  form: "single",
@@ -52880,6 +53137,12 @@ Object.defineProperty(exports, "mayWriteToLocation", {
52880
53137
  return mayWriteToLocation;
52881
53138
  }
52882
53139
  });
53140
+ Object.defineProperty(exports, "memoizePinnedFfmpeg", {
53141
+ enumerable: true,
53142
+ get: function() {
53143
+ return memoizePinnedFfmpeg;
53144
+ }
53145
+ });
52883
53146
  Object.defineProperty(exports, "migrateLegacyDeviceSignalConfig", {
52884
53147
  enumerable: true,
52885
53148
  get: function() {
@@ -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-CyJWk-_f.js");
5
+ const require_dist = require("../dist-BLf0YjAa.js");
6
6
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Dt as motionDetectionCapability, bn as hydrateSchema, fn as BaseAddon, ln as DeviceType, st as evaluateZoneRules } from "../dist-DdVMFlJ6.mjs";
1
+ import { Ot as motionDetectionCapability, pn as BaseAddon, st as evaluateZoneRules, un as DeviceType, xn as hydrateSchema } from "../dist-B3_sbBDM.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -1,4 +1,4 @@
1
- import { in as buildFfmpegArgs, rn as Fmp4BoxSplitter, sn as isSoftwareDecode, un as errMsg } from "./dist-DdVMFlJ6.mjs";
1
+ import { an as buildFfmpegArgs, cn as isSoftwareDecode, dn as errMsg, in as Fmp4BoxSplitter } from "./dist-B3_sbBDM.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { realpathSync } from "node:fs";
4
4
  import path from "node:path";
@@ -112,58 +112,6 @@ async function probeFfmpegBinary(path) {
112
112
  ]);
113
113
  return parseFfmpegCapabilities(path, versionOut, hwaccelOut, encoderOut);
114
114
  }
115
- /**
116
- * The ffmpeg build every CamStack node downloads, per platform and arch.
117
- *
118
- * ## Why a download, on every node, including the container
119
- *
120
- * The version of ffmpeg used to be CODE: baked into the image, changeable only
121
- * by rebuilding and rolling it. Now it is DATA — this file states the release,
122
- * and a node that boots with a different one downloads it. Changing ffmpeg is a
123
- * framework bump, not an image rebuild.
124
- *
125
- * It also settles the licence question by removing it. FFmpeg's licence is
126
- * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
127
- * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
128
- * makes the result undistributable. These are GPL v3 builds, and we do not
129
- * distribute them: the user's own node fetches the archive from the project
130
- * that publishes it, so we convey no GPL work and inherit none of the
131
- * obligations that come with conveying one. That is the whole reason the image
132
- * no longer installs ffmpeg at all — not a technical preference.
133
- *
134
- * ## Why jellyfin-ffmpeg
135
- *
136
- * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
137
- * from one release, with the widest hardware surface of anything maintained:
138
- * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
139
- * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
140
- * so the binary is not linked against a driver stack it may not find.
141
- *
142
- * **What it still needs from the host, measured 2026-09-19.** On the Unraid
143
- * HOST, which has no libva, `-vaapi_device` aborts the process outright —
144
- * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
145
- * "Assertion in generated code"' failed`. Inside our container, which installs
146
- * libva plus the iHD driver, the same command encodes: verified end to end with
147
- * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
148
- * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
149
- *
150
- * ## Why each artifact carries a checksum and a claim
151
- *
152
- * The download is now the only source, so `sha256` is verified before anything
153
- * is extracted — jellyfin publishes no checksums on its release assets, so
154
- * these are ours, taken at the version bump. And `expectedHwaccels` is what the
155
- * build is supposed to be able to do: a binary that probes short of its own
156
- * claim is a source that changed under us, which is precisely what went
157
- * unnoticed for months when a static build turned out to carry no VAAPI at all
158
- * (D536).
159
- */
160
- /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
161
- var FFMPEG_RELEASE = "8.1.2-5";
162
- var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
163
- function portable(target) {
164
- return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
165
- }
166
- portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
167
115
  var DEFAULT_FIRST_UNIT_TIMEOUT_MS = 12e3;
168
116
  /** Heartbeat cadence — ~2 minutes of 4 s fragments. */
169
117
  var FRAGMENT_LOG_EVERY = 30;
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-CyJWk-_f.js");
2
+ const require_dist = require("./dist-BLf0YjAa.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_fs = require("node:fs");
5
5
  node_fs = require_chunk.__toESM(node_fs, 1);
@@ -115,58 +115,6 @@ async function probeFfmpegBinary(path) {
115
115
  ]);
116
116
  return parseFfmpegCapabilities(path, versionOut, hwaccelOut, encoderOut);
117
117
  }
118
- /**
119
- * The ffmpeg build every CamStack node downloads, per platform and arch.
120
- *
121
- * ## Why a download, on every node, including the container
122
- *
123
- * The version of ffmpeg used to be CODE: baked into the image, changeable only
124
- * by rebuilding and rolling it. Now it is DATA — this file states the release,
125
- * and a node that boots with a different one downloads it. Changing ffmpeg is a
126
- * framework bump, not an image rebuild.
127
- *
128
- * It also settles the licence question by removing it. FFmpeg's licence is
129
- * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
130
- * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
131
- * makes the result undistributable. These are GPL v3 builds, and we do not
132
- * distribute them: the user's own node fetches the archive from the project
133
- * that publishes it, so we convey no GPL work and inherit none of the
134
- * obligations that come with conveying one. That is the whole reason the image
135
- * no longer installs ffmpeg at all — not a technical preference.
136
- *
137
- * ## Why jellyfin-ffmpeg
138
- *
139
- * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
140
- * from one release, with the widest hardware surface of anything maintained:
141
- * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
142
- * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
143
- * so the binary is not linked against a driver stack it may not find.
144
- *
145
- * **What it still needs from the host, measured 2026-09-19.** On the Unraid
146
- * HOST, which has no libva, `-vaapi_device` aborts the process outright —
147
- * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
148
- * "Assertion in generated code"' failed`. Inside our container, which installs
149
- * libva plus the iHD driver, the same command encodes: verified end to end with
150
- * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
151
- * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
152
- *
153
- * ## Why each artifact carries a checksum and a claim
154
- *
155
- * The download is now the only source, so `sha256` is verified before anything
156
- * is extracted — jellyfin publishes no checksums on its release assets, so
157
- * these are ours, taken at the version bump. And `expectedHwaccels` is what the
158
- * build is supposed to be able to do: a binary that probes short of its own
159
- * claim is a source that changed under us, which is precisely what went
160
- * unnoticed for months when a static build turned out to carry no VAAPI at all
161
- * (D536).
162
- */
163
- /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
164
- var FFMPEG_RELEASE = "8.1.2-5";
165
- var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
166
- function portable(target) {
167
- return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
168
- }
169
- portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
170
118
  var DEFAULT_FIRST_UNIT_TIMEOUT_MS = 12e3;
171
119
  /** Heartbeat cadence — ~2 minutes of 4 s fragments. */
172
120
  var FRAGMENT_LOG_EVERY = 30;
@@ -3,9 +3,9 @@ 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-CyJWk-_f.js");
7
- const require_node = require("../node-HsWG5fGp.js");
8
- const require_default_detection_model = require("../default-detection-model-DgdiQtQb.js");
6
+ const require_dist = require("../dist-BLf0YjAa.js");
7
+ const require_node = require("../node-Vwf2PuIT.js");
8
+ const require_default_detection_model = require("../default-detection-model-BZMS04Wn.js");
9
9
  const require_worker_protocol = require("../worker-protocol-C-G8qmye.js");
10
10
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
11
11
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
@@ -1,6 +1,6 @@
1
- import { An as array, C as FailureCounters, D as NativeLeaseAdmissionSchema, E as MOTION_CLOSE_AFTER_MS, Fn as number, In as object, Mt as pickNativeLeaseOverride, Nn as lazy, O as NativeLeaseSettingsSchema, Pn as literal, Pt as pipelineRunnerCapability, Vn as EventCategory, _ as DEFAULT_NATIVE_LEASE_SETTINGS, _n as customAction, dt as failureContributionCapability, fn as BaseAddon, gn as createEvent, h as DEFAULT_DETAIL_CROP_CONVENTION, i as BackgroundRunRegistry, jn as boolean, jt as pickDetailCropConvention, kn as _enum, tt as deriveDetailCropRect, un as errMsg, vn as defineCustomActions, wn as nodePin, yt as loadContributionCapability, zn as string } from "../dist-DdVMFlJ6.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-COu_tHy4.mjs";
3
- import { c as macroGateVerdict, d as resolveFrameViewGeometry, g as getStepDefinition, l as rootObjectGate, o as placeDetailStep, r as CustomModelCatalog, s as stepsForElectedPool, u as localFrameRegistry, v as RETIRED_MODEL_IDS } from "../default-detection-model-BV9bIuOo.mjs";
1
+ import { An as _enum, Bn as string, C as FailureCounters, D as NativeLeaseAdmissionSchema, E as MOTION_CLOSE_AFTER_MS, Fn as literal, Ft as pipelineRunnerCapability, Hn as EventCategory, In as number, Ln as object, Mn as boolean, Mt as pickDetailCropConvention, Nt as pickNativeLeaseOverride, O as NativeLeaseSettingsSchema, Pn as lazy, Tn as nodePin, _ as DEFAULT_NATIVE_LEASE_SETTINGS, _n as createEvent, dn as errMsg, dt as failureContributionCapability, h as DEFAULT_DETAIL_CROP_CONVENTION, i as BackgroundRunRegistry, jn as array, pn as BaseAddon, tt as deriveDetailCropRect, vn as customAction, yn as defineCustomActions, yt as loadContributionCapability } from "../dist-B3_sbBDM.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-DJFKTJ0B.mjs";
3
+ import { c as macroGateVerdict, d as resolveFrameViewGeometry, g as getStepDefinition, l as rootObjectGate, o as placeDetailStep, r as CustomModelCatalog, s as stepsForElectedPool, u as localFrameRegistry, v as RETIRED_MODEL_IDS } from "../default-detection-model-ClQ1gcZ9.mjs";
4
4
  import { t as isWorkerReply } from "../worker-protocol-D_NzPcnh.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";