@camstack/addon-pipeline 1.2.106 → 1.2.115

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 (35) hide show
  1. package/dist/{addon-utils-BEzVJ0xg.js → addon-utils-C0ht2KPO.js} +51 -15
  2. package/dist/{addon-utils-A2S9D7pu.mjs → addon-utils-CgBCF-mE.mjs} +50 -14
  3. package/dist/audio-analyzer/index.js +3 -3
  4. package/dist/audio-analyzer/index.mjs +3 -3
  5. package/dist/detection-pipeline/index.js +198 -38
  6. package/dist/detection-pipeline/index.mjs +197 -37
  7. package/dist/{dist-BSeR_hVv.js → dist-BqIbYW1A.js} +290 -17
  8. package/dist/{dist-lITI1Bn5.mjs → dist-DGQkkWc6.mjs} +273 -18
  9. package/dist/{event-loop-stall-monitor-0VvjTRDP.mjs → event-loop-stall-monitor-D5jK5v4Z.mjs} +223 -2
  10. package/dist/{event-loop-stall-monitor-BNsp9k8r.js → event-loop-stall-monitor-ylMGpz48.js} +234 -1
  11. package/dist/{lazy-sharp-CBohM8D8.js → lazy-sharp-cOsy7l_P.js} +1 -1
  12. package/dist/motion-wasm/index.js +2 -2
  13. package/dist/motion-wasm/index.mjs +1 -1
  14. package/dist/pipeline-runner/index.js +915 -107
  15. package/dist/pipeline-runner/index.mjs +914 -106
  16. package/dist/{process-memory-C33u3tQz.js → process-memory-45juuHpN.js} +1 -1
  17. package/dist/{process-memory-CEKVKfwg.mjs → process-memory-BtT7WfbJ.mjs} +1 -1
  18. package/dist/recorder/index.js +187 -47
  19. package/dist/recorder/index.mjs +187 -47
  20. package/dist/session-decode/decode-worker-child.js +30 -10
  21. package/dist/session-decode/decode-worker-child.mjs +29 -9
  22. package/dist/stream-broker/_stub.js +2 -2
  23. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-w2XLD3uI.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-C_SFFNGT.mjs} +3 -3
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B1LDFHY9.mjs +26 -0
  25. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DsIi4G5Q.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BAMyzCWw.mjs} +1 -1
  26. package/dist/stream-broker/{hostInit-B-h24cDy.mjs → hostInit-CG28NvlV.mjs} +3 -3
  27. package/dist/stream-broker/index.js +279 -198
  28. package/dist/stream-broker/index.mjs +279 -198
  29. package/dist/stream-broker/remoteEntry.js +1 -1
  30. package/dist/{worker-protocol-CiKfal2P.js → worker-protocol-CIrqGbpG.js} +6 -3
  31. package/dist/{worker-protocol-BDiL8TBm.mjs → worker-protocol-DyocTIx_.mjs} +6 -3
  32. package/package.json +1 -1
  33. package/python/inference_pool.py +4 -1
  34. package/python/test_inference_pool_preprocess.py +87 -16
  35. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DvZWLWk1.mjs +0 -26
@@ -9081,6 +9081,15 @@ var LabelDefinitionSchema = object({
9081
9081
  description: string().optional(),
9082
9082
  icon: string().optional()
9083
9083
  });
9084
+ var ClassMapDefinitionSchema = object({
9085
+ mapping: record(string(), _enum([
9086
+ "person",
9087
+ "vehicle",
9088
+ "animal",
9089
+ "package"
9090
+ ])),
9091
+ preserveOriginal: boolean()
9092
+ });
9084
9093
  var MODEL_FORMATS = [
9085
9094
  "onnx",
9086
9095
  "coreml",
@@ -9259,7 +9268,13 @@ var ModelCatalogEntrySchema = object({
9259
9268
  * `id` stays the source of truth for resolution/download/persistence; grouping
9260
9269
  * is a presentation overlay resolved back to an `id`.
9261
9270
  */
9262
- group: ModelVariantGroupSchema.optional()
9271
+ group: ModelVariantGroupSchema.optional(),
9272
+ /**
9273
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
9274
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
9275
+ * labels already ARE the CamStack macros (Scrypted identity map).
9276
+ */
9277
+ classMap: ClassMapDefinitionSchema.optional()
9263
9278
  });
9264
9279
  var ConvertTargetSchema = discriminatedUnion("format", [object({
9265
9280
  format: literal("openvino"),
@@ -9288,7 +9303,8 @@ var ModelConvertMetadataSchema = object({
9288
9303
  "ocr",
9289
9304
  "segmentation"
9290
9305
  ]),
9291
- faceAlignment: boolean().optional()
9306
+ faceAlignment: boolean().optional(),
9307
+ classMap: ClassMapDefinitionSchema.optional()
9292
9308
  });
9293
9309
  var ConvertResultSchema = object({
9294
9310
  entry: ModelCatalogEntrySchema,
@@ -19072,6 +19088,33 @@ var NativeCropRefSchema = object({
19072
19088
  h: number()
19073
19089
  })
19074
19090
  });
19091
+ object({
19092
+ crop: object({
19093
+ left: number(),
19094
+ top: number(),
19095
+ width: number().positive(),
19096
+ height: number().positive()
19097
+ }).optional(),
19098
+ content: object({
19099
+ width: number().int().positive(),
19100
+ height: number().int().positive()
19101
+ }),
19102
+ fit: _enum(["stretch", "contain"]),
19103
+ format: _enum([
19104
+ "rgb",
19105
+ "gray",
19106
+ "jpeg"
19107
+ ])
19108
+ });
19109
+ var FrameRefSchema = object({
19110
+ registryId: string().min(1),
19111
+ id: string().min(1),
19112
+ width: number().int().positive(),
19113
+ height: number().int().positive(),
19114
+ format: _enum(["rgb", "gray"]),
19115
+ timestamp: number(),
19116
+ capturedAt: number().optional()
19117
+ });
19075
19118
  var ModelFormatSchema$1 = _enum([
19076
19119
  "onnx",
19077
19120
  "coreml",
@@ -19392,7 +19435,7 @@ var pipelineExecutorCapability = {
19392
19435
  * legacy call shape used by existing benchmark code; once all
19393
19436
  * callers pass it explicitly we make it required.
19394
19437
  *
19395
- * Exactly one of `frame`, `frameHandle`, `imageBase64`,
19438
+ * Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
19396
19439
  * `referenceImage` must be provided:
19397
19440
  * - `frame`: runtime dispatch path (runner → decoded broker frame).
19398
19441
  * Carries the raw buffer, dimensions, and format; the executor
@@ -19414,6 +19457,12 @@ var pipelineExecutorCapability = {
19414
19457
  steps: array(PipelineStepInputSchema).min(1),
19415
19458
  frame: FrameInputSchema.optional(),
19416
19459
  /**
19460
+ * Process-local lazy frame. Valid only when caller and provider resolve
19461
+ * in the same execution-group process; split/cross-node callers use
19462
+ * `frame`/`image` inline compatibility instead.
19463
+ */
19464
+ frameRef: FrameRefSchema.optional(),
19465
+ /**
19417
19466
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
19418
19467
  * the decoded pixels live in. One more member of the one-of
19419
19468
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -19723,7 +19772,10 @@ var NativeCropResultSchema = object({
19723
19772
  * Which source served this crop, so a quality-sensitive consumer (the native
19724
19773
  * `keyFrame`) can reject a degraded fallback:
19725
19774
  * - `native` — cut from the decode worker's retained NATIVE surface (the
19726
- * quality path).
19775
+ * quality path). A subject-tile serve is also native-resolution and stays
19776
+ * `native` here: the public enum cannot name `tile` without a breaking cap
19777
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
19778
+ * internal crop result (`nativeHits` vs `tileHits`).
19727
19779
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
19728
19780
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
19729
19781
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -20214,12 +20266,41 @@ var RunnerLocalLoadSchema = object({
20214
20266
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
20215
20267
  * working unchanged when they switch to reading from the runner cap.
20216
20268
  */
20269
+ var FrameLazyCountersSchema = object({
20270
+ framesDecoded: number(),
20271
+ framesAdmitted: number(),
20272
+ framesDroppedPixelFree: number(),
20273
+ viewsMaterialized: number(),
20274
+ viewsSkipped: number(),
20275
+ workerToRunnerBytes: number(),
20276
+ runnerToPoolRawBytes: number(),
20277
+ runnerToPoolJpegBytes: number(),
20278
+ onDemandFullFrameRequests: number(),
20279
+ onDemandCropRequests: number(),
20280
+ nativeHits: number(),
20281
+ nativeMisses: number(),
20282
+ tileHits: number(),
20283
+ tileMisses: number(),
20284
+ fallbackHits: number(),
20285
+ fallbackMisses: number(),
20286
+ retainedWritesAvoided: number(),
20287
+ residentRefs: number(),
20288
+ residentBytes: number(),
20289
+ releases: number(),
20290
+ evictions: number(),
20291
+ staleMisses: number()
20292
+ });
20293
+ var FrameLazyMetricsSchema = object({
20294
+ node: FrameLazyCountersSchema,
20295
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
20296
+ });
20217
20297
  var RunnerLocalMetricsSchema = object({
20218
20298
  nodeId: string(),
20219
20299
  activeCameras: number(),
20220
20300
  throttledCameras: number(),
20221
20301
  avgInferenceTimeMs: number(),
20222
- queueDepth: number()
20302
+ queueDepth: number(),
20303
+ frameLazy: FrameLazyMetricsSchema.optional()
20223
20304
  });
20224
20305
  /**
20225
20306
  * Pipeline Runner capability — runtime detection workhorse.
@@ -21676,6 +21757,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
21676
21757
  location: StorageLocationSchema,
21677
21758
  relativePath: string()
21678
21759
  }), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
21760
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
21761
+ var ProfileSettingsSchemaBridge = unknown().nullable();
21762
+ var ProfileSettingsBagSchema = record(string(), unknown());
21679
21763
  /**
21680
21764
  * A live terminal session hosted by the provider addon. Output and input do
21681
21765
  * NOT flow through the capability — they use the addon data plane
@@ -21705,7 +21789,14 @@ var TerminalSessionInfoSchema = object({
21705
21789
  var TerminalProfileInfoSchema = object({
21706
21790
  profileId: string(),
21707
21791
  label: string(),
21708
- description: string().optional()
21792
+ description: string().optional(),
21793
+ /** Spawn defaults the instance form copies on create. */
21794
+ executable: string().optional(),
21795
+ args: array(string()).readonly().optional(),
21796
+ cwd: string().optional(),
21797
+ environment: array(string()).readonly().optional(),
21798
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
21799
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
21709
21800
  });
21710
21801
  /**
21711
21802
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -21718,7 +21809,12 @@ var TerminalInstanceInfoSchema = object({
21718
21809
  profileId: string(),
21719
21810
  profileLabel: string(),
21720
21811
  name: string(),
21721
- enabled: boolean()
21812
+ enabled: boolean(),
21813
+ executable: string(),
21814
+ args: array(string()).readonly(),
21815
+ cwd: string(),
21816
+ environment: array(string()).readonly(),
21817
+ profileSettings: ProfileSettingsBagSchema
21722
21818
  });
21723
21819
  var TerminalLegacyCameraSchema = object({
21724
21820
  stableId: string(),
@@ -21748,7 +21844,23 @@ var TerminalOutputBatchSchema = object({
21748
21844
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
21749
21845
  targetNodeId: string().min(1),
21750
21846
  profileId: string().min(1),
21751
- name: string().trim().min(1).max(160).optional()
21847
+ name: string().trim().min(1).max(160).optional(),
21848
+ executable: string().max(1024).optional(),
21849
+ args: array(string().max(2048)).max(64).optional(),
21850
+ cwd: string().max(1024).optional(),
21851
+ environment: array(string().max(4096)).max(64).optional(),
21852
+ profileSettings: ProfileSettingsBagSchema.optional()
21853
+ }), TerminalInstanceInfoSchema, {
21854
+ kind: "mutation",
21855
+ auth: "admin"
21856
+ }), method(object({
21857
+ instanceId: string().min(1),
21858
+ name: string().trim().min(1).max(160).optional(),
21859
+ executable: string().max(1024).optional(),
21860
+ args: array(string().max(2048)).max(64).optional(),
21861
+ cwd: string().max(1024).optional(),
21862
+ environment: array(string().max(4096)).max(64).optional(),
21863
+ profileSettings: ProfileSettingsBagSchema.optional()
21752
21864
  }), TerminalInstanceInfoSchema, {
21753
21865
  kind: "mutation",
21754
21866
  auth: "admin"
@@ -21770,7 +21882,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
21770
21882
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
21771
21883
  profileId: string(),
21772
21884
  cols: number().int().positive(),
21773
- rows: number().int().positive()
21885
+ rows: number().int().positive(),
21886
+ executable: string().max(1024).optional(),
21887
+ args: array(string().max(2048)).max(64).optional(),
21888
+ cwd: string().max(1024).optional(),
21889
+ environment: array(string().max(4096)).max(64).optional()
21774
21890
  }), TerminalSessionInfoSchema, {
21775
21891
  kind: "mutation",
21776
21892
  auth: "admin"
@@ -24699,10 +24815,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
24699
24815
  *
24700
24816
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24701
24817
  * to receive an ordered list of candidate base URLs it should race
24702
- * on connect — LAN IPv4 first (lowest latency when on same network),
24703
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24704
- * race them with short timeouts and stick with the winner for the
24705
- * session.
24818
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24819
+ * when on the same network), then public hostname (if a tunnel is
24820
+ * up). The SDK can race them with short timeouts and stick with the
24821
+ * winner for the session.
24706
24822
  *
24707
24823
  * Why hub-only: agents are not directly addressable by the operator's
24708
24824
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24857,6 +24973,17 @@ var NotificationEndpointSchema = object({
24857
24973
  /** What the ranking currently resolves to (null when nothing is reachable). */
24858
24974
  resolved: string().nullable()
24859
24975
  });
24976
+ /**
24977
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24978
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24979
+ * currently expands to, so the UI can show the effective set either way.
24980
+ */
24981
+ var ViewerEndpointsSchema = object({
24982
+ /** The operator's explicit race set, or empty for AUTO. */
24983
+ baseUrls: array(string()).readonly(),
24984
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24985
+ resolved: array(string()).readonly()
24986
+ });
24860
24987
  var AllowedAddressesSchema = object({
24861
24988
  /**
24862
24989
  * Allowlist of interface addresses operators have explicitly opted
@@ -24865,6 +24992,20 @@ var AllowedAddressesSchema = object({
24865
24992
  * Network Addresses admin page and persisted by the addon.
24866
24993
  */
24867
24994
  addresses: array(string()).readonly() });
24995
+ var TlsStatusSchema = object({
24996
+ mode: _enum([
24997
+ "generated",
24998
+ "uploaded",
24999
+ "disabled"
25000
+ ]),
25001
+ leafFingerprintSha256: string().nullable(),
25002
+ caFingerprintSha256: string().nullable(),
25003
+ validTo: string().nullable(),
25004
+ sans: array(string()),
25005
+ caCertPem: string().nullable(),
25006
+ reissueError: string().nullable(),
25007
+ restartRequired: boolean()
25008
+ });
24868
25009
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24869
25010
  /**
24870
25011
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24874,17 +25015,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24874
25015
  */
24875
25016
  port: number().int().min(1).max(65535).optional(),
24876
25017
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24877
- * candidate. Default `true`. */
25018
+ * candidate. Default `false` — loopback is not a client route. */
24878
25019
  includeLoopback: boolean().optional(),
24879
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24880
- * Default `false`. */
25020
+ /** Skip IPv6 entries. Default `false` the palette includes stable
25021
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
25022
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24881
25023
  ipv4Only: boolean().optional(),
24882
25024
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24883
25025
  * Pass `'https'` when the caller is itself loaded over HTTPS
24884
25026
  * to avoid mixed-content blocks in the browser. The public
24885
25027
  * tunnel always emits `https://` regardless. */
24886
25028
  scheme: _enum(["http", "https"]).optional()
24887
- }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" });
25029
+ }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
25030
+ kind: "mutation",
25031
+ auth: "admin"
25032
+ }), method(object({
25033
+ certPem: string().min(1),
25034
+ keyPem: string().min(1),
25035
+ caPem: string().optional()
25036
+ }), TlsStatusSchema, {
25037
+ kind: "mutation",
25038
+ auth: "admin"
25039
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
25040
+ kind: "mutation",
25041
+ auth: "admin"
25042
+ });
24888
25043
  object({
24889
25044
  /** Lifecycle state of the lock. `jammed` means the motor reported
24890
25045
  * failure to reach the target — operator intervention required. */
@@ -30819,6 +30974,12 @@ Object.freeze({
30819
30974
  addonId: null,
30820
30975
  access: "create"
30821
30976
  },
30977
+ "localNetwork.downloadCa": {
30978
+ capName: "local-network",
30979
+ capScope: "system",
30980
+ addonId: null,
30981
+ access: "view"
30982
+ },
30822
30983
  "localNetwork.getAllowedAddresses": {
30823
30984
  capName: "local-network",
30824
30985
  capScope: "system",
@@ -30843,18 +31004,42 @@ Object.freeze({
30843
31004
  addonId: null,
30844
31005
  access: "view"
30845
31006
  },
31007
+ "localNetwork.getTlsStatus": {
31008
+ capName: "local-network",
31009
+ capScope: "system",
31010
+ addonId: null,
31011
+ access: "view"
31012
+ },
31013
+ "localNetwork.getViewerEndpoints": {
31014
+ capName: "local-network",
31015
+ capScope: "system",
31016
+ addonId: null,
31017
+ access: "view"
31018
+ },
30846
31019
  "localNetwork.list": {
30847
31020
  capName: "local-network",
30848
31021
  capScope: "system",
30849
31022
  addonId: null,
30850
31023
  access: "view"
30851
31024
  },
31025
+ "localNetwork.regenerateCertificate": {
31026
+ capName: "local-network",
31027
+ capScope: "system",
31028
+ addonId: null,
31029
+ access: "create"
31030
+ },
30852
31031
  "localNetwork.resetAllowlistToBestMatch": {
30853
31032
  capName: "local-network",
30854
31033
  capScope: "system",
30855
31034
  addonId: null,
30856
31035
  access: "delete"
30857
31036
  },
31037
+ "localNetwork.revertToGeneratedCertificate": {
31038
+ capName: "local-network",
31039
+ capScope: "system",
31040
+ addonId: null,
31041
+ access: "create"
31042
+ },
30858
31043
  "localNetwork.setAllowedAddresses": {
30859
31044
  capName: "local-network",
30860
31045
  capScope: "system",
@@ -30867,6 +31052,18 @@ Object.freeze({
30867
31052
  addonId: null,
30868
31053
  access: "create"
30869
31054
  },
31055
+ "localNetwork.setViewerEndpoints": {
31056
+ capName: "local-network",
31057
+ capScope: "system",
31058
+ addonId: null,
31059
+ access: "create"
31060
+ },
31061
+ "localNetwork.uploadCertificate": {
31062
+ capName: "local-network",
31063
+ capScope: "system",
31064
+ addonId: null,
31065
+ access: "create"
31066
+ },
30870
31067
  "lockControl.lock": {
30871
31068
  capName: "lock-control",
30872
31069
  capScope: "device",
@@ -33747,6 +33944,12 @@ Object.freeze({
33747
33944
  addonId: null,
33748
33945
  access: "create"
33749
33946
  },
33947
+ "terminalSession.updateInstance": {
33948
+ capName: "terminal-session",
33949
+ capScope: "system",
33950
+ addonId: null,
33951
+ access: "create"
33952
+ },
33750
33953
  "terminalSession.writeInput": {
33751
33954
  capName: "terminal-session",
33752
33955
  capScope: "system",
@@ -36398,6 +36601,58 @@ function resolveClusterStepModelId(stepId, models) {
36398
36601
  const chosen = models[stepId];
36399
36602
  return chosen !== void 0 && chosen !== "" ? chosen : step.defaultModelId;
36400
36603
  }
36604
+ var CLUSTER_STEP_SETTING_FIELDS = [{
36605
+ stepId: "face-embedding",
36606
+ key: "minLandmarkFaceSize",
36607
+ label: "Min face size for recognition (detection px)",
36608
+ description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
36609
+ type: "slider",
36610
+ min: 0,
36611
+ max: 64,
36612
+ step: 2,
36613
+ default: 24
36614
+ }];
36615
+ function clusterStepSettingKey(stepId, fieldKey) {
36616
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
36617
+ }
36618
+ var ClusterSettingNumberSchema = number().finite();
36619
+ function readClusterStepSettings(config) {
36620
+ const out = {};
36621
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
36622
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
36623
+ const value = parsed.success ? parsed.data : field.default;
36624
+ const existing = out[field.stepId] ?? {};
36625
+ out[field.stepId] = {
36626
+ ...existing,
36627
+ [field.key]: value
36628
+ };
36629
+ }
36630
+ return out;
36631
+ }
36632
+ var DEFAULT_CLUSTER_STEP_SETTINGS = readClusterStepSettings({});
36633
+ function pickClusterStepSettings(view) {
36634
+ if (view === null) return DEFAULT_CLUSTER_STEP_SETTINGS;
36635
+ const flat = {};
36636
+ const wanted = new Set(CLUSTER_STEP_SETTING_FIELDS.map((field) => clusterStepSettingKey(field.stepId, field.key)));
36637
+ for (const section of view.sections) for (const entry of section.fields) {
36638
+ if (!isHydratedField$2(entry) || typeof entry.key !== "string") continue;
36639
+ if (wanted.has(entry.key)) flat[entry.key] = entry.value;
36640
+ }
36641
+ return readClusterStepSettings(flat);
36642
+ }
36643
+ /**
36644
+ * Cluster knobs win over leftover per-device values. The cluster row is the
36645
+ * authority; a device-local copy is a leftover of the old per-node editor.
36646
+ */
36647
+ function overlayClusterStepSettings(stepId, deviceSettings, cluster) {
36648
+ const overlay = cluster[stepId];
36649
+ if (overlay === void 0 || Object.keys(overlay).length === 0) return deviceSettings === void 0 ? void 0 : { ...deviceSettings };
36650
+ if (deviceSettings === void 0) return { ...overlay };
36651
+ return {
36652
+ ...deviceSettings,
36653
+ ...overlay
36654
+ };
36655
+ }
36401
36656
  var DETAIL_CROP_PADDING_KEY = "detailCropPaddingRatio";
36402
36657
  var DETAIL_CROP_SQUARE_KEY = "detailCropSquare";
36403
36658
  /**
@@ -37523,6 +37778,12 @@ Object.defineProperty(exports, "DEFAULT_CLUSTER_STEP_MODELS", {
37523
37778
  return DEFAULT_CLUSTER_STEP_MODELS;
37524
37779
  }
37525
37780
  });
37781
+ Object.defineProperty(exports, "DEFAULT_CLUSTER_STEP_SETTINGS", {
37782
+ enumerable: true,
37783
+ get: function() {
37784
+ return DEFAULT_CLUSTER_STEP_SETTINGS;
37785
+ }
37786
+ });
37526
37787
  Object.defineProperty(exports, "DEFAULT_DETAIL_CROP_CONVENTION", {
37527
37788
  enumerable: true,
37528
37789
  get: function() {
@@ -37907,6 +38168,12 @@ Object.defineProperty(exports, "object", {
37907
38168
  return object;
37908
38169
  }
37909
38170
  });
38171
+ Object.defineProperty(exports, "overlayClusterStepSettings", {
38172
+ enumerable: true,
38173
+ get: function() {
38174
+ return overlayClusterStepSettings;
38175
+ }
38176
+ });
37910
38177
  Object.defineProperty(exports, "parseJsonUnknown", {
37911
38178
  enumerable: true,
37912
38179
  get: function() {
@@ -37931,6 +38198,12 @@ Object.defineProperty(exports, "pickClusterStepModels", {
37931
38198
  return pickClusterStepModels;
37932
38199
  }
37933
38200
  });
38201
+ Object.defineProperty(exports, "pickClusterStepSettings", {
38202
+ enumerable: true,
38203
+ get: function() {
38204
+ return pickClusterStepSettings;
38205
+ }
38206
+ });
37934
38207
  Object.defineProperty(exports, "pickDetailCropConvention", {
37935
38208
  enumerable: true,
37936
38209
  get: function() {