@camstack/addon-provider-homeassistant 1.2.39 → 1.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("./dist-DGR35D_v.js");
2
+ const require_dist = require("./dist-BoTrJXhA.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_zlib = require("node:zlib");
5
5
  //#region src/ha-device-source.ts
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as pressureSensorCapability, A as coverCapability, B as imageCapability, C as buttonCapability, Ct as record, D as connectivityCapability, Dt as url, E as colorCapability, Et as unknown, F as fanControlCapability, G as normalizeUnit, H as lockControlCapability, I as floodCapability, J as numericSensorCapability, K as notificationOutputCapability, L as gasCapability, N as enumSensorCapability, O as contactCapability, Ot as EventCategory, P as eventEmitterCapability, Q as presenceCapability, R as humidifierCapability, S as buildAddonRouteProvider, St as object, T as climateControlCapability, Tt as union, U as mediaPlayerCapability, V as lawnMowerControlCapability, W as motionCapability, X as powerMeterCapability, Z as prepareNotification, _ as batteryCapability, _t as _enum, at as updateCapability, b as brightnessCapability, bt as literal, ct as vibrationCapability, d as accessoriesCapability, dt as errMsg, et as scriptRunnerCapability, f as addonRoutesCapability, g as automationControlCapability, gt as createEvent, h as ambientLightSensorCapability, ht as DeviceType, it as temperatureSensorCapability, j as deviceAdoptionCapability, k as controlCapability, lt as waterHeaterCapability, m as alarmPanelCapability, mt as DeviceRole, n as BaseDevice, nt as switchCapability, o as EnumSensorDateTimeFormatSchema, ot as vacuumControlCapability, p as airQualitySensorCapability, pt as DeviceFeature, q as notifierCapability, r as BaseDeviceProvider, rt as tamperCapability, st as valveCapability, tt as smokeCapability, u as TargetSchema, ut as weatherCapability, v as bestLocationMatch, vt as array, w as carbonMonoxideCapability, wt as string, x as brokerCapability, xt as number, y as binaryCapability, yt as discriminatedUnion, z as humiditySensorCapability } from "./dist-CMmUPJOe.mjs";
1
+ import { $ as pressureSensorCapability, A as coverCapability, B as imageCapability, C as buttonCapability, Ct as record, D as connectivityCapability, Dt as url, E as colorCapability, Et as unknown, F as fanControlCapability, G as normalizeUnit, H as lockControlCapability, I as floodCapability, J as numericSensorCapability, K as notificationOutputCapability, L as gasCapability, N as enumSensorCapability, O as contactCapability, Ot as EventCategory, P as eventEmitterCapability, Q as presenceCapability, R as humidifierCapability, S as buildAddonRouteProvider, St as object, T as climateControlCapability, Tt as union, U as mediaPlayerCapability, V as lawnMowerControlCapability, W as motionCapability, X as powerMeterCapability, Z as prepareNotification, _ as batteryCapability, _t as _enum, at as updateCapability, b as brightnessCapability, bt as literal, ct as vibrationCapability, d as accessoriesCapability, dt as errMsg, et as scriptRunnerCapability, f as addonRoutesCapability, g as automationControlCapability, gt as createEvent, h as ambientLightSensorCapability, ht as DeviceType, it as temperatureSensorCapability, j as deviceAdoptionCapability, k as controlCapability, lt as waterHeaterCapability, m as alarmPanelCapability, mt as DeviceRole, n as BaseDevice, nt as switchCapability, o as EnumSensorDateTimeFormatSchema, ot as vacuumControlCapability, p as airQualitySensorCapability, pt as DeviceFeature, q as notifierCapability, r as BaseDeviceProvider, rt as tamperCapability, st as valveCapability, tt as smokeCapability, u as TargetSchema, ut as weatherCapability, v as bestLocationMatch, vt as array, w as carbonMonoxideCapability, wt as string, x as brokerCapability, xt as number, y as binaryCapability, yt as discriminatedUnion, z as humiditySensorCapability } from "./dist-DeursJRH.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
4
4
  //#region src/ha-device-source.ts
@@ -8138,6 +8138,15 @@ var LabelDefinitionSchema = object({
8138
8138
  description: string().optional(),
8139
8139
  icon: string().optional()
8140
8140
  });
8141
+ var ClassMapDefinitionSchema = object({
8142
+ mapping: record(string(), _enum([
8143
+ "person",
8144
+ "vehicle",
8145
+ "animal",
8146
+ "package"
8147
+ ])),
8148
+ preserveOriginal: boolean()
8149
+ });
8141
8150
  var MODEL_FORMATS = [
8142
8151
  "onnx",
8143
8152
  "coreml",
@@ -8316,7 +8325,13 @@ var ModelCatalogEntrySchema = object({
8316
8325
  * `id` stays the source of truth for resolution/download/persistence; grouping
8317
8326
  * is a presentation overlay resolved back to an `id`.
8318
8327
  */
8319
- group: ModelVariantGroupSchema.optional()
8328
+ group: ModelVariantGroupSchema.optional(),
8329
+ /**
8330
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8331
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8332
+ * labels already ARE the CamStack macros (Scrypted identity map).
8333
+ */
8334
+ classMap: ClassMapDefinitionSchema.optional()
8320
8335
  });
8321
8336
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8322
8337
  format: literal("openvino"),
@@ -8345,7 +8360,8 @@ var ModelConvertMetadataSchema = object({
8345
8360
  "ocr",
8346
8361
  "segmentation"
8347
8362
  ]),
8348
- faceAlignment: boolean().optional()
8363
+ faceAlignment: boolean().optional(),
8364
+ classMap: ClassMapDefinitionSchema.optional()
8349
8365
  });
8350
8366
  var ConvertResultSchema = object({
8351
8367
  entry: ModelCatalogEntrySchema,
@@ -17813,6 +17829,33 @@ var NativeCropRefSchema = object({
17813
17829
  h: number()
17814
17830
  })
17815
17831
  });
17832
+ object({
17833
+ crop: object({
17834
+ left: number(),
17835
+ top: number(),
17836
+ width: number().positive(),
17837
+ height: number().positive()
17838
+ }).optional(),
17839
+ content: object({
17840
+ width: number().int().positive(),
17841
+ height: number().int().positive()
17842
+ }),
17843
+ fit: _enum(["stretch", "contain"]),
17844
+ format: _enum([
17845
+ "rgb",
17846
+ "gray",
17847
+ "jpeg"
17848
+ ])
17849
+ });
17850
+ var FrameRefSchema = object({
17851
+ registryId: string().min(1),
17852
+ id: string().min(1),
17853
+ width: number().int().positive(),
17854
+ height: number().int().positive(),
17855
+ format: _enum(["rgb", "gray"]),
17856
+ timestamp: number(),
17857
+ capturedAt: number().optional()
17858
+ });
17816
17859
  var ModelFormatSchema$1 = _enum([
17817
17860
  "onnx",
17818
17861
  "coreml",
@@ -18057,6 +18100,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
18057
18100
  steps: array(PipelineStepInputSchema).min(1),
18058
18101
  frame: FrameInputSchema.optional(),
18059
18102
  /**
18103
+ * Process-local lazy frame. Valid only when caller and provider resolve
18104
+ * in the same execution-group process; split/cross-node callers use
18105
+ * `frame`/`image` inline compatibility instead.
18106
+ */
18107
+ frameRef: FrameRefSchema.optional(),
18108
+ /**
18060
18109
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
18061
18110
  * the decoded pixels live in. One more member of the one-of
18062
18111
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18352,7 +18401,10 @@ var NativeCropResultSchema = object({
18352
18401
  * Which source served this crop, so a quality-sensitive consumer (the native
18353
18402
  * `keyFrame`) can reject a degraded fallback:
18354
18403
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18355
- * quality path).
18404
+ * quality path). A subject-tile serve is also native-resolution and stays
18405
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18406
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18407
+ * internal crop result (`nativeHits` vs `tileHits`).
18356
18408
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18357
18409
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18358
18410
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18843,12 +18895,41 @@ var RunnerLocalLoadSchema = object({
18843
18895
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18844
18896
  * working unchanged when they switch to reading from the runner cap.
18845
18897
  */
18898
+ var FrameLazyCountersSchema = object({
18899
+ framesDecoded: number(),
18900
+ framesAdmitted: number(),
18901
+ framesDroppedPixelFree: number(),
18902
+ viewsMaterialized: number(),
18903
+ viewsSkipped: number(),
18904
+ workerToRunnerBytes: number(),
18905
+ runnerToPoolRawBytes: number(),
18906
+ runnerToPoolJpegBytes: number(),
18907
+ onDemandFullFrameRequests: number(),
18908
+ onDemandCropRequests: number(),
18909
+ nativeHits: number(),
18910
+ nativeMisses: number(),
18911
+ tileHits: number(),
18912
+ tileMisses: number(),
18913
+ fallbackHits: number(),
18914
+ fallbackMisses: number(),
18915
+ retainedWritesAvoided: number(),
18916
+ residentRefs: number(),
18917
+ residentBytes: number(),
18918
+ releases: number(),
18919
+ evictions: number(),
18920
+ staleMisses: number()
18921
+ });
18922
+ var FrameLazyMetricsSchema = object({
18923
+ node: FrameLazyCountersSchema,
18924
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18925
+ });
18846
18926
  var RunnerLocalMetricsSchema = object({
18847
18927
  nodeId: string(),
18848
18928
  activeCameras: number(),
18849
18929
  throttledCameras: number(),
18850
18930
  avgInferenceTimeMs: number(),
18851
- queueDepth: number()
18931
+ queueDepth: number(),
18932
+ frameLazy: FrameLazyMetricsSchema.optional()
18852
18933
  });
18853
18934
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
18854
18935
  handle: FrameHandleSchema,
@@ -20148,6 +20229,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20148
20229
  location: StorageLocationSchema,
20149
20230
  relativePath: string()
20150
20231
  }), _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" });
20232
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20233
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20234
+ var ProfileSettingsBagSchema = record(string(), unknown());
20151
20235
  /**
20152
20236
  * A live terminal session hosted by the provider addon. Output and input do
20153
20237
  * NOT flow through the capability — they use the addon data plane
@@ -20177,7 +20261,14 @@ var TerminalSessionInfoSchema = object({
20177
20261
  var TerminalProfileInfoSchema = object({
20178
20262
  profileId: string(),
20179
20263
  label: string(),
20180
- description: string().optional()
20264
+ description: string().optional(),
20265
+ /** Spawn defaults the instance form copies on create. */
20266
+ executable: string().optional(),
20267
+ args: array(string()).readonly().optional(),
20268
+ cwd: string().optional(),
20269
+ environment: array(string()).readonly().optional(),
20270
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20271
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20181
20272
  });
20182
20273
  /**
20183
20274
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20190,7 +20281,12 @@ var TerminalInstanceInfoSchema = object({
20190
20281
  profileId: string(),
20191
20282
  profileLabel: string(),
20192
20283
  name: string(),
20193
- enabled: boolean()
20284
+ enabled: boolean(),
20285
+ executable: string(),
20286
+ args: array(string()).readonly(),
20287
+ cwd: string(),
20288
+ environment: array(string()).readonly(),
20289
+ profileSettings: ProfileSettingsBagSchema
20194
20290
  });
20195
20291
  var TerminalLegacyCameraSchema = object({
20196
20292
  stableId: string(),
@@ -20220,7 +20316,23 @@ var TerminalOutputBatchSchema = object({
20220
20316
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20221
20317
  targetNodeId: string().min(1),
20222
20318
  profileId: string().min(1),
20223
- name: string().trim().min(1).max(160).optional()
20319
+ name: string().trim().min(1).max(160).optional(),
20320
+ executable: string().max(1024).optional(),
20321
+ args: array(string().max(2048)).max(64).optional(),
20322
+ cwd: string().max(1024).optional(),
20323
+ environment: array(string().max(4096)).max(64).optional(),
20324
+ profileSettings: ProfileSettingsBagSchema.optional()
20325
+ }), TerminalInstanceInfoSchema, {
20326
+ kind: "mutation",
20327
+ auth: "admin"
20328
+ }), method(object({
20329
+ instanceId: string().min(1),
20330
+ name: string().trim().min(1).max(160).optional(),
20331
+ executable: string().max(1024).optional(),
20332
+ args: array(string().max(2048)).max(64).optional(),
20333
+ cwd: string().max(1024).optional(),
20334
+ environment: array(string().max(4096)).max(64).optional(),
20335
+ profileSettings: ProfileSettingsBagSchema.optional()
20224
20336
  }), TerminalInstanceInfoSchema, {
20225
20337
  kind: "mutation",
20226
20338
  auth: "admin"
@@ -20242,7 +20354,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20242
20354
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20243
20355
  profileId: string(),
20244
20356
  cols: number().int().positive(),
20245
- rows: number().int().positive()
20357
+ rows: number().int().positive(),
20358
+ executable: string().max(1024).optional(),
20359
+ args: array(string().max(2048)).max(64).optional(),
20360
+ cwd: string().max(1024).optional(),
20361
+ environment: array(string().max(4096)).max(64).optional()
20246
20362
  }), TerminalSessionInfoSchema, {
20247
20363
  kind: "mutation",
20248
20364
  auth: "admin"
@@ -24206,10 +24322,10 @@ var lawnMowerControlCapability = {
24206
24322
  *
24207
24323
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24208
24324
  * to receive an ordered list of candidate base URLs it should race
24209
- * on connect — LAN IPv4 first (lowest latency when on same network),
24210
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24211
- * race them with short timeouts and stick with the winner for the
24212
- * session.
24325
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24326
+ * when on the same network), then public hostname (if a tunnel is
24327
+ * up). The SDK can race them with short timeouts and stick with the
24328
+ * winner for the session.
24213
24329
  *
24214
24330
  * Why hub-only: agents are not directly addressable by the operator's
24215
24331
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24364,6 +24480,17 @@ var NotificationEndpointSchema = object({
24364
24480
  /** What the ranking currently resolves to (null when nothing is reachable). */
24365
24481
  resolved: string().nullable()
24366
24482
  });
24483
+ /**
24484
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24485
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24486
+ * currently expands to, so the UI can show the effective set either way.
24487
+ */
24488
+ var ViewerEndpointsSchema = object({
24489
+ /** The operator's explicit race set, or empty for AUTO. */
24490
+ baseUrls: array(string()).readonly(),
24491
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24492
+ resolved: array(string()).readonly()
24493
+ });
24367
24494
  var AllowedAddressesSchema = object({
24368
24495
  /**
24369
24496
  * Allowlist of interface addresses operators have explicitly opted
@@ -24372,6 +24499,20 @@ var AllowedAddressesSchema = object({
24372
24499
  * Network Addresses admin page and persisted by the addon.
24373
24500
  */
24374
24501
  addresses: array(string()).readonly() });
24502
+ var TlsStatusSchema = object({
24503
+ mode: _enum([
24504
+ "generated",
24505
+ "uploaded",
24506
+ "disabled"
24507
+ ]),
24508
+ leafFingerprintSha256: string().nullable(),
24509
+ caFingerprintSha256: string().nullable(),
24510
+ validTo: string().nullable(),
24511
+ sans: array(string()),
24512
+ caCertPem: string().nullable(),
24513
+ reissueError: string().nullable(),
24514
+ restartRequired: boolean()
24515
+ });
24375
24516
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24376
24517
  /**
24377
24518
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24381,17 +24522,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24381
24522
  */
24382
24523
  port: number().int().min(1).max(65535).optional(),
24383
24524
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24384
- * candidate. Default `true`. */
24525
+ * candidate. Default `false` — loopback is not a client route. */
24385
24526
  includeLoopback: boolean().optional(),
24386
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24387
- * Default `false`. */
24527
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24528
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24529
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24388
24530
  ipv4Only: boolean().optional(),
24389
24531
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24390
24532
  * Pass `'https'` when the caller is itself loaded over HTTPS
24391
24533
  * to avoid mixed-content blocks in the browser. The public
24392
24534
  * tunnel always emits `https://` regardless. */
24393
24535
  scheme: _enum(["http", "https"]).optional()
24394
- }), 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" });
24536
+ }), 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, {
24537
+ kind: "mutation",
24538
+ auth: "admin"
24539
+ }), method(object({
24540
+ certPem: string().min(1),
24541
+ keyPem: string().min(1),
24542
+ caPem: string().optional()
24543
+ }), TlsStatusSchema, {
24544
+ kind: "mutation",
24545
+ auth: "admin"
24546
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24547
+ kind: "mutation",
24548
+ auth: "admin"
24549
+ });
24395
24550
  var LockControlStatusSchema = object({
24396
24551
  /** Lifecycle state of the lock. `jammed` means the motor reported
24397
24552
  * failure to reach the target — operator intervention required. */
@@ -32418,6 +32573,12 @@ Object.freeze({
32418
32573
  addonId: null,
32419
32574
  access: "create"
32420
32575
  },
32576
+ "localNetwork.downloadCa": {
32577
+ capName: "local-network",
32578
+ capScope: "system",
32579
+ addonId: null,
32580
+ access: "view"
32581
+ },
32421
32582
  "localNetwork.getAllowedAddresses": {
32422
32583
  capName: "local-network",
32423
32584
  capScope: "system",
@@ -32442,18 +32603,42 @@ Object.freeze({
32442
32603
  addonId: null,
32443
32604
  access: "view"
32444
32605
  },
32606
+ "localNetwork.getTlsStatus": {
32607
+ capName: "local-network",
32608
+ capScope: "system",
32609
+ addonId: null,
32610
+ access: "view"
32611
+ },
32612
+ "localNetwork.getViewerEndpoints": {
32613
+ capName: "local-network",
32614
+ capScope: "system",
32615
+ addonId: null,
32616
+ access: "view"
32617
+ },
32445
32618
  "localNetwork.list": {
32446
32619
  capName: "local-network",
32447
32620
  capScope: "system",
32448
32621
  addonId: null,
32449
32622
  access: "view"
32450
32623
  },
32624
+ "localNetwork.regenerateCertificate": {
32625
+ capName: "local-network",
32626
+ capScope: "system",
32627
+ addonId: null,
32628
+ access: "create"
32629
+ },
32451
32630
  "localNetwork.resetAllowlistToBestMatch": {
32452
32631
  capName: "local-network",
32453
32632
  capScope: "system",
32454
32633
  addonId: null,
32455
32634
  access: "delete"
32456
32635
  },
32636
+ "localNetwork.revertToGeneratedCertificate": {
32637
+ capName: "local-network",
32638
+ capScope: "system",
32639
+ addonId: null,
32640
+ access: "create"
32641
+ },
32457
32642
  "localNetwork.setAllowedAddresses": {
32458
32643
  capName: "local-network",
32459
32644
  capScope: "system",
@@ -32466,6 +32651,18 @@ Object.freeze({
32466
32651
  addonId: null,
32467
32652
  access: "create"
32468
32653
  },
32654
+ "localNetwork.setViewerEndpoints": {
32655
+ capName: "local-network",
32656
+ capScope: "system",
32657
+ addonId: null,
32658
+ access: "create"
32659
+ },
32660
+ "localNetwork.uploadCertificate": {
32661
+ capName: "local-network",
32662
+ capScope: "system",
32663
+ addonId: null,
32664
+ access: "create"
32665
+ },
32469
32666
  "lockControl.lock": {
32470
32667
  capName: "lock-control",
32471
32668
  capScope: "device",
@@ -35346,6 +35543,12 @@ Object.freeze({
35346
35543
  addonId: null,
35347
35544
  access: "create"
35348
35545
  },
35546
+ "terminalSession.updateInstance": {
35547
+ capName: "terminal-session",
35548
+ capScope: "system",
35549
+ addonId: null,
35550
+ access: "create"
35551
+ },
35349
35552
  "terminalSession.writeInput": {
35350
35553
  capName: "terminal-session",
35351
35554
  capScope: "system",
@@ -38040,6 +38243,35 @@ Object.freeze(Object.fromEntries([{
38040
38243
  }]
38041
38244
  }].map((s) => [s.stepId, s.defaultModelId])));
38042
38245
  string().min(1);
38246
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38247
+ stepId: "face-embedding",
38248
+ key: "minLandmarkFaceSize",
38249
+ label: "Min face size for recognition (detection px)",
38250
+ 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.",
38251
+ type: "slider",
38252
+ min: 0,
38253
+ max: 64,
38254
+ step: 2,
38255
+ default: 24
38256
+ }];
38257
+ function clusterStepSettingKey(stepId, fieldKey) {
38258
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38259
+ }
38260
+ var ClusterSettingNumberSchema = number().finite();
38261
+ function readClusterStepSettings(config) {
38262
+ const out = {};
38263
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38264
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38265
+ const value = parsed.success ? parsed.data : field.default;
38266
+ const existing = out[field.stepId] ?? {};
38267
+ out[field.stepId] = {
38268
+ ...existing,
38269
+ [field.key]: value
38270
+ };
38271
+ }
38272
+ return out;
38273
+ }
38274
+ readClusterStepSettings({});
38043
38275
  object({
38044
38276
  /**
38045
38277
  * Fraction of the box's own size added on EACH side before cutting.
@@ -8138,6 +8138,15 @@ var LabelDefinitionSchema = object({
8138
8138
  description: string().optional(),
8139
8139
  icon: string().optional()
8140
8140
  });
8141
+ var ClassMapDefinitionSchema = object({
8142
+ mapping: record(string(), _enum([
8143
+ "person",
8144
+ "vehicle",
8145
+ "animal",
8146
+ "package"
8147
+ ])),
8148
+ preserveOriginal: boolean()
8149
+ });
8141
8150
  var MODEL_FORMATS = [
8142
8151
  "onnx",
8143
8152
  "coreml",
@@ -8316,7 +8325,13 @@ var ModelCatalogEntrySchema = object({
8316
8325
  * `id` stays the source of truth for resolution/download/persistence; grouping
8317
8326
  * is a presentation overlay resolved back to an `id`.
8318
8327
  */
8319
- group: ModelVariantGroupSchema.optional()
8328
+ group: ModelVariantGroupSchema.optional(),
8329
+ /**
8330
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8331
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8332
+ * labels already ARE the CamStack macros (Scrypted identity map).
8333
+ */
8334
+ classMap: ClassMapDefinitionSchema.optional()
8320
8335
  });
8321
8336
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8322
8337
  format: literal("openvino"),
@@ -8345,7 +8360,8 @@ var ModelConvertMetadataSchema = object({
8345
8360
  "ocr",
8346
8361
  "segmentation"
8347
8362
  ]),
8348
- faceAlignment: boolean().optional()
8363
+ faceAlignment: boolean().optional(),
8364
+ classMap: ClassMapDefinitionSchema.optional()
8349
8365
  });
8350
8366
  var ConvertResultSchema = object({
8351
8367
  entry: ModelCatalogEntrySchema,
@@ -17813,6 +17829,33 @@ var NativeCropRefSchema = object({
17813
17829
  h: number()
17814
17830
  })
17815
17831
  });
17832
+ object({
17833
+ crop: object({
17834
+ left: number(),
17835
+ top: number(),
17836
+ width: number().positive(),
17837
+ height: number().positive()
17838
+ }).optional(),
17839
+ content: object({
17840
+ width: number().int().positive(),
17841
+ height: number().int().positive()
17842
+ }),
17843
+ fit: _enum(["stretch", "contain"]),
17844
+ format: _enum([
17845
+ "rgb",
17846
+ "gray",
17847
+ "jpeg"
17848
+ ])
17849
+ });
17850
+ var FrameRefSchema = object({
17851
+ registryId: string().min(1),
17852
+ id: string().min(1),
17853
+ width: number().int().positive(),
17854
+ height: number().int().positive(),
17855
+ format: _enum(["rgb", "gray"]),
17856
+ timestamp: number(),
17857
+ capturedAt: number().optional()
17858
+ });
17816
17859
  var ModelFormatSchema$1 = _enum([
17817
17860
  "onnx",
17818
17861
  "coreml",
@@ -18057,6 +18100,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
18057
18100
  steps: array(PipelineStepInputSchema).min(1),
18058
18101
  frame: FrameInputSchema.optional(),
18059
18102
  /**
18103
+ * Process-local lazy frame. Valid only when caller and provider resolve
18104
+ * in the same execution-group process; split/cross-node callers use
18105
+ * `frame`/`image` inline compatibility instead.
18106
+ */
18107
+ frameRef: FrameRefSchema.optional(),
18108
+ /**
18060
18109
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
18061
18110
  * the decoded pixels live in. One more member of the one-of
18062
18111
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18352,7 +18401,10 @@ var NativeCropResultSchema = object({
18352
18401
  * Which source served this crop, so a quality-sensitive consumer (the native
18353
18402
  * `keyFrame`) can reject a degraded fallback:
18354
18403
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18355
- * quality path).
18404
+ * quality path). A subject-tile serve is also native-resolution and stays
18405
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18406
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18407
+ * internal crop result (`nativeHits` vs `tileHits`).
18356
18408
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18357
18409
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18358
18410
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18843,12 +18895,41 @@ var RunnerLocalLoadSchema = object({
18843
18895
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18844
18896
  * working unchanged when they switch to reading from the runner cap.
18845
18897
  */
18898
+ var FrameLazyCountersSchema = object({
18899
+ framesDecoded: number(),
18900
+ framesAdmitted: number(),
18901
+ framesDroppedPixelFree: number(),
18902
+ viewsMaterialized: number(),
18903
+ viewsSkipped: number(),
18904
+ workerToRunnerBytes: number(),
18905
+ runnerToPoolRawBytes: number(),
18906
+ runnerToPoolJpegBytes: number(),
18907
+ onDemandFullFrameRequests: number(),
18908
+ onDemandCropRequests: number(),
18909
+ nativeHits: number(),
18910
+ nativeMisses: number(),
18911
+ tileHits: number(),
18912
+ tileMisses: number(),
18913
+ fallbackHits: number(),
18914
+ fallbackMisses: number(),
18915
+ retainedWritesAvoided: number(),
18916
+ residentRefs: number(),
18917
+ residentBytes: number(),
18918
+ releases: number(),
18919
+ evictions: number(),
18920
+ staleMisses: number()
18921
+ });
18922
+ var FrameLazyMetricsSchema = object({
18923
+ node: FrameLazyCountersSchema,
18924
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18925
+ });
18846
18926
  var RunnerLocalMetricsSchema = object({
18847
18927
  nodeId: string(),
18848
18928
  activeCameras: number(),
18849
18929
  throttledCameras: number(),
18850
18930
  avgInferenceTimeMs: number(),
18851
- queueDepth: number()
18931
+ queueDepth: number(),
18932
+ frameLazy: FrameLazyMetricsSchema.optional()
18852
18933
  });
18853
18934
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
18854
18935
  handle: FrameHandleSchema,
@@ -20148,6 +20229,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20148
20229
  location: StorageLocationSchema,
20149
20230
  relativePath: string()
20150
20231
  }), _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" });
20232
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20233
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20234
+ var ProfileSettingsBagSchema = record(string(), unknown());
20151
20235
  /**
20152
20236
  * A live terminal session hosted by the provider addon. Output and input do
20153
20237
  * NOT flow through the capability — they use the addon data plane
@@ -20177,7 +20261,14 @@ var TerminalSessionInfoSchema = object({
20177
20261
  var TerminalProfileInfoSchema = object({
20178
20262
  profileId: string(),
20179
20263
  label: string(),
20180
- description: string().optional()
20264
+ description: string().optional(),
20265
+ /** Spawn defaults the instance form copies on create. */
20266
+ executable: string().optional(),
20267
+ args: array(string()).readonly().optional(),
20268
+ cwd: string().optional(),
20269
+ environment: array(string()).readonly().optional(),
20270
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20271
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20181
20272
  });
20182
20273
  /**
20183
20274
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20190,7 +20281,12 @@ var TerminalInstanceInfoSchema = object({
20190
20281
  profileId: string(),
20191
20282
  profileLabel: string(),
20192
20283
  name: string(),
20193
- enabled: boolean()
20284
+ enabled: boolean(),
20285
+ executable: string(),
20286
+ args: array(string()).readonly(),
20287
+ cwd: string(),
20288
+ environment: array(string()).readonly(),
20289
+ profileSettings: ProfileSettingsBagSchema
20194
20290
  });
20195
20291
  var TerminalLegacyCameraSchema = object({
20196
20292
  stableId: string(),
@@ -20220,7 +20316,23 @@ var TerminalOutputBatchSchema = object({
20220
20316
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20221
20317
  targetNodeId: string().min(1),
20222
20318
  profileId: string().min(1),
20223
- name: string().trim().min(1).max(160).optional()
20319
+ name: string().trim().min(1).max(160).optional(),
20320
+ executable: string().max(1024).optional(),
20321
+ args: array(string().max(2048)).max(64).optional(),
20322
+ cwd: string().max(1024).optional(),
20323
+ environment: array(string().max(4096)).max(64).optional(),
20324
+ profileSettings: ProfileSettingsBagSchema.optional()
20325
+ }), TerminalInstanceInfoSchema, {
20326
+ kind: "mutation",
20327
+ auth: "admin"
20328
+ }), method(object({
20329
+ instanceId: string().min(1),
20330
+ name: string().trim().min(1).max(160).optional(),
20331
+ executable: string().max(1024).optional(),
20332
+ args: array(string().max(2048)).max(64).optional(),
20333
+ cwd: string().max(1024).optional(),
20334
+ environment: array(string().max(4096)).max(64).optional(),
20335
+ profileSettings: ProfileSettingsBagSchema.optional()
20224
20336
  }), TerminalInstanceInfoSchema, {
20225
20337
  kind: "mutation",
20226
20338
  auth: "admin"
@@ -20242,7 +20354,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20242
20354
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20243
20355
  profileId: string(),
20244
20356
  cols: number().int().positive(),
20245
- rows: number().int().positive()
20357
+ rows: number().int().positive(),
20358
+ executable: string().max(1024).optional(),
20359
+ args: array(string().max(2048)).max(64).optional(),
20360
+ cwd: string().max(1024).optional(),
20361
+ environment: array(string().max(4096)).max(64).optional()
20246
20362
  }), TerminalSessionInfoSchema, {
20247
20363
  kind: "mutation",
20248
20364
  auth: "admin"
@@ -24206,10 +24322,10 @@ var lawnMowerControlCapability = {
24206
24322
  *
24207
24323
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24208
24324
  * to receive an ordered list of candidate base URLs it should race
24209
- * on connect — LAN IPv4 first (lowest latency when on same network),
24210
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24211
- * race them with short timeouts and stick with the winner for the
24212
- * session.
24325
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24326
+ * when on the same network), then public hostname (if a tunnel is
24327
+ * up). The SDK can race them with short timeouts and stick with the
24328
+ * winner for the session.
24213
24329
  *
24214
24330
  * Why hub-only: agents are not directly addressable by the operator's
24215
24331
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24364,6 +24480,17 @@ var NotificationEndpointSchema = object({
24364
24480
  /** What the ranking currently resolves to (null when nothing is reachable). */
24365
24481
  resolved: string().nullable()
24366
24482
  });
24483
+ /**
24484
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24485
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24486
+ * currently expands to, so the UI can show the effective set either way.
24487
+ */
24488
+ var ViewerEndpointsSchema = object({
24489
+ /** The operator's explicit race set, or empty for AUTO. */
24490
+ baseUrls: array(string()).readonly(),
24491
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24492
+ resolved: array(string()).readonly()
24493
+ });
24367
24494
  var AllowedAddressesSchema = object({
24368
24495
  /**
24369
24496
  * Allowlist of interface addresses operators have explicitly opted
@@ -24372,6 +24499,20 @@ var AllowedAddressesSchema = object({
24372
24499
  * Network Addresses admin page and persisted by the addon.
24373
24500
  */
24374
24501
  addresses: array(string()).readonly() });
24502
+ var TlsStatusSchema = object({
24503
+ mode: _enum([
24504
+ "generated",
24505
+ "uploaded",
24506
+ "disabled"
24507
+ ]),
24508
+ leafFingerprintSha256: string().nullable(),
24509
+ caFingerprintSha256: string().nullable(),
24510
+ validTo: string().nullable(),
24511
+ sans: array(string()),
24512
+ caCertPem: string().nullable(),
24513
+ reissueError: string().nullable(),
24514
+ restartRequired: boolean()
24515
+ });
24375
24516
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24376
24517
  /**
24377
24518
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24381,17 +24522,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24381
24522
  */
24382
24523
  port: number().int().min(1).max(65535).optional(),
24383
24524
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24384
- * candidate. Default `true`. */
24525
+ * candidate. Default `false` — loopback is not a client route. */
24385
24526
  includeLoopback: boolean().optional(),
24386
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24387
- * Default `false`. */
24527
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24528
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24529
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24388
24530
  ipv4Only: boolean().optional(),
24389
24531
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24390
24532
  * Pass `'https'` when the caller is itself loaded over HTTPS
24391
24533
  * to avoid mixed-content blocks in the browser. The public
24392
24534
  * tunnel always emits `https://` regardless. */
24393
24535
  scheme: _enum(["http", "https"]).optional()
24394
- }), 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" });
24536
+ }), 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, {
24537
+ kind: "mutation",
24538
+ auth: "admin"
24539
+ }), method(object({
24540
+ certPem: string().min(1),
24541
+ keyPem: string().min(1),
24542
+ caPem: string().optional()
24543
+ }), TlsStatusSchema, {
24544
+ kind: "mutation",
24545
+ auth: "admin"
24546
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24547
+ kind: "mutation",
24548
+ auth: "admin"
24549
+ });
24395
24550
  var LockControlStatusSchema = object({
24396
24551
  /** Lifecycle state of the lock. `jammed` means the motor reported
24397
24552
  * failure to reach the target — operator intervention required. */
@@ -32418,6 +32573,12 @@ Object.freeze({
32418
32573
  addonId: null,
32419
32574
  access: "create"
32420
32575
  },
32576
+ "localNetwork.downloadCa": {
32577
+ capName: "local-network",
32578
+ capScope: "system",
32579
+ addonId: null,
32580
+ access: "view"
32581
+ },
32421
32582
  "localNetwork.getAllowedAddresses": {
32422
32583
  capName: "local-network",
32423
32584
  capScope: "system",
@@ -32442,18 +32603,42 @@ Object.freeze({
32442
32603
  addonId: null,
32443
32604
  access: "view"
32444
32605
  },
32606
+ "localNetwork.getTlsStatus": {
32607
+ capName: "local-network",
32608
+ capScope: "system",
32609
+ addonId: null,
32610
+ access: "view"
32611
+ },
32612
+ "localNetwork.getViewerEndpoints": {
32613
+ capName: "local-network",
32614
+ capScope: "system",
32615
+ addonId: null,
32616
+ access: "view"
32617
+ },
32445
32618
  "localNetwork.list": {
32446
32619
  capName: "local-network",
32447
32620
  capScope: "system",
32448
32621
  addonId: null,
32449
32622
  access: "view"
32450
32623
  },
32624
+ "localNetwork.regenerateCertificate": {
32625
+ capName: "local-network",
32626
+ capScope: "system",
32627
+ addonId: null,
32628
+ access: "create"
32629
+ },
32451
32630
  "localNetwork.resetAllowlistToBestMatch": {
32452
32631
  capName: "local-network",
32453
32632
  capScope: "system",
32454
32633
  addonId: null,
32455
32634
  access: "delete"
32456
32635
  },
32636
+ "localNetwork.revertToGeneratedCertificate": {
32637
+ capName: "local-network",
32638
+ capScope: "system",
32639
+ addonId: null,
32640
+ access: "create"
32641
+ },
32457
32642
  "localNetwork.setAllowedAddresses": {
32458
32643
  capName: "local-network",
32459
32644
  capScope: "system",
@@ -32466,6 +32651,18 @@ Object.freeze({
32466
32651
  addonId: null,
32467
32652
  access: "create"
32468
32653
  },
32654
+ "localNetwork.setViewerEndpoints": {
32655
+ capName: "local-network",
32656
+ capScope: "system",
32657
+ addonId: null,
32658
+ access: "create"
32659
+ },
32660
+ "localNetwork.uploadCertificate": {
32661
+ capName: "local-network",
32662
+ capScope: "system",
32663
+ addonId: null,
32664
+ access: "create"
32665
+ },
32469
32666
  "lockControl.lock": {
32470
32667
  capName: "lock-control",
32471
32668
  capScope: "device",
@@ -35346,6 +35543,12 @@ Object.freeze({
35346
35543
  addonId: null,
35347
35544
  access: "create"
35348
35545
  },
35546
+ "terminalSession.updateInstance": {
35547
+ capName: "terminal-session",
35548
+ capScope: "system",
35549
+ addonId: null,
35550
+ access: "create"
35551
+ },
35349
35552
  "terminalSession.writeInput": {
35350
35553
  capName: "terminal-session",
35351
35554
  capScope: "system",
@@ -38040,6 +38243,35 @@ Object.freeze(Object.fromEntries([{
38040
38243
  }]
38041
38244
  }].map((s) => [s.stepId, s.defaultModelId])));
38042
38245
  string().min(1);
38246
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38247
+ stepId: "face-embedding",
38248
+ key: "minLandmarkFaceSize",
38249
+ label: "Min face size for recognition (detection px)",
38250
+ 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.",
38251
+ type: "slider",
38252
+ min: 0,
38253
+ max: 64,
38254
+ step: 2,
38255
+ default: 24
38256
+ }];
38257
+ function clusterStepSettingKey(stepId, fieldKey) {
38258
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38259
+ }
38260
+ var ClusterSettingNumberSchema = number().finite();
38261
+ function readClusterStepSettings(config) {
38262
+ const out = {};
38263
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38264
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38265
+ const value = parsed.success ? parsed.data : field.default;
38266
+ const existing = out[field.stepId] ?? {};
38267
+ out[field.stepId] = {
38268
+ ...existing,
38269
+ [field.key]: value
38270
+ };
38271
+ }
38272
+ return out;
38273
+ }
38274
+ readClusterStepSettings({});
38043
38275
  object({
38044
38276
  /**
38045
38277
  * Fraction of the box's own size added on EACH side before cutting.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  //#endregion
6
- const require_dist = require("../dist-DGR35D_v.js");
6
+ const require_dist = require("../dist-BoTrJXhA.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  //#region src/ha-export/topics.ts
9
9
  /**
@@ -1,4 +1,4 @@
1
- import { M as deviceExportCapability, Ot as EventCategory, S as buildAddonRouteProvider, Y as oauthIntegrationCapability, a as CameraSwitchIdSchema, c as HvacModeSchema, f as addonRoutesCapability, ft as BaseAddon, i as COCO_TO_MACRO, l as MediaPlayerRepeatSchema, s as FanDirectionSchema, t as AlarmArmModeSchema, wt as string } from "../dist-CMmUPJOe.mjs";
1
+ import { M as deviceExportCapability, Ot as EventCategory, S as buildAddonRouteProvider, Y as oauthIntegrationCapability, a as CameraSwitchIdSchema, c as HvacModeSchema, f as addonRoutesCapability, ft as BaseAddon, i as COCO_TO_MACRO, l as MediaPlayerRepeatSchema, s as FanDirectionSchema, t as AlarmArmModeSchema, wt as string } from "../dist-DeursJRH.mjs";
2
2
  import { createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/ha-export/topics.ts
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.2.39",
3
+ "version": "1.2.40",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",