@camstack/addon-model-studio 1.1.183 → 1.1.184

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 (18) hide show
  1. package/dist/{MotionZonesSettings-D5fe7czg.mjs → MotionZonesSettings-CLIRob-J.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-C2hylmd3.mjs → PrivacyMaskSettings-exV6L1j_.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-CLZ8DeD3.mjs → SceneMonitorEditor-icoLBztR.mjs} +3 -3
  4. package/dist/_stub.js +11 -11
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Ca-jPREF.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DQxc1RfH.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D3PT9fEx.mjs +26 -0
  7. package/dist/{hostInit-DiUsU_UL.mjs → hostInit-C9yJIB1e.mjs} +2 -2
  8. package/dist/model-studio.addon.js +177 -45
  9. package/dist/model-studio.addon.mjs +177 -45
  10. package/dist/{player-overlays-CgxP2Qzw.mjs → player-overlays-DwfCWVUG.mjs} +1 -1
  11. package/dist/remoteEntry.js +1 -1
  12. package/dist/{responsive-F2i_EZ7a.mjs → responsive-BRO7smWV.mjs} +1 -1
  13. package/dist/{scene-monitor-copy-RkL6wtjU.mjs → scene-monitor-copy--wZxxF0G.mjs} +1 -1
  14. package/dist/{square-C4QMTFWA.mjs → square-BfZLUXuN.mjs} +1 -1
  15. package/dist/{trash-2-BtfILwcu.mjs → trash-2-0kWm0Lcw.mjs} +1 -1
  16. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DflrE0ec.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-JOrjSbrc.mjs} +1 -1
  17. package/package.json +1 -1
  18. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CEWbeCwN.mjs +0 -26
@@ -8051,7 +8051,59 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
8051
8051
  return DeviceRole;
8052
8052
  }({});
8053
8053
  //#endregion
8054
- //#region ../types/dist/composition-BK-GTFYb.mjs
8054
+ //#region ../types/dist/composition-Dq42XWp0.mjs
8055
+ /**
8056
+ * The ffmpeg build every CamStack node downloads, per platform and arch.
8057
+ *
8058
+ * ## Why a download, on every node, including the container
8059
+ *
8060
+ * The version of ffmpeg used to be CODE: baked into the image, changeable only
8061
+ * by rebuilding and rolling it. Now it is DATA — this file states the release,
8062
+ * and a node that boots with a different one downloads it. Changing ffmpeg is a
8063
+ * framework bump, not an image rebuild.
8064
+ *
8065
+ * It also settles the licence question by removing it. FFmpeg's licence is
8066
+ * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
8067
+ * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
8068
+ * makes the result undistributable. These are GPL v3 builds, and we do not
8069
+ * distribute them: the user's own node fetches the archive from the project
8070
+ * that publishes it, so we convey no GPL work and inherit none of the
8071
+ * obligations that come with conveying one. That is the whole reason the image
8072
+ * no longer installs ffmpeg at all — not a technical preference.
8073
+ *
8074
+ * ## Why jellyfin-ffmpeg
8075
+ *
8076
+ * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
8077
+ * from one release, with the widest hardware surface of anything maintained:
8078
+ * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
8079
+ * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
8080
+ * so the binary is not linked against a driver stack it may not find.
8081
+ *
8082
+ * **What it still needs from the host, measured 2026-09-19.** On the Unraid
8083
+ * HOST, which has no libva, `-vaapi_device` aborts the process outright —
8084
+ * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
8085
+ * "Assertion in generated code"' failed`. Inside our container, which installs
8086
+ * libva plus the iHD driver, the same command encodes: verified end to end with
8087
+ * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
8088
+ * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
8089
+ *
8090
+ * ## Why each artifact carries a checksum and a claim
8091
+ *
8092
+ * The download is now the only source, so `sha256` is verified before anything
8093
+ * is extracted — jellyfin publishes no checksums on its release assets, so
8094
+ * these are ours, taken at the version bump. And `expectedHwaccels` is what the
8095
+ * build is supposed to be able to do: a binary that probes short of its own
8096
+ * claim is a source that changed under us, which is precisely what went
8097
+ * unnoticed for months when a static build turned out to carry no VAAPI at all
8098
+ * (D536).
8099
+ */
8100
+ /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
8101
+ var FFMPEG_RELEASE = "8.1.2-5";
8102
+ var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
8103
+ function portable(target) {
8104
+ return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
8105
+ }
8106
+ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
8055
8107
  /**
8056
8108
  * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
8057
8109
  * valutatore puro del suo FRONTE.
@@ -13628,6 +13680,70 @@ var CompositionBlockStateSchema = object({
13628
13680
  reason: string().optional(),
13629
13681
  fields: array(CompositionFieldStateSchema)
13630
13682
  });
13683
+ var NUMBER = {
13684
+ kind: "fixed",
13685
+ result: ["number"]
13686
+ };
13687
+ var BOOLEAN = {
13688
+ kind: "fixed",
13689
+ result: ["boolean"]
13690
+ };
13691
+ Object.freeze({
13692
+ min: NUMBER,
13693
+ max: NUMBER,
13694
+ abs: NUMBER,
13695
+ floor: NUMBER,
13696
+ ceil: NUMBER,
13697
+ sqrt: NUMBER,
13698
+ round: NUMBER,
13699
+ pow: NUMBER,
13700
+ clamp: NUMBER,
13701
+ avg: NUMBER,
13702
+ sum: NUMBER,
13703
+ age: NUMBER,
13704
+ convert: NUMBER,
13705
+ coalesce: { kind: "coalesce" },
13706
+ any: BOOLEAN,
13707
+ all: BOOLEAN,
13708
+ within: BOOLEAN,
13709
+ latest: {
13710
+ kind: "fixed",
13711
+ result: ["number", "null"]
13712
+ },
13713
+ number: {
13714
+ kind: "fixed",
13715
+ result: ["number", "null"]
13716
+ },
13717
+ rose: {
13718
+ kind: "fixed",
13719
+ result: ["number", "null"]
13720
+ },
13721
+ count: NUMBER
13722
+ });
13723
+ `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
13724
+ /**
13725
+ * What a composition may BUILD on a device type (G2, D676): the caps a new
13726
+ * device of that type, or an existing one that lacks them, can be given. The
13727
+ * blockers are the validator's own refusal codes, and a spec compares this
13728
+ * listing with `planComposition` for every capability — the editor can never
13729
+ * offer a feature the save would refuse for the same reason.
13730
+ */
13731
+ var ComposableFieldSchema = object({
13732
+ path: string(),
13733
+ kind: CompositionFieldKindSchema,
13734
+ nullable: boolean(),
13735
+ required: boolean(),
13736
+ enumValues: array(string()).optional()
13737
+ });
13738
+ var ComposableCapabilitiesSchema = object({ caps: array(object({
13739
+ cap: string(),
13740
+ fields: array(ComposableFieldSchema),
13741
+ /** Present for an item-array cap (`consumables.items`). */
13742
+ itemArray: object({
13743
+ path: string(),
13744
+ keyField: string()
13745
+ }).optional()
13746
+ })) });
13631
13747
  /** Where a block runs. The operator chooses — a block driving a device on an
13632
13748
  * agent is the reason placement is not fixed to the hub. */
13633
13749
  var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
@@ -13792,7 +13908,7 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
13792
13908
  }), method(object({ blockId: string() }), CompositionGetReadSchema, { auth: "admin" }), method(object({}), CompositionListReadSchema, { auth: "admin" }), method(object({
13793
13909
  addonId: string().min(1),
13794
13910
  stableId: string().min(1)
13795
- }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({
13911
+ }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }), method(object({
13796
13912
  composition: CompositionSchema,
13797
13913
  blockId: string().optional()
13798
13914
  }), CompositionValidationSchema, {
@@ -20714,7 +20830,7 @@ function cameraSensorRefKey(ref) {
20714
20830
  }
20715
20831
  /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
20716
20832
  var CameraSensorsModeSchema = _enum(["in-addition"]);
20717
- object({
20833
+ var CameraSensorsConfigSchema = object({
20718
20834
  mode: CameraSensorsModeSchema,
20719
20835
  sensors: array(CameraSensorRefSchema).min(1).max(8)
20720
20836
  }).superRefine((value, ctx) => {
@@ -21704,6 +21820,21 @@ var ObjectEventSchema = object({
21704
21820
  keyFrameMediaId: number().int().optional(),
21705
21821
  /** Populated by B5 (recording playback URL for this event). */
21706
21822
  mediaUrl: string().optional(),
21823
+ /**
21824
+ * When the change this row records HAPPENED, epoch ms, when that is earlier
21825
+ * than {@link timestamp} and the producer could date it (D684).
21826
+ *
21827
+ * Set on a package PICK-UP row only: its `timestamp` is when the departure
21828
+ * was CONCLUDED — five minutes of unseen observed time after the parcel went
21829
+ * — and a notification's footage has to be cut around the pick-up, not the
21830
+ * empty doormat after it (D682). Stored so every path that rebuilds a
21831
+ * notification subject from the row (the boot reconcile, a dry-run) anchors
21832
+ * on the same instant the live hook did.
21833
+ *
21834
+ * `timestamp` keeps its meaning. Absent on every other row and on every
21835
+ * pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
21836
+ */
21837
+ observedAt: number().optional(),
21707
21838
  /** The parent track's key-event importance [0,1], propagated to every object
21708
21839
  * event of the track (so an event row can be sorted by importance without a
21709
21840
  * track join). Absent on legacy rows / before the track was scored. */
@@ -24771,6 +24902,28 @@ var NodeInferenceDevicesSchema = object({
24771
24902
  reachable: boolean(),
24772
24903
  devices: array(NodeInferenceDeviceSchema).readonly()
24773
24904
  });
24905
+ /**
24906
+ * Pipeline Orchestrator capability — global load balancer + camera dispatcher.
24907
+ *
24908
+ * Lives on the hub. Tracks the camera-to-agent assignment map, listens to
24909
+ * device lifecycle events, queries each runner's capacity + hardware
24910
+ * profile, and dispatches `attachCamera` / `detachCamera` cap calls to the
24911
+ * appropriate runner instances. Persists assignments via the multi-level
24912
+ * settings store so they survive hub restarts.
24913
+ *
24914
+ * Strictly the control plane: never sees a frame, never calls inference,
24915
+ * never drains queues. The runner does that work locally on each agent.
24916
+ */
24917
+ /**
24918
+ * The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
24919
+ * camera's attached sensors (D672). `config: null` removes the attachment —
24920
+ * the camera reads `not-configured` again, never `unreadable`.
24921
+ */
24922
+ var SetCameraSensorsInputSchema = object({
24923
+ deviceId: number().int().nonnegative(),
24924
+ /** `null` removes the attachment: the camera goes back to `not-configured`. */
24925
+ config: CameraSensorsConfigSchema.nullable()
24926
+ });
24774
24927
  method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
24775
24928
  kind: "mutation",
24776
24929
  auth: "admin"
@@ -24925,7 +25078,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
24925
25078
  }), CameraSwitchGroupSchema, {
24926
25079
  kind: "mutation",
24927
25080
  auth: "admin"
24928
- }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), DiskReconcileJobSchema, {
25081
+ }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
25082
+ kind: "mutation",
25083
+ auth: "admin"
25084
+ }), method(_void(), DiskReconcileJobSchema, {
24929
25085
  kind: "mutation",
24930
25086
  auth: "admin"
24931
25087
  }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
@@ -35826,47 +35982,6 @@ DeviceType.Camera, method(object({
35826
35982
  detection: array(ZoneRuleSchema).readonly(),
35827
35983
  package: array(ZoneRuleSchema).readonly()
35828
35984
  });
35829
- var NUMBER = {
35830
- kind: "fixed",
35831
- result: ["number"]
35832
- };
35833
- var BOOLEAN = {
35834
- kind: "fixed",
35835
- result: ["boolean"]
35836
- };
35837
- Object.freeze({
35838
- min: NUMBER,
35839
- max: NUMBER,
35840
- abs: NUMBER,
35841
- floor: NUMBER,
35842
- ceil: NUMBER,
35843
- sqrt: NUMBER,
35844
- round: NUMBER,
35845
- pow: NUMBER,
35846
- clamp: NUMBER,
35847
- avg: NUMBER,
35848
- sum: NUMBER,
35849
- age: NUMBER,
35850
- convert: NUMBER,
35851
- coalesce: { kind: "coalesce" },
35852
- any: BOOLEAN,
35853
- all: BOOLEAN,
35854
- within: BOOLEAN,
35855
- latest: {
35856
- kind: "fixed",
35857
- result: ["number", "null"]
35858
- },
35859
- number: {
35860
- kind: "fixed",
35861
- result: ["number", "null"]
35862
- },
35863
- rose: {
35864
- kind: "fixed",
35865
- result: ["number", "null"]
35866
- },
35867
- count: NUMBER
35868
- });
35869
- `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
35870
35985
  /**
35871
35986
  * Accessory device helpers — shared across drivers.
35872
35987
  *
@@ -38289,6 +38404,12 @@ Object.freeze({
38289
38404
  addonId: null,
38290
38405
  access: "view"
38291
38406
  },
38407
+ "coreBlocks.listComposableCaps": {
38408
+ capName: "core-blocks",
38409
+ capScope: "system",
38410
+ addonId: null,
38411
+ access: "view"
38412
+ },
38292
38413
  "coreBlocks.listCompositions": {
38293
38414
  capName: "core-blocks",
38294
38415
  capScope: "system",
@@ -41973,6 +42094,12 @@ Object.freeze({
41973
42094
  addonId: null,
41974
42095
  access: "create"
41975
42096
  },
42097
+ "pipelineOrchestrator.setCameraSensors": {
42098
+ capName: "pipeline-orchestrator",
42099
+ capScope: "system",
42100
+ addonId: null,
42101
+ access: "create"
42102
+ },
41976
42103
  "pipelineOrchestrator.setCameraStepOverride": {
41977
42104
  capName: "pipeline-orchestrator",
41978
42105
  capScope: "system",
@@ -45683,6 +45810,11 @@ Object.freeze({
45683
45810
  form: "single",
45684
45811
  optional: false
45685
45812
  }],
45813
+ "pipelineOrchestrator.setCameraSensors": [{
45814
+ name: "deviceId",
45815
+ form: "single",
45816
+ optional: false
45817
+ }],
45686
45818
  "pipelineOrchestrator.setCameraStepOverride": [{
45687
45819
  name: "deviceId",
45688
45820
  form: "single",
@@ -8030,7 +8030,59 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
8030
8030
  return DeviceRole;
8031
8031
  }({});
8032
8032
  //#endregion
8033
- //#region ../types/dist/composition-BK-GTFYb.mjs
8033
+ //#region ../types/dist/composition-Dq42XWp0.mjs
8034
+ /**
8035
+ * The ffmpeg build every CamStack node downloads, per platform and arch.
8036
+ *
8037
+ * ## Why a download, on every node, including the container
8038
+ *
8039
+ * The version of ffmpeg used to be CODE: baked into the image, changeable only
8040
+ * by rebuilding and rolling it. Now it is DATA — this file states the release,
8041
+ * and a node that boots with a different one downloads it. Changing ffmpeg is a
8042
+ * framework bump, not an image rebuild.
8043
+ *
8044
+ * It also settles the licence question by removing it. FFmpeg's licence is
8045
+ * chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
8046
+ * (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
8047
+ * makes the result undistributable. These are GPL v3 builds, and we do not
8048
+ * distribute them: the user's own node fetches the archive from the project
8049
+ * that publishes it, so we convey no GPL work and inherit none of the
8050
+ * obligations that come with conveying one. That is the whole reason the image
8051
+ * no longer installs ffmpeg at all — not a technical preference.
8052
+ *
8053
+ * ## Why jellyfin-ffmpeg
8054
+ *
8055
+ * One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
8056
+ * from one release, with the widest hardware surface of anything maintained:
8057
+ * VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
8058
+ * MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
8059
+ * so the binary is not linked against a driver stack it may not find.
8060
+ *
8061
+ * **What it still needs from the host, measured 2026-09-19.** On the Unraid
8062
+ * HOST, which has no libva, `-vaapi_device` aborts the process outright —
8063
+ * `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
8064
+ * "Assertion in generated code"' failed`. Inside our container, which installs
8065
+ * libva plus the iHD driver, the same command encodes: verified end to end with
8066
+ * `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
8067
+ * KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
8068
+ *
8069
+ * ## Why each artifact carries a checksum and a claim
8070
+ *
8071
+ * The download is now the only source, so `sha256` is verified before anything
8072
+ * is extracted — jellyfin publishes no checksums on its release assets, so
8073
+ * these are ours, taken at the version bump. And `expectedHwaccels` is what the
8074
+ * build is supposed to be able to do: a binary that probes short of its own
8075
+ * claim is a source that changed under us, which is precisely what went
8076
+ * unnoticed for months when a static build turned out to carry no VAAPI at all
8077
+ * (D536).
8078
+ */
8079
+ /** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
8080
+ var FFMPEG_RELEASE = "8.1.2-5";
8081
+ var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
8082
+ function portable(target) {
8083
+ return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
8084
+ }
8085
+ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
8034
8086
  /**
8035
8087
  * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
8036
8088
  * valutatore puro del suo FRONTE.
@@ -13607,6 +13659,70 @@ var CompositionBlockStateSchema = object({
13607
13659
  reason: string().optional(),
13608
13660
  fields: array(CompositionFieldStateSchema)
13609
13661
  });
13662
+ var NUMBER = {
13663
+ kind: "fixed",
13664
+ result: ["number"]
13665
+ };
13666
+ var BOOLEAN = {
13667
+ kind: "fixed",
13668
+ result: ["boolean"]
13669
+ };
13670
+ Object.freeze({
13671
+ min: NUMBER,
13672
+ max: NUMBER,
13673
+ abs: NUMBER,
13674
+ floor: NUMBER,
13675
+ ceil: NUMBER,
13676
+ sqrt: NUMBER,
13677
+ round: NUMBER,
13678
+ pow: NUMBER,
13679
+ clamp: NUMBER,
13680
+ avg: NUMBER,
13681
+ sum: NUMBER,
13682
+ age: NUMBER,
13683
+ convert: NUMBER,
13684
+ coalesce: { kind: "coalesce" },
13685
+ any: BOOLEAN,
13686
+ all: BOOLEAN,
13687
+ within: BOOLEAN,
13688
+ latest: {
13689
+ kind: "fixed",
13690
+ result: ["number", "null"]
13691
+ },
13692
+ number: {
13693
+ kind: "fixed",
13694
+ result: ["number", "null"]
13695
+ },
13696
+ rose: {
13697
+ kind: "fixed",
13698
+ result: ["number", "null"]
13699
+ },
13700
+ count: NUMBER
13701
+ });
13702
+ `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
13703
+ /**
13704
+ * What a composition may BUILD on a device type (G2, D676): the caps a new
13705
+ * device of that type, or an existing one that lacks them, can be given. The
13706
+ * blockers are the validator's own refusal codes, and a spec compares this
13707
+ * listing with `planComposition` for every capability — the editor can never
13708
+ * offer a feature the save would refuse for the same reason.
13709
+ */
13710
+ var ComposableFieldSchema = object({
13711
+ path: string(),
13712
+ kind: CompositionFieldKindSchema,
13713
+ nullable: boolean(),
13714
+ required: boolean(),
13715
+ enumValues: array(string()).optional()
13716
+ });
13717
+ var ComposableCapabilitiesSchema = object({ caps: array(object({
13718
+ cap: string(),
13719
+ fields: array(ComposableFieldSchema),
13720
+ /** Present for an item-array cap (`consumables.items`). */
13721
+ itemArray: object({
13722
+ path: string(),
13723
+ keyField: string()
13724
+ }).optional()
13725
+ })) });
13610
13726
  /** Where a block runs. The operator chooses — a block driving a device on an
13611
13727
  * agent is the reason placement is not fixed to the hub. */
13612
13728
  var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
@@ -13771,7 +13887,7 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
13771
13887
  }), method(object({ blockId: string() }), CompositionGetReadSchema, { auth: "admin" }), method(object({}), CompositionListReadSchema, { auth: "admin" }), method(object({
13772
13888
  addonId: string().min(1),
13773
13889
  stableId: string().min(1)
13774
- }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({
13890
+ }), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }), method(object({
13775
13891
  composition: CompositionSchema,
13776
13892
  blockId: string().optional()
13777
13893
  }), CompositionValidationSchema, {
@@ -20693,7 +20809,7 @@ function cameraSensorRefKey(ref) {
20693
20809
  }
20694
20810
  /** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
20695
20811
  var CameraSensorsModeSchema = _enum(["in-addition"]);
20696
- object({
20812
+ var CameraSensorsConfigSchema = object({
20697
20813
  mode: CameraSensorsModeSchema,
20698
20814
  sensors: array(CameraSensorRefSchema).min(1).max(8)
20699
20815
  }).superRefine((value, ctx) => {
@@ -21683,6 +21799,21 @@ var ObjectEventSchema = object({
21683
21799
  keyFrameMediaId: number().int().optional(),
21684
21800
  /** Populated by B5 (recording playback URL for this event). */
21685
21801
  mediaUrl: string().optional(),
21802
+ /**
21803
+ * When the change this row records HAPPENED, epoch ms, when that is earlier
21804
+ * than {@link timestamp} and the producer could date it (D684).
21805
+ *
21806
+ * Set on a package PICK-UP row only: its `timestamp` is when the departure
21807
+ * was CONCLUDED — five minutes of unseen observed time after the parcel went
21808
+ * — and a notification's footage has to be cut around the pick-up, not the
21809
+ * empty doormat after it (D682). Stored so every path that rebuilds a
21810
+ * notification subject from the row (the boot reconcile, a dry-run) anchors
21811
+ * on the same instant the live hook did.
21812
+ *
21813
+ * `timestamp` keeps its meaning. Absent on every other row and on every
21814
+ * pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
21815
+ */
21816
+ observedAt: number().optional(),
21686
21817
  /** The parent track's key-event importance [0,1], propagated to every object
21687
21818
  * event of the track (so an event row can be sorted by importance without a
21688
21819
  * track join). Absent on legacy rows / before the track was scored. */
@@ -24750,6 +24881,28 @@ var NodeInferenceDevicesSchema = object({
24750
24881
  reachable: boolean(),
24751
24882
  devices: array(NodeInferenceDeviceSchema).readonly()
24752
24883
  });
24884
+ /**
24885
+ * Pipeline Orchestrator capability — global load balancer + camera dispatcher.
24886
+ *
24887
+ * Lives on the hub. Tracks the camera-to-agent assignment map, listens to
24888
+ * device lifecycle events, queries each runner's capacity + hardware
24889
+ * profile, and dispatches `attachCamera` / `detachCamera` cap calls to the
24890
+ * appropriate runner instances. Persists assignments via the multi-level
24891
+ * settings store so they survive hub restarts.
24892
+ *
24893
+ * Strictly the control plane: never sees a frame, never calls inference,
24894
+ * never drains queues. The runner does that work locally on each agent.
24895
+ */
24896
+ /**
24897
+ * The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
24898
+ * camera's attached sensors (D672). `config: null` removes the attachment —
24899
+ * the camera reads `not-configured` again, never `unreadable`.
24900
+ */
24901
+ var SetCameraSensorsInputSchema = object({
24902
+ deviceId: number().int().nonnegative(),
24903
+ /** `null` removes the attachment: the camera goes back to `not-configured`. */
24904
+ config: CameraSensorsConfigSchema.nullable()
24905
+ });
24753
24906
  method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
24754
24907
  kind: "mutation",
24755
24908
  auth: "admin"
@@ -24904,7 +25057,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
24904
25057
  }), CameraSwitchGroupSchema, {
24905
25058
  kind: "mutation",
24906
25059
  auth: "admin"
24907
- }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), DiskReconcileJobSchema, {
25060
+ }), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
25061
+ kind: "mutation",
25062
+ auth: "admin"
25063
+ }), method(_void(), DiskReconcileJobSchema, {
24908
25064
  kind: "mutation",
24909
25065
  auth: "admin"
24910
25066
  }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
@@ -35805,47 +35961,6 @@ DeviceType.Camera, method(object({
35805
35961
  detection: array(ZoneRuleSchema).readonly(),
35806
35962
  package: array(ZoneRuleSchema).readonly()
35807
35963
  });
35808
- var NUMBER = {
35809
- kind: "fixed",
35810
- result: ["number"]
35811
- };
35812
- var BOOLEAN = {
35813
- kind: "fixed",
35814
- result: ["boolean"]
35815
- };
35816
- Object.freeze({
35817
- min: NUMBER,
35818
- max: NUMBER,
35819
- abs: NUMBER,
35820
- floor: NUMBER,
35821
- ceil: NUMBER,
35822
- sqrt: NUMBER,
35823
- round: NUMBER,
35824
- pow: NUMBER,
35825
- clamp: NUMBER,
35826
- avg: NUMBER,
35827
- sum: NUMBER,
35828
- age: NUMBER,
35829
- convert: NUMBER,
35830
- coalesce: { kind: "coalesce" },
35831
- any: BOOLEAN,
35832
- all: BOOLEAN,
35833
- within: BOOLEAN,
35834
- latest: {
35835
- kind: "fixed",
35836
- result: ["number", "null"]
35837
- },
35838
- number: {
35839
- kind: "fixed",
35840
- result: ["number", "null"]
35841
- },
35842
- rose: {
35843
- kind: "fixed",
35844
- result: ["number", "null"]
35845
- },
35846
- count: NUMBER
35847
- });
35848
- `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
35849
35964
  /**
35850
35965
  * Accessory device helpers — shared across drivers.
35851
35966
  *
@@ -38268,6 +38383,12 @@ Object.freeze({
38268
38383
  addonId: null,
38269
38384
  access: "view"
38270
38385
  },
38386
+ "coreBlocks.listComposableCaps": {
38387
+ capName: "core-blocks",
38388
+ capScope: "system",
38389
+ addonId: null,
38390
+ access: "view"
38391
+ },
38271
38392
  "coreBlocks.listCompositions": {
38272
38393
  capName: "core-blocks",
38273
38394
  capScope: "system",
@@ -41952,6 +42073,12 @@ Object.freeze({
41952
42073
  addonId: null,
41953
42074
  access: "create"
41954
42075
  },
42076
+ "pipelineOrchestrator.setCameraSensors": {
42077
+ capName: "pipeline-orchestrator",
42078
+ capScope: "system",
42079
+ addonId: null,
42080
+ access: "create"
42081
+ },
41955
42082
  "pipelineOrchestrator.setCameraStepOverride": {
41956
42083
  capName: "pipeline-orchestrator",
41957
42084
  capScope: "system",
@@ -45662,6 +45789,11 @@ Object.freeze({
45662
45789
  form: "single",
45663
45790
  optional: false
45664
45791
  }],
45792
+ "pipelineOrchestrator.setCameraSensors": [{
45793
+ name: "deviceId",
45794
+ form: "single",
45795
+ optional: false
45796
+ }],
45665
45797
  "pipelineOrchestrator.setCameraStepOverride": [{
45666
45798
  name: "deviceId",
45667
45799
  form: "single",
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { o as i, s as a } from "./responsive-F2i_EZ7a.mjs";
2
+ import { o as i, s as a } from "./responsive-BRO7smWV.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DflrE0ec.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-JOrjSbrc.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { c as e, g as t, h as n, l as r, n as i, p as a, r as o, t as s, u as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { n as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CEWbeCwN.mjs";
3
+ import { n as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D3PT9fEx.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  l();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
@@ -1,5 +1,5 @@
1
1
  import { c as e, h as t, p as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { s as i } from "./responsive-F2i_EZ7a.mjs";
2
+ import { s as i } from "./responsive-BRO7smWV.mjs";
3
3
  var a = i("camera", [["path", {
4
4
  d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
5
5
  key: "18u6gg"
@@ -1,4 +1,4 @@
1
- import { s as e } from "./responsive-F2i_EZ7a.mjs";
1
+ import { s as e } from "./responsive-BRO7smWV.mjs";
2
2
  var t = e("eye-off", [
3
3
  ["path", {
4
4
  d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
@@ -1,4 +1,4 @@
1
- import { s as e } from "./responsive-F2i_EZ7a.mjs";
1
+ import { s as e } from "./responsive-BRO7smWV.mjs";
2
2
  var t = e("trash-2", [
3
3
  ["path", {
4
4
  d: "M10 11v6",
@@ -2753,7 +2753,7 @@ async function rr(e) {
2753
2753
  }
2754
2754
  }
2755
2755
  async function ir() {
2756
- return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Ca-jPREF.mjs")).catch((e) => {
2756
+ return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DQxc1RfH.mjs")).catch((e) => {
2757
2757
  throw tr = void 0, e;
2758
2758
  }), tr;
2759
2759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-model-studio",
3
- "version": "1.1.183",
3
+ "version": "1.1.184",
4
4
  "description": "Custom detection model registry, conversion & distribution for CamStack",
5
5
  "keywords": [
6
6
  "camstack",