@camstack/addon-provider-homematic 1.2.27 → 1.2.28

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 (3) hide show
  1. package/dist/addon.js +248 -16
  2. package/dist/addon.mjs +248 -16
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8029,6 +8029,15 @@ var LabelDefinitionSchema = object({
8029
8029
  description: string().optional(),
8030
8030
  icon: string().optional()
8031
8031
  });
8032
+ var ClassMapDefinitionSchema = object({
8033
+ mapping: record(string(), _enum([
8034
+ "person",
8035
+ "vehicle",
8036
+ "animal",
8037
+ "package"
8038
+ ])),
8039
+ preserveOriginal: boolean()
8040
+ });
8032
8041
  var MODEL_FORMATS = [
8033
8042
  "onnx",
8034
8043
  "coreml",
@@ -8207,7 +8216,13 @@ var ModelCatalogEntrySchema = object({
8207
8216
  * `id` stays the source of truth for resolution/download/persistence; grouping
8208
8217
  * is a presentation overlay resolved back to an `id`.
8209
8218
  */
8210
- group: ModelVariantGroupSchema.optional()
8219
+ group: ModelVariantGroupSchema.optional(),
8220
+ /**
8221
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8222
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8223
+ * labels already ARE the CamStack macros (Scrypted identity map).
8224
+ */
8225
+ classMap: ClassMapDefinitionSchema.optional()
8211
8226
  });
8212
8227
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8213
8228
  format: literal("openvino"),
@@ -8236,7 +8251,8 @@ var ModelConvertMetadataSchema = object({
8236
8251
  "ocr",
8237
8252
  "segmentation"
8238
8253
  ]),
8239
- faceAlignment: boolean().optional()
8254
+ faceAlignment: boolean().optional(),
8255
+ classMap: ClassMapDefinitionSchema.optional()
8240
8256
  });
8241
8257
  var ConvertResultSchema = object({
8242
8258
  entry: ModelCatalogEntrySchema,
@@ -17595,6 +17611,33 @@ var NativeCropRefSchema = object({
17595
17611
  h: number()
17596
17612
  })
17597
17613
  });
17614
+ object({
17615
+ crop: object({
17616
+ left: number(),
17617
+ top: number(),
17618
+ width: number().positive(),
17619
+ height: number().positive()
17620
+ }).optional(),
17621
+ content: object({
17622
+ width: number().int().positive(),
17623
+ height: number().int().positive()
17624
+ }),
17625
+ fit: _enum(["stretch", "contain"]),
17626
+ format: _enum([
17627
+ "rgb",
17628
+ "gray",
17629
+ "jpeg"
17630
+ ])
17631
+ });
17632
+ var FrameRefSchema = object({
17633
+ registryId: string().min(1),
17634
+ id: string().min(1),
17635
+ width: number().int().positive(),
17636
+ height: number().int().positive(),
17637
+ format: _enum(["rgb", "gray"]),
17638
+ timestamp: number(),
17639
+ capturedAt: number().optional()
17640
+ });
17598
17641
  var ModelFormatSchema$1 = _enum([
17599
17642
  "onnx",
17600
17643
  "coreml",
@@ -17839,6 +17882,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17839
17882
  steps: array(PipelineStepInputSchema).min(1),
17840
17883
  frame: FrameInputSchema.optional(),
17841
17884
  /**
17885
+ * Process-local lazy frame. Valid only when caller and provider resolve
17886
+ * in the same execution-group process; split/cross-node callers use
17887
+ * `frame`/`image` inline compatibility instead.
17888
+ */
17889
+ frameRef: FrameRefSchema.optional(),
17890
+ /**
17842
17891
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17843
17892
  * the decoded pixels live in. One more member of the one-of
17844
17893
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18134,7 +18183,10 @@ var NativeCropResultSchema = object({
18134
18183
  * Which source served this crop, so a quality-sensitive consumer (the native
18135
18184
  * `keyFrame`) can reject a degraded fallback:
18136
18185
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18137
- * quality path).
18186
+ * quality path). A subject-tile serve is also native-resolution and stays
18187
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18188
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18189
+ * internal crop result (`nativeHits` vs `tileHits`).
18138
18190
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18139
18191
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18140
18192
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18625,12 +18677,41 @@ var RunnerLocalLoadSchema = object({
18625
18677
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18626
18678
  * working unchanged when they switch to reading from the runner cap.
18627
18679
  */
18680
+ var FrameLazyCountersSchema = object({
18681
+ framesDecoded: number(),
18682
+ framesAdmitted: number(),
18683
+ framesDroppedPixelFree: number(),
18684
+ viewsMaterialized: number(),
18685
+ viewsSkipped: number(),
18686
+ workerToRunnerBytes: number(),
18687
+ runnerToPoolRawBytes: number(),
18688
+ runnerToPoolJpegBytes: number(),
18689
+ onDemandFullFrameRequests: number(),
18690
+ onDemandCropRequests: number(),
18691
+ nativeHits: number(),
18692
+ nativeMisses: number(),
18693
+ tileHits: number(),
18694
+ tileMisses: number(),
18695
+ fallbackHits: number(),
18696
+ fallbackMisses: number(),
18697
+ retainedWritesAvoided: number(),
18698
+ residentRefs: number(),
18699
+ residentBytes: number(),
18700
+ releases: number(),
18701
+ evictions: number(),
18702
+ staleMisses: number()
18703
+ });
18704
+ var FrameLazyMetricsSchema = object({
18705
+ node: FrameLazyCountersSchema,
18706
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18707
+ });
18628
18708
  var RunnerLocalMetricsSchema = object({
18629
18709
  nodeId: string(),
18630
18710
  activeCameras: number(),
18631
18711
  throttledCameras: number(),
18632
18712
  avgInferenceTimeMs: number(),
18633
- queueDepth: number()
18713
+ queueDepth: number(),
18714
+ frameLazy: FrameLazyMetricsSchema.optional()
18634
18715
  });
18635
18716
  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({
18636
18717
  handle: FrameHandleSchema,
@@ -19930,6 +20011,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19930
20011
  location: StorageLocationSchema,
19931
20012
  relativePath: string()
19932
20013
  }), _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" });
20014
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20015
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20016
+ var ProfileSettingsBagSchema = record(string(), unknown());
19933
20017
  /**
19934
20018
  * A live terminal session hosted by the provider addon. Output and input do
19935
20019
  * NOT flow through the capability — they use the addon data plane
@@ -19959,7 +20043,14 @@ var TerminalSessionInfoSchema = object({
19959
20043
  var TerminalProfileInfoSchema = object({
19960
20044
  profileId: string(),
19961
20045
  label: string(),
19962
- description: string().optional()
20046
+ description: string().optional(),
20047
+ /** Spawn defaults the instance form copies on create. */
20048
+ executable: string().optional(),
20049
+ args: array(string()).readonly().optional(),
20050
+ cwd: string().optional(),
20051
+ environment: array(string()).readonly().optional(),
20052
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20053
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19963
20054
  });
19964
20055
  /**
19965
20056
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19972,7 +20063,12 @@ var TerminalInstanceInfoSchema = object({
19972
20063
  profileId: string(),
19973
20064
  profileLabel: string(),
19974
20065
  name: string(),
19975
- enabled: boolean()
20066
+ enabled: boolean(),
20067
+ executable: string(),
20068
+ args: array(string()).readonly(),
20069
+ cwd: string(),
20070
+ environment: array(string()).readonly(),
20071
+ profileSettings: ProfileSettingsBagSchema
19976
20072
  });
19977
20073
  var TerminalLegacyCameraSchema = object({
19978
20074
  stableId: string(),
@@ -20002,7 +20098,23 @@ var TerminalOutputBatchSchema = object({
20002
20098
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20003
20099
  targetNodeId: string().min(1),
20004
20100
  profileId: string().min(1),
20005
- name: string().trim().min(1).max(160).optional()
20101
+ name: string().trim().min(1).max(160).optional(),
20102
+ executable: string().max(1024).optional(),
20103
+ args: array(string().max(2048)).max(64).optional(),
20104
+ cwd: string().max(1024).optional(),
20105
+ environment: array(string().max(4096)).max(64).optional(),
20106
+ profileSettings: ProfileSettingsBagSchema.optional()
20107
+ }), TerminalInstanceInfoSchema, {
20108
+ kind: "mutation",
20109
+ auth: "admin"
20110
+ }), method(object({
20111
+ instanceId: string().min(1),
20112
+ name: string().trim().min(1).max(160).optional(),
20113
+ executable: string().max(1024).optional(),
20114
+ args: array(string().max(2048)).max(64).optional(),
20115
+ cwd: string().max(1024).optional(),
20116
+ environment: array(string().max(4096)).max(64).optional(),
20117
+ profileSettings: ProfileSettingsBagSchema.optional()
20006
20118
  }), TerminalInstanceInfoSchema, {
20007
20119
  kind: "mutation",
20008
20120
  auth: "admin"
@@ -20024,7 +20136,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20024
20136
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20025
20137
  profileId: string(),
20026
20138
  cols: number().int().positive(),
20027
- rows: number().int().positive()
20139
+ rows: number().int().positive(),
20140
+ executable: string().max(1024).optional(),
20141
+ args: array(string().max(2048)).max(64).optional(),
20142
+ cwd: string().max(1024).optional(),
20143
+ environment: array(string().max(4096)).max(64).optional()
20028
20144
  }), TerminalSessionInfoSchema, {
20029
20145
  kind: "mutation",
20030
20146
  auth: "admin"
@@ -23899,10 +24015,10 @@ var lawnMowerControlCapability = {
23899
24015
  *
23900
24016
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23901
24017
  * to receive an ordered list of candidate base URLs it should race
23902
- * on connect — LAN IPv4 first (lowest latency when on same network),
23903
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23904
- * race them with short timeouts and stick with the winner for the
23905
- * session.
24018
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24019
+ * when on the same network), then public hostname (if a tunnel is
24020
+ * up). The SDK can race them with short timeouts and stick with the
24021
+ * winner for the session.
23906
24022
  *
23907
24023
  * Why hub-only: agents are not directly addressable by the operator's
23908
24024
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24057,6 +24173,17 @@ var NotificationEndpointSchema = object({
24057
24173
  /** What the ranking currently resolves to (null when nothing is reachable). */
24058
24174
  resolved: string().nullable()
24059
24175
  });
24176
+ /**
24177
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24178
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24179
+ * currently expands to, so the UI can show the effective set either way.
24180
+ */
24181
+ var ViewerEndpointsSchema = object({
24182
+ /** The operator's explicit race set, or empty for AUTO. */
24183
+ baseUrls: array(string()).readonly(),
24184
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24185
+ resolved: array(string()).readonly()
24186
+ });
24060
24187
  var AllowedAddressesSchema = object({
24061
24188
  /**
24062
24189
  * Allowlist of interface addresses operators have explicitly opted
@@ -24065,6 +24192,20 @@ var AllowedAddressesSchema = object({
24065
24192
  * Network Addresses admin page and persisted by the addon.
24066
24193
  */
24067
24194
  addresses: array(string()).readonly() });
24195
+ var TlsStatusSchema = object({
24196
+ mode: _enum([
24197
+ "generated",
24198
+ "uploaded",
24199
+ "disabled"
24200
+ ]),
24201
+ leafFingerprintSha256: string().nullable(),
24202
+ caFingerprintSha256: string().nullable(),
24203
+ validTo: string().nullable(),
24204
+ sans: array(string()),
24205
+ caCertPem: string().nullable(),
24206
+ reissueError: string().nullable(),
24207
+ restartRequired: boolean()
24208
+ });
24068
24209
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24069
24210
  /**
24070
24211
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24074,17 +24215,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24074
24215
  */
24075
24216
  port: number().int().min(1).max(65535).optional(),
24076
24217
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24077
- * candidate. Default `true`. */
24218
+ * candidate. Default `false` — loopback is not a client route. */
24078
24219
  includeLoopback: boolean().optional(),
24079
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24080
- * Default `false`. */
24220
+ /** Skip IPv6 entries. Default `false` — the palette includes stable
24221
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24222
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24081
24223
  ipv4Only: boolean().optional(),
24082
24224
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24083
24225
  * Pass `'https'` when the caller is itself loaded over HTTPS
24084
24226
  * to avoid mixed-content blocks in the browser. The public
24085
24227
  * tunnel always emits `https://` regardless. */
24086
24228
  scheme: _enum(["http", "https"]).optional()
24087
- }), 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" });
24229
+ }), 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, {
24230
+ kind: "mutation",
24231
+ auth: "admin"
24232
+ }), method(object({
24233
+ certPem: string().min(1),
24234
+ keyPem: string().min(1),
24235
+ caPem: string().optional()
24236
+ }), TlsStatusSchema, {
24237
+ kind: "mutation",
24238
+ auth: "admin"
24239
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24240
+ kind: "mutation",
24241
+ auth: "admin"
24242
+ });
24088
24243
  var LockControlStatusSchema = object({
24089
24244
  /** Lifecycle state of the lock. `jammed` means the motor reported
24090
24245
  * failure to reach the target — operator intervention required. */
@@ -32111,6 +32266,12 @@ Object.freeze({
32111
32266
  addonId: null,
32112
32267
  access: "create"
32113
32268
  },
32269
+ "localNetwork.downloadCa": {
32270
+ capName: "local-network",
32271
+ capScope: "system",
32272
+ addonId: null,
32273
+ access: "view"
32274
+ },
32114
32275
  "localNetwork.getAllowedAddresses": {
32115
32276
  capName: "local-network",
32116
32277
  capScope: "system",
@@ -32135,18 +32296,42 @@ Object.freeze({
32135
32296
  addonId: null,
32136
32297
  access: "view"
32137
32298
  },
32299
+ "localNetwork.getTlsStatus": {
32300
+ capName: "local-network",
32301
+ capScope: "system",
32302
+ addonId: null,
32303
+ access: "view"
32304
+ },
32305
+ "localNetwork.getViewerEndpoints": {
32306
+ capName: "local-network",
32307
+ capScope: "system",
32308
+ addonId: null,
32309
+ access: "view"
32310
+ },
32138
32311
  "localNetwork.list": {
32139
32312
  capName: "local-network",
32140
32313
  capScope: "system",
32141
32314
  addonId: null,
32142
32315
  access: "view"
32143
32316
  },
32317
+ "localNetwork.regenerateCertificate": {
32318
+ capName: "local-network",
32319
+ capScope: "system",
32320
+ addonId: null,
32321
+ access: "create"
32322
+ },
32144
32323
  "localNetwork.resetAllowlistToBestMatch": {
32145
32324
  capName: "local-network",
32146
32325
  capScope: "system",
32147
32326
  addonId: null,
32148
32327
  access: "delete"
32149
32328
  },
32329
+ "localNetwork.revertToGeneratedCertificate": {
32330
+ capName: "local-network",
32331
+ capScope: "system",
32332
+ addonId: null,
32333
+ access: "create"
32334
+ },
32150
32335
  "localNetwork.setAllowedAddresses": {
32151
32336
  capName: "local-network",
32152
32337
  capScope: "system",
@@ -32159,6 +32344,18 @@ Object.freeze({
32159
32344
  addonId: null,
32160
32345
  access: "create"
32161
32346
  },
32347
+ "localNetwork.setViewerEndpoints": {
32348
+ capName: "local-network",
32349
+ capScope: "system",
32350
+ addonId: null,
32351
+ access: "create"
32352
+ },
32353
+ "localNetwork.uploadCertificate": {
32354
+ capName: "local-network",
32355
+ capScope: "system",
32356
+ addonId: null,
32357
+ access: "create"
32358
+ },
32162
32359
  "lockControl.lock": {
32163
32360
  capName: "lock-control",
32164
32361
  capScope: "device",
@@ -35039,6 +35236,12 @@ Object.freeze({
35039
35236
  addonId: null,
35040
35237
  access: "create"
35041
35238
  },
35239
+ "terminalSession.updateInstance": {
35240
+ capName: "terminal-session",
35241
+ capScope: "system",
35242
+ addonId: null,
35243
+ access: "create"
35244
+ },
35042
35245
  "terminalSession.writeInput": {
35043
35246
  capName: "terminal-session",
35044
35247
  capScope: "system",
@@ -37526,6 +37729,35 @@ Object.freeze(Object.fromEntries([{
37526
37729
  }]
37527
37730
  }].map((s) => [s.stepId, s.defaultModelId])));
37528
37731
  string().min(1);
37732
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37733
+ stepId: "face-embedding",
37734
+ key: "minLandmarkFaceSize",
37735
+ label: "Min face size for recognition (detection px)",
37736
+ 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.",
37737
+ type: "slider",
37738
+ min: 0,
37739
+ max: 64,
37740
+ step: 2,
37741
+ default: 24
37742
+ }];
37743
+ function clusterStepSettingKey(stepId, fieldKey) {
37744
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37745
+ }
37746
+ var ClusterSettingNumberSchema = number().finite();
37747
+ function readClusterStepSettings(config) {
37748
+ const out = {};
37749
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37750
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37751
+ const value = parsed.success ? parsed.data : field.default;
37752
+ const existing = out[field.stepId] ?? {};
37753
+ out[field.stepId] = {
37754
+ ...existing,
37755
+ [field.key]: value
37756
+ };
37757
+ }
37758
+ return out;
37759
+ }
37760
+ readClusterStepSettings({});
37529
37761
  object({
37530
37762
  /**
37531
37763
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -8030,6 +8030,15 @@ var LabelDefinitionSchema = object({
8030
8030
  description: string().optional(),
8031
8031
  icon: string().optional()
8032
8032
  });
8033
+ var ClassMapDefinitionSchema = object({
8034
+ mapping: record(string(), _enum([
8035
+ "person",
8036
+ "vehicle",
8037
+ "animal",
8038
+ "package"
8039
+ ])),
8040
+ preserveOriginal: boolean()
8041
+ });
8033
8042
  var MODEL_FORMATS = [
8034
8043
  "onnx",
8035
8044
  "coreml",
@@ -8208,7 +8217,13 @@ var ModelCatalogEntrySchema = object({
8208
8217
  * `id` stays the source of truth for resolution/download/persistence; grouping
8209
8218
  * is a presentation overlay resolved back to an `id`.
8210
8219
  */
8211
- group: ModelVariantGroupSchema.optional()
8220
+ group: ModelVariantGroupSchema.optional(),
8221
+ /**
8222
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8223
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8224
+ * labels already ARE the CamStack macros (Scrypted identity map).
8225
+ */
8226
+ classMap: ClassMapDefinitionSchema.optional()
8212
8227
  });
8213
8228
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8214
8229
  format: literal("openvino"),
@@ -8237,7 +8252,8 @@ var ModelConvertMetadataSchema = object({
8237
8252
  "ocr",
8238
8253
  "segmentation"
8239
8254
  ]),
8240
- faceAlignment: boolean().optional()
8255
+ faceAlignment: boolean().optional(),
8256
+ classMap: ClassMapDefinitionSchema.optional()
8241
8257
  });
8242
8258
  var ConvertResultSchema = object({
8243
8259
  entry: ModelCatalogEntrySchema,
@@ -17596,6 +17612,33 @@ var NativeCropRefSchema = object({
17596
17612
  h: number()
17597
17613
  })
17598
17614
  });
17615
+ object({
17616
+ crop: object({
17617
+ left: number(),
17618
+ top: number(),
17619
+ width: number().positive(),
17620
+ height: number().positive()
17621
+ }).optional(),
17622
+ content: object({
17623
+ width: number().int().positive(),
17624
+ height: number().int().positive()
17625
+ }),
17626
+ fit: _enum(["stretch", "contain"]),
17627
+ format: _enum([
17628
+ "rgb",
17629
+ "gray",
17630
+ "jpeg"
17631
+ ])
17632
+ });
17633
+ var FrameRefSchema = object({
17634
+ registryId: string().min(1),
17635
+ id: string().min(1),
17636
+ width: number().int().positive(),
17637
+ height: number().int().positive(),
17638
+ format: _enum(["rgb", "gray"]),
17639
+ timestamp: number(),
17640
+ capturedAt: number().optional()
17641
+ });
17599
17642
  var ModelFormatSchema$1 = _enum([
17600
17643
  "onnx",
17601
17644
  "coreml",
@@ -17840,6 +17883,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17840
17883
  steps: array(PipelineStepInputSchema).min(1),
17841
17884
  frame: FrameInputSchema.optional(),
17842
17885
  /**
17886
+ * Process-local lazy frame. Valid only when caller and provider resolve
17887
+ * in the same execution-group process; split/cross-node callers use
17888
+ * `frame`/`image` inline compatibility instead.
17889
+ */
17890
+ frameRef: FrameRefSchema.optional(),
17891
+ /**
17843
17892
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17844
17893
  * the decoded pixels live in. One more member of the one-of
17845
17894
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18135,7 +18184,10 @@ var NativeCropResultSchema = object({
18135
18184
  * Which source served this crop, so a quality-sensitive consumer (the native
18136
18185
  * `keyFrame`) can reject a degraded fallback:
18137
18186
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18138
- * quality path).
18187
+ * quality path). A subject-tile serve is also native-resolution and stays
18188
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18189
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18190
+ * internal crop result (`nativeHits` vs `tileHits`).
18139
18191
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18140
18192
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18141
18193
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18626,12 +18678,41 @@ var RunnerLocalLoadSchema = object({
18626
18678
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18627
18679
  * working unchanged when they switch to reading from the runner cap.
18628
18680
  */
18681
+ var FrameLazyCountersSchema = object({
18682
+ framesDecoded: number(),
18683
+ framesAdmitted: number(),
18684
+ framesDroppedPixelFree: number(),
18685
+ viewsMaterialized: number(),
18686
+ viewsSkipped: number(),
18687
+ workerToRunnerBytes: number(),
18688
+ runnerToPoolRawBytes: number(),
18689
+ runnerToPoolJpegBytes: number(),
18690
+ onDemandFullFrameRequests: number(),
18691
+ onDemandCropRequests: number(),
18692
+ nativeHits: number(),
18693
+ nativeMisses: number(),
18694
+ tileHits: number(),
18695
+ tileMisses: number(),
18696
+ fallbackHits: number(),
18697
+ fallbackMisses: number(),
18698
+ retainedWritesAvoided: number(),
18699
+ residentRefs: number(),
18700
+ residentBytes: number(),
18701
+ releases: number(),
18702
+ evictions: number(),
18703
+ staleMisses: number()
18704
+ });
18705
+ var FrameLazyMetricsSchema = object({
18706
+ node: FrameLazyCountersSchema,
18707
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18708
+ });
18629
18709
  var RunnerLocalMetricsSchema = object({
18630
18710
  nodeId: string(),
18631
18711
  activeCameras: number(),
18632
18712
  throttledCameras: number(),
18633
18713
  avgInferenceTimeMs: number(),
18634
- queueDepth: number()
18714
+ queueDepth: number(),
18715
+ frameLazy: FrameLazyMetricsSchema.optional()
18635
18716
  });
18636
18717
  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({
18637
18718
  handle: FrameHandleSchema,
@@ -19931,6 +20012,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19931
20012
  location: StorageLocationSchema,
19932
20013
  relativePath: string()
19933
20014
  }), _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" });
20015
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20016
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20017
+ var ProfileSettingsBagSchema = record(string(), unknown());
19934
20018
  /**
19935
20019
  * A live terminal session hosted by the provider addon. Output and input do
19936
20020
  * NOT flow through the capability — they use the addon data plane
@@ -19960,7 +20044,14 @@ var TerminalSessionInfoSchema = object({
19960
20044
  var TerminalProfileInfoSchema = object({
19961
20045
  profileId: string(),
19962
20046
  label: string(),
19963
- description: string().optional()
20047
+ description: string().optional(),
20048
+ /** Spawn defaults the instance form copies on create. */
20049
+ executable: string().optional(),
20050
+ args: array(string()).readonly().optional(),
20051
+ cwd: string().optional(),
20052
+ environment: array(string()).readonly().optional(),
20053
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20054
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19964
20055
  });
19965
20056
  /**
19966
20057
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19973,7 +20064,12 @@ var TerminalInstanceInfoSchema = object({
19973
20064
  profileId: string(),
19974
20065
  profileLabel: string(),
19975
20066
  name: string(),
19976
- enabled: boolean()
20067
+ enabled: boolean(),
20068
+ executable: string(),
20069
+ args: array(string()).readonly(),
20070
+ cwd: string(),
20071
+ environment: array(string()).readonly(),
20072
+ profileSettings: ProfileSettingsBagSchema
19977
20073
  });
19978
20074
  var TerminalLegacyCameraSchema = object({
19979
20075
  stableId: string(),
@@ -20003,7 +20099,23 @@ var TerminalOutputBatchSchema = object({
20003
20099
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20004
20100
  targetNodeId: string().min(1),
20005
20101
  profileId: string().min(1),
20006
- name: string().trim().min(1).max(160).optional()
20102
+ name: string().trim().min(1).max(160).optional(),
20103
+ executable: string().max(1024).optional(),
20104
+ args: array(string().max(2048)).max(64).optional(),
20105
+ cwd: string().max(1024).optional(),
20106
+ environment: array(string().max(4096)).max(64).optional(),
20107
+ profileSettings: ProfileSettingsBagSchema.optional()
20108
+ }), TerminalInstanceInfoSchema, {
20109
+ kind: "mutation",
20110
+ auth: "admin"
20111
+ }), method(object({
20112
+ instanceId: string().min(1),
20113
+ name: string().trim().min(1).max(160).optional(),
20114
+ executable: string().max(1024).optional(),
20115
+ args: array(string().max(2048)).max(64).optional(),
20116
+ cwd: string().max(1024).optional(),
20117
+ environment: array(string().max(4096)).max(64).optional(),
20118
+ profileSettings: ProfileSettingsBagSchema.optional()
20007
20119
  }), TerminalInstanceInfoSchema, {
20008
20120
  kind: "mutation",
20009
20121
  auth: "admin"
@@ -20025,7 +20137,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20025
20137
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20026
20138
  profileId: string(),
20027
20139
  cols: number().int().positive(),
20028
- rows: number().int().positive()
20140
+ rows: number().int().positive(),
20141
+ executable: string().max(1024).optional(),
20142
+ args: array(string().max(2048)).max(64).optional(),
20143
+ cwd: string().max(1024).optional(),
20144
+ environment: array(string().max(4096)).max(64).optional()
20029
20145
  }), TerminalSessionInfoSchema, {
20030
20146
  kind: "mutation",
20031
20147
  auth: "admin"
@@ -23900,10 +24016,10 @@ var lawnMowerControlCapability = {
23900
24016
  *
23901
24017
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23902
24018
  * to receive an ordered list of candidate base URLs it should race
23903
- * on connect — LAN IPv4 first (lowest latency when on same network),
23904
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23905
- * race them with short timeouts and stick with the winner for the
23906
- * session.
24019
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24020
+ * when on the same network), then public hostname (if a tunnel is
24021
+ * up). The SDK can race them with short timeouts and stick with the
24022
+ * winner for the session.
23907
24023
  *
23908
24024
  * Why hub-only: agents are not directly addressable by the operator's
23909
24025
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24058,6 +24174,17 @@ var NotificationEndpointSchema = object({
24058
24174
  /** What the ranking currently resolves to (null when nothing is reachable). */
24059
24175
  resolved: string().nullable()
24060
24176
  });
24177
+ /**
24178
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24179
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24180
+ * currently expands to, so the UI can show the effective set either way.
24181
+ */
24182
+ var ViewerEndpointsSchema = object({
24183
+ /** The operator's explicit race set, or empty for AUTO. */
24184
+ baseUrls: array(string()).readonly(),
24185
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24186
+ resolved: array(string()).readonly()
24187
+ });
24061
24188
  var AllowedAddressesSchema = object({
24062
24189
  /**
24063
24190
  * Allowlist of interface addresses operators have explicitly opted
@@ -24066,6 +24193,20 @@ var AllowedAddressesSchema = object({
24066
24193
  * Network Addresses admin page and persisted by the addon.
24067
24194
  */
24068
24195
  addresses: array(string()).readonly() });
24196
+ var TlsStatusSchema = object({
24197
+ mode: _enum([
24198
+ "generated",
24199
+ "uploaded",
24200
+ "disabled"
24201
+ ]),
24202
+ leafFingerprintSha256: string().nullable(),
24203
+ caFingerprintSha256: string().nullable(),
24204
+ validTo: string().nullable(),
24205
+ sans: array(string()),
24206
+ caCertPem: string().nullable(),
24207
+ reissueError: string().nullable(),
24208
+ restartRequired: boolean()
24209
+ });
24069
24210
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24070
24211
  /**
24071
24212
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24075,17 +24216,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24075
24216
  */
24076
24217
  port: number().int().min(1).max(65535).optional(),
24077
24218
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24078
- * candidate. Default `true`. */
24219
+ * candidate. Default `false` — loopback is not a client route. */
24079
24220
  includeLoopback: boolean().optional(),
24080
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24081
- * Default `false`. */
24221
+ /** Skip IPv6 entries. Default `false` — the palette includes stable
24222
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24223
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24082
24224
  ipv4Only: boolean().optional(),
24083
24225
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24084
24226
  * Pass `'https'` when the caller is itself loaded over HTTPS
24085
24227
  * to avoid mixed-content blocks in the browser. The public
24086
24228
  * tunnel always emits `https://` regardless. */
24087
24229
  scheme: _enum(["http", "https"]).optional()
24088
- }), 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" });
24230
+ }), 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, {
24231
+ kind: "mutation",
24232
+ auth: "admin"
24233
+ }), method(object({
24234
+ certPem: string().min(1),
24235
+ keyPem: string().min(1),
24236
+ caPem: string().optional()
24237
+ }), TlsStatusSchema, {
24238
+ kind: "mutation",
24239
+ auth: "admin"
24240
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24241
+ kind: "mutation",
24242
+ auth: "admin"
24243
+ });
24089
24244
  var LockControlStatusSchema = object({
24090
24245
  /** Lifecycle state of the lock. `jammed` means the motor reported
24091
24246
  * failure to reach the target — operator intervention required. */
@@ -32112,6 +32267,12 @@ Object.freeze({
32112
32267
  addonId: null,
32113
32268
  access: "create"
32114
32269
  },
32270
+ "localNetwork.downloadCa": {
32271
+ capName: "local-network",
32272
+ capScope: "system",
32273
+ addonId: null,
32274
+ access: "view"
32275
+ },
32115
32276
  "localNetwork.getAllowedAddresses": {
32116
32277
  capName: "local-network",
32117
32278
  capScope: "system",
@@ -32136,18 +32297,42 @@ Object.freeze({
32136
32297
  addonId: null,
32137
32298
  access: "view"
32138
32299
  },
32300
+ "localNetwork.getTlsStatus": {
32301
+ capName: "local-network",
32302
+ capScope: "system",
32303
+ addonId: null,
32304
+ access: "view"
32305
+ },
32306
+ "localNetwork.getViewerEndpoints": {
32307
+ capName: "local-network",
32308
+ capScope: "system",
32309
+ addonId: null,
32310
+ access: "view"
32311
+ },
32139
32312
  "localNetwork.list": {
32140
32313
  capName: "local-network",
32141
32314
  capScope: "system",
32142
32315
  addonId: null,
32143
32316
  access: "view"
32144
32317
  },
32318
+ "localNetwork.regenerateCertificate": {
32319
+ capName: "local-network",
32320
+ capScope: "system",
32321
+ addonId: null,
32322
+ access: "create"
32323
+ },
32145
32324
  "localNetwork.resetAllowlistToBestMatch": {
32146
32325
  capName: "local-network",
32147
32326
  capScope: "system",
32148
32327
  addonId: null,
32149
32328
  access: "delete"
32150
32329
  },
32330
+ "localNetwork.revertToGeneratedCertificate": {
32331
+ capName: "local-network",
32332
+ capScope: "system",
32333
+ addonId: null,
32334
+ access: "create"
32335
+ },
32151
32336
  "localNetwork.setAllowedAddresses": {
32152
32337
  capName: "local-network",
32153
32338
  capScope: "system",
@@ -32160,6 +32345,18 @@ Object.freeze({
32160
32345
  addonId: null,
32161
32346
  access: "create"
32162
32347
  },
32348
+ "localNetwork.setViewerEndpoints": {
32349
+ capName: "local-network",
32350
+ capScope: "system",
32351
+ addonId: null,
32352
+ access: "create"
32353
+ },
32354
+ "localNetwork.uploadCertificate": {
32355
+ capName: "local-network",
32356
+ capScope: "system",
32357
+ addonId: null,
32358
+ access: "create"
32359
+ },
32163
32360
  "lockControl.lock": {
32164
32361
  capName: "lock-control",
32165
32362
  capScope: "device",
@@ -35040,6 +35237,12 @@ Object.freeze({
35040
35237
  addonId: null,
35041
35238
  access: "create"
35042
35239
  },
35240
+ "terminalSession.updateInstance": {
35241
+ capName: "terminal-session",
35242
+ capScope: "system",
35243
+ addonId: null,
35244
+ access: "create"
35245
+ },
35043
35246
  "terminalSession.writeInput": {
35044
35247
  capName: "terminal-session",
35045
35248
  capScope: "system",
@@ -37527,6 +37730,35 @@ Object.freeze(Object.fromEntries([{
37527
37730
  }]
37528
37731
  }].map((s) => [s.stepId, s.defaultModelId])));
37529
37732
  string().min(1);
37733
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37734
+ stepId: "face-embedding",
37735
+ key: "minLandmarkFaceSize",
37736
+ label: "Min face size for recognition (detection px)",
37737
+ 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.",
37738
+ type: "slider",
37739
+ min: 0,
37740
+ max: 64,
37741
+ step: 2,
37742
+ default: 24
37743
+ }];
37744
+ function clusterStepSettingKey(stepId, fieldKey) {
37745
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37746
+ }
37747
+ var ClusterSettingNumberSchema = number().finite();
37748
+ function readClusterStepSettings(config) {
37749
+ const out = {};
37750
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37751
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37752
+ const value = parsed.success ? parsed.data : field.default;
37753
+ const existing = out[field.stepId] ?? {};
37754
+ out[field.stepId] = {
37755
+ ...existing,
37756
+ [field.key]: value
37757
+ };
37758
+ }
37759
+ return out;
37760
+ }
37761
+ readClusterStepSettings({});
37530
37762
  object({
37531
37763
  /**
37532
37764
  * Fraction of the box's own size added on EACH side before cutting.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.27",
3
+ "version": "1.2.28",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",