@camstack/addon-provider-hikvision 1.2.33 → 1.2.34

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
@@ -8190,6 +8190,15 @@ var LabelDefinitionSchema = object({
8190
8190
  description: string().optional(),
8191
8191
  icon: string().optional()
8192
8192
  });
8193
+ var ClassMapDefinitionSchema = object({
8194
+ mapping: record(string(), _enum([
8195
+ "person",
8196
+ "vehicle",
8197
+ "animal",
8198
+ "package"
8199
+ ])),
8200
+ preserveOriginal: boolean()
8201
+ });
8193
8202
  var MODEL_FORMATS = [
8194
8203
  "onnx",
8195
8204
  "coreml",
@@ -8368,7 +8377,13 @@ var ModelCatalogEntrySchema = object({
8368
8377
  * `id` stays the source of truth for resolution/download/persistence; grouping
8369
8378
  * is a presentation overlay resolved back to an `id`.
8370
8379
  */
8371
- group: ModelVariantGroupSchema.optional()
8380
+ group: ModelVariantGroupSchema.optional(),
8381
+ /**
8382
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8383
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8384
+ * labels already ARE the CamStack macros (Scrypted identity map).
8385
+ */
8386
+ classMap: ClassMapDefinitionSchema.optional()
8372
8387
  });
8373
8388
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8374
8389
  format: literal("openvino"),
@@ -8397,7 +8412,8 @@ var ModelConvertMetadataSchema = object({
8397
8412
  "ocr",
8398
8413
  "segmentation"
8399
8414
  ]),
8400
- faceAlignment: boolean().optional()
8415
+ faceAlignment: boolean().optional(),
8416
+ classMap: ClassMapDefinitionSchema.optional()
8401
8417
  });
8402
8418
  var ConvertResultSchema = object({
8403
8419
  entry: ModelCatalogEntrySchema,
@@ -17702,6 +17718,33 @@ var NativeCropRefSchema = object({
17702
17718
  h: number()
17703
17719
  })
17704
17720
  });
17721
+ object({
17722
+ crop: object({
17723
+ left: number(),
17724
+ top: number(),
17725
+ width: number().positive(),
17726
+ height: number().positive()
17727
+ }).optional(),
17728
+ content: object({
17729
+ width: number().int().positive(),
17730
+ height: number().int().positive()
17731
+ }),
17732
+ fit: _enum(["stretch", "contain"]),
17733
+ format: _enum([
17734
+ "rgb",
17735
+ "gray",
17736
+ "jpeg"
17737
+ ])
17738
+ });
17739
+ var FrameRefSchema = object({
17740
+ registryId: string().min(1),
17741
+ id: string().min(1),
17742
+ width: number().int().positive(),
17743
+ height: number().int().positive(),
17744
+ format: _enum(["rgb", "gray"]),
17745
+ timestamp: number(),
17746
+ capturedAt: number().optional()
17747
+ });
17705
17748
  var ModelFormatSchema$1 = _enum([
17706
17749
  "onnx",
17707
17750
  "coreml",
@@ -17946,6 +17989,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17946
17989
  steps: array(PipelineStepInputSchema).min(1),
17947
17990
  frame: FrameInputSchema.optional(),
17948
17991
  /**
17992
+ * Process-local lazy frame. Valid only when caller and provider resolve
17993
+ * in the same execution-group process; split/cross-node callers use
17994
+ * `frame`/`image` inline compatibility instead.
17995
+ */
17996
+ frameRef: FrameRefSchema.optional(),
17997
+ /**
17949
17998
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17950
17999
  * the decoded pixels live in. One more member of the one-of
17951
18000
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18241,7 +18290,10 @@ var NativeCropResultSchema = object({
18241
18290
  * Which source served this crop, so a quality-sensitive consumer (the native
18242
18291
  * `keyFrame`) can reject a degraded fallback:
18243
18292
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18244
- * quality path).
18293
+ * quality path). A subject-tile serve is also native-resolution and stays
18294
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18295
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18296
+ * internal crop result (`nativeHits` vs `tileHits`).
18245
18297
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18246
18298
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18247
18299
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18732,12 +18784,41 @@ var RunnerLocalLoadSchema = object({
18732
18784
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18733
18785
  * working unchanged when they switch to reading from the runner cap.
18734
18786
  */
18787
+ var FrameLazyCountersSchema = object({
18788
+ framesDecoded: number(),
18789
+ framesAdmitted: number(),
18790
+ framesDroppedPixelFree: number(),
18791
+ viewsMaterialized: number(),
18792
+ viewsSkipped: number(),
18793
+ workerToRunnerBytes: number(),
18794
+ runnerToPoolRawBytes: number(),
18795
+ runnerToPoolJpegBytes: number(),
18796
+ onDemandFullFrameRequests: number(),
18797
+ onDemandCropRequests: number(),
18798
+ nativeHits: number(),
18799
+ nativeMisses: number(),
18800
+ tileHits: number(),
18801
+ tileMisses: number(),
18802
+ fallbackHits: number(),
18803
+ fallbackMisses: number(),
18804
+ retainedWritesAvoided: number(),
18805
+ residentRefs: number(),
18806
+ residentBytes: number(),
18807
+ releases: number(),
18808
+ evictions: number(),
18809
+ staleMisses: number()
18810
+ });
18811
+ var FrameLazyMetricsSchema = object({
18812
+ node: FrameLazyCountersSchema,
18813
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18814
+ });
18735
18815
  var RunnerLocalMetricsSchema = object({
18736
18816
  nodeId: string(),
18737
18817
  activeCameras: number(),
18738
18818
  throttledCameras: number(),
18739
18819
  avgInferenceTimeMs: number(),
18740
- queueDepth: number()
18820
+ queueDepth: number(),
18821
+ frameLazy: FrameLazyMetricsSchema.optional()
18741
18822
  });
18742
18823
  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({
18743
18824
  handle: FrameHandleSchema,
@@ -20141,6 +20222,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20141
20222
  location: StorageLocationSchema,
20142
20223
  relativePath: string()
20143
20224
  }), _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" });
20225
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20226
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20227
+ var ProfileSettingsBagSchema = record(string(), unknown());
20144
20228
  /**
20145
20229
  * A live terminal session hosted by the provider addon. Output and input do
20146
20230
  * NOT flow through the capability — they use the addon data plane
@@ -20170,7 +20254,14 @@ var TerminalSessionInfoSchema = object({
20170
20254
  var TerminalProfileInfoSchema = object({
20171
20255
  profileId: string(),
20172
20256
  label: string(),
20173
- description: string().optional()
20257
+ description: string().optional(),
20258
+ /** Spawn defaults the instance form copies on create. */
20259
+ executable: string().optional(),
20260
+ args: array(string()).readonly().optional(),
20261
+ cwd: string().optional(),
20262
+ environment: array(string()).readonly().optional(),
20263
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20264
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20174
20265
  });
20175
20266
  /**
20176
20267
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20183,7 +20274,12 @@ var TerminalInstanceInfoSchema = object({
20183
20274
  profileId: string(),
20184
20275
  profileLabel: string(),
20185
20276
  name: string(),
20186
- enabled: boolean()
20277
+ enabled: boolean(),
20278
+ executable: string(),
20279
+ args: array(string()).readonly(),
20280
+ cwd: string(),
20281
+ environment: array(string()).readonly(),
20282
+ profileSettings: ProfileSettingsBagSchema
20187
20283
  });
20188
20284
  var TerminalLegacyCameraSchema = object({
20189
20285
  stableId: string(),
@@ -20213,7 +20309,23 @@ var TerminalOutputBatchSchema = object({
20213
20309
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20214
20310
  targetNodeId: string().min(1),
20215
20311
  profileId: string().min(1),
20216
- name: string().trim().min(1).max(160).optional()
20312
+ name: string().trim().min(1).max(160).optional(),
20313
+ executable: string().max(1024).optional(),
20314
+ args: array(string().max(2048)).max(64).optional(),
20315
+ cwd: string().max(1024).optional(),
20316
+ environment: array(string().max(4096)).max(64).optional(),
20317
+ profileSettings: ProfileSettingsBagSchema.optional()
20318
+ }), TerminalInstanceInfoSchema, {
20319
+ kind: "mutation",
20320
+ auth: "admin"
20321
+ }), method(object({
20322
+ instanceId: string().min(1),
20323
+ name: string().trim().min(1).max(160).optional(),
20324
+ executable: string().max(1024).optional(),
20325
+ args: array(string().max(2048)).max(64).optional(),
20326
+ cwd: string().max(1024).optional(),
20327
+ environment: array(string().max(4096)).max(64).optional(),
20328
+ profileSettings: ProfileSettingsBagSchema.optional()
20217
20329
  }), TerminalInstanceInfoSchema, {
20218
20330
  kind: "mutation",
20219
20331
  auth: "admin"
@@ -20235,7 +20347,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20235
20347
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20236
20348
  profileId: string(),
20237
20349
  cols: number().int().positive(),
20238
- rows: number().int().positive()
20350
+ rows: number().int().positive(),
20351
+ executable: string().max(1024).optional(),
20352
+ args: array(string().max(2048)).max(64).optional(),
20353
+ cwd: string().max(1024).optional(),
20354
+ environment: array(string().max(4096)).max(64).optional()
20239
20355
  }), TerminalSessionInfoSchema, {
20240
20356
  kind: "mutation",
20241
20357
  auth: "admin"
@@ -24110,10 +24226,10 @@ var lawnMowerControlCapability = {
24110
24226
  *
24111
24227
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24112
24228
  * to receive an ordered list of candidate base URLs it should race
24113
- * on connect — LAN IPv4 first (lowest latency when on same network),
24114
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24115
- * race them with short timeouts and stick with the winner for the
24116
- * session.
24229
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24230
+ * when on the same network), then public hostname (if a tunnel is
24231
+ * up). The SDK can race them with short timeouts and stick with the
24232
+ * winner for the session.
24117
24233
  *
24118
24234
  * Why hub-only: agents are not directly addressable by the operator's
24119
24235
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24268,6 +24384,17 @@ var NotificationEndpointSchema = object({
24268
24384
  /** What the ranking currently resolves to (null when nothing is reachable). */
24269
24385
  resolved: string().nullable()
24270
24386
  });
24387
+ /**
24388
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24389
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24390
+ * currently expands to, so the UI can show the effective set either way.
24391
+ */
24392
+ var ViewerEndpointsSchema = object({
24393
+ /** The operator's explicit race set, or empty for AUTO. */
24394
+ baseUrls: array(string()).readonly(),
24395
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24396
+ resolved: array(string()).readonly()
24397
+ });
24271
24398
  var AllowedAddressesSchema = object({
24272
24399
  /**
24273
24400
  * Allowlist of interface addresses operators have explicitly opted
@@ -24276,6 +24403,20 @@ var AllowedAddressesSchema = object({
24276
24403
  * Network Addresses admin page and persisted by the addon.
24277
24404
  */
24278
24405
  addresses: array(string()).readonly() });
24406
+ var TlsStatusSchema = object({
24407
+ mode: _enum([
24408
+ "generated",
24409
+ "uploaded",
24410
+ "disabled"
24411
+ ]),
24412
+ leafFingerprintSha256: string().nullable(),
24413
+ caFingerprintSha256: string().nullable(),
24414
+ validTo: string().nullable(),
24415
+ sans: array(string()),
24416
+ caCertPem: string().nullable(),
24417
+ reissueError: string().nullable(),
24418
+ restartRequired: boolean()
24419
+ });
24279
24420
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24280
24421
  /**
24281
24422
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24285,17 +24426,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24285
24426
  */
24286
24427
  port: number().int().min(1).max(65535).optional(),
24287
24428
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24288
- * candidate. Default `true`. */
24429
+ * candidate. Default `false` — loopback is not a client route. */
24289
24430
  includeLoopback: boolean().optional(),
24290
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24291
- * Default `false`. */
24431
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24432
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24433
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24292
24434
  ipv4Only: boolean().optional(),
24293
24435
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24294
24436
  * Pass `'https'` when the caller is itself loaded over HTTPS
24295
24437
  * to avoid mixed-content blocks in the browser. The public
24296
24438
  * tunnel always emits `https://` regardless. */
24297
24439
  scheme: _enum(["http", "https"]).optional()
24298
- }), 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" });
24440
+ }), 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, {
24441
+ kind: "mutation",
24442
+ auth: "admin"
24443
+ }), method(object({
24444
+ certPem: string().min(1),
24445
+ keyPem: string().min(1),
24446
+ caPem: string().optional()
24447
+ }), TlsStatusSchema, {
24448
+ kind: "mutation",
24449
+ auth: "admin"
24450
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24451
+ kind: "mutation",
24452
+ auth: "admin"
24453
+ });
24299
24454
  var LockControlStatusSchema = object({
24300
24455
  /** Lifecycle state of the lock. `jammed` means the motor reported
24301
24456
  * failure to reach the target — operator intervention required. */
@@ -32886,6 +33041,12 @@ Object.freeze({
32886
33041
  addonId: null,
32887
33042
  access: "create"
32888
33043
  },
33044
+ "localNetwork.downloadCa": {
33045
+ capName: "local-network",
33046
+ capScope: "system",
33047
+ addonId: null,
33048
+ access: "view"
33049
+ },
32889
33050
  "localNetwork.getAllowedAddresses": {
32890
33051
  capName: "local-network",
32891
33052
  capScope: "system",
@@ -32910,18 +33071,42 @@ Object.freeze({
32910
33071
  addonId: null,
32911
33072
  access: "view"
32912
33073
  },
33074
+ "localNetwork.getTlsStatus": {
33075
+ capName: "local-network",
33076
+ capScope: "system",
33077
+ addonId: null,
33078
+ access: "view"
33079
+ },
33080
+ "localNetwork.getViewerEndpoints": {
33081
+ capName: "local-network",
33082
+ capScope: "system",
33083
+ addonId: null,
33084
+ access: "view"
33085
+ },
32913
33086
  "localNetwork.list": {
32914
33087
  capName: "local-network",
32915
33088
  capScope: "system",
32916
33089
  addonId: null,
32917
33090
  access: "view"
32918
33091
  },
33092
+ "localNetwork.regenerateCertificate": {
33093
+ capName: "local-network",
33094
+ capScope: "system",
33095
+ addonId: null,
33096
+ access: "create"
33097
+ },
32919
33098
  "localNetwork.resetAllowlistToBestMatch": {
32920
33099
  capName: "local-network",
32921
33100
  capScope: "system",
32922
33101
  addonId: null,
32923
33102
  access: "delete"
32924
33103
  },
33104
+ "localNetwork.revertToGeneratedCertificate": {
33105
+ capName: "local-network",
33106
+ capScope: "system",
33107
+ addonId: null,
33108
+ access: "create"
33109
+ },
32925
33110
  "localNetwork.setAllowedAddresses": {
32926
33111
  capName: "local-network",
32927
33112
  capScope: "system",
@@ -32934,6 +33119,18 @@ Object.freeze({
32934
33119
  addonId: null,
32935
33120
  access: "create"
32936
33121
  },
33122
+ "localNetwork.setViewerEndpoints": {
33123
+ capName: "local-network",
33124
+ capScope: "system",
33125
+ addonId: null,
33126
+ access: "create"
33127
+ },
33128
+ "localNetwork.uploadCertificate": {
33129
+ capName: "local-network",
33130
+ capScope: "system",
33131
+ addonId: null,
33132
+ access: "create"
33133
+ },
32937
33134
  "lockControl.lock": {
32938
33135
  capName: "lock-control",
32939
33136
  capScope: "device",
@@ -35814,6 +36011,12 @@ Object.freeze({
35814
36011
  addonId: null,
35815
36012
  access: "create"
35816
36013
  },
36014
+ "terminalSession.updateInstance": {
36015
+ capName: "terminal-session",
36016
+ capScope: "system",
36017
+ addonId: null,
36018
+ access: "create"
36019
+ },
35817
36020
  "terminalSession.writeInput": {
35818
36021
  capName: "terminal-session",
35819
36022
  capScope: "system",
@@ -38301,6 +38504,35 @@ Object.freeze(Object.fromEntries([{
38301
38504
  }]
38302
38505
  }].map((s) => [s.stepId, s.defaultModelId])));
38303
38506
  string().min(1);
38507
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38508
+ stepId: "face-embedding",
38509
+ key: "minLandmarkFaceSize",
38510
+ label: "Min face size for recognition (detection px)",
38511
+ 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.",
38512
+ type: "slider",
38513
+ min: 0,
38514
+ max: 64,
38515
+ step: 2,
38516
+ default: 24
38517
+ }];
38518
+ function clusterStepSettingKey(stepId, fieldKey) {
38519
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38520
+ }
38521
+ var ClusterSettingNumberSchema = number().finite();
38522
+ function readClusterStepSettings(config) {
38523
+ const out = {};
38524
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38525
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38526
+ const value = parsed.success ? parsed.data : field.default;
38527
+ const existing = out[field.stepId] ?? {};
38528
+ out[field.stepId] = {
38529
+ ...existing,
38530
+ [field.key]: value
38531
+ };
38532
+ }
38533
+ return out;
38534
+ }
38535
+ readClusterStepSettings({});
38304
38536
  object({
38305
38537
  /**
38306
38538
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -8191,6 +8191,15 @@ var LabelDefinitionSchema = object({
8191
8191
  description: string().optional(),
8192
8192
  icon: string().optional()
8193
8193
  });
8194
+ var ClassMapDefinitionSchema = object({
8195
+ mapping: record(string(), _enum([
8196
+ "person",
8197
+ "vehicle",
8198
+ "animal",
8199
+ "package"
8200
+ ])),
8201
+ preserveOriginal: boolean()
8202
+ });
8194
8203
  var MODEL_FORMATS = [
8195
8204
  "onnx",
8196
8205
  "coreml",
@@ -8369,7 +8378,13 @@ var ModelCatalogEntrySchema = object({
8369
8378
  * `id` stays the source of truth for resolution/download/persistence; grouping
8370
8379
  * is a presentation overlay resolved back to an `id`.
8371
8380
  */
8372
- group: ModelVariantGroupSchema.optional()
8381
+ group: ModelVariantGroupSchema.optional(),
8382
+ /**
8383
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8384
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8385
+ * labels already ARE the CamStack macros (Scrypted identity map).
8386
+ */
8387
+ classMap: ClassMapDefinitionSchema.optional()
8373
8388
  });
8374
8389
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8375
8390
  format: literal("openvino"),
@@ -8398,7 +8413,8 @@ var ModelConvertMetadataSchema = object({
8398
8413
  "ocr",
8399
8414
  "segmentation"
8400
8415
  ]),
8401
- faceAlignment: boolean().optional()
8416
+ faceAlignment: boolean().optional(),
8417
+ classMap: ClassMapDefinitionSchema.optional()
8402
8418
  });
8403
8419
  var ConvertResultSchema = object({
8404
8420
  entry: ModelCatalogEntrySchema,
@@ -17703,6 +17719,33 @@ var NativeCropRefSchema = object({
17703
17719
  h: number()
17704
17720
  })
17705
17721
  });
17722
+ object({
17723
+ crop: object({
17724
+ left: number(),
17725
+ top: number(),
17726
+ width: number().positive(),
17727
+ height: number().positive()
17728
+ }).optional(),
17729
+ content: object({
17730
+ width: number().int().positive(),
17731
+ height: number().int().positive()
17732
+ }),
17733
+ fit: _enum(["stretch", "contain"]),
17734
+ format: _enum([
17735
+ "rgb",
17736
+ "gray",
17737
+ "jpeg"
17738
+ ])
17739
+ });
17740
+ var FrameRefSchema = object({
17741
+ registryId: string().min(1),
17742
+ id: string().min(1),
17743
+ width: number().int().positive(),
17744
+ height: number().int().positive(),
17745
+ format: _enum(["rgb", "gray"]),
17746
+ timestamp: number(),
17747
+ capturedAt: number().optional()
17748
+ });
17706
17749
  var ModelFormatSchema$1 = _enum([
17707
17750
  "onnx",
17708
17751
  "coreml",
@@ -17947,6 +17990,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17947
17990
  steps: array(PipelineStepInputSchema).min(1),
17948
17991
  frame: FrameInputSchema.optional(),
17949
17992
  /**
17993
+ * Process-local lazy frame. Valid only when caller and provider resolve
17994
+ * in the same execution-group process; split/cross-node callers use
17995
+ * `frame`/`image` inline compatibility instead.
17996
+ */
17997
+ frameRef: FrameRefSchema.optional(),
17998
+ /**
17950
17999
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17951
18000
  * the decoded pixels live in. One more member of the one-of
17952
18001
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18242,7 +18291,10 @@ var NativeCropResultSchema = object({
18242
18291
  * Which source served this crop, so a quality-sensitive consumer (the native
18243
18292
  * `keyFrame`) can reject a degraded fallback:
18244
18293
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18245
- * quality path).
18294
+ * quality path). A subject-tile serve is also native-resolution and stays
18295
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18296
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18297
+ * internal crop result (`nativeHits` vs `tileHits`).
18246
18298
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18247
18299
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18248
18300
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18733,12 +18785,41 @@ var RunnerLocalLoadSchema = object({
18733
18785
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18734
18786
  * working unchanged when they switch to reading from the runner cap.
18735
18787
  */
18788
+ var FrameLazyCountersSchema = object({
18789
+ framesDecoded: number(),
18790
+ framesAdmitted: number(),
18791
+ framesDroppedPixelFree: number(),
18792
+ viewsMaterialized: number(),
18793
+ viewsSkipped: number(),
18794
+ workerToRunnerBytes: number(),
18795
+ runnerToPoolRawBytes: number(),
18796
+ runnerToPoolJpegBytes: number(),
18797
+ onDemandFullFrameRequests: number(),
18798
+ onDemandCropRequests: number(),
18799
+ nativeHits: number(),
18800
+ nativeMisses: number(),
18801
+ tileHits: number(),
18802
+ tileMisses: number(),
18803
+ fallbackHits: number(),
18804
+ fallbackMisses: number(),
18805
+ retainedWritesAvoided: number(),
18806
+ residentRefs: number(),
18807
+ residentBytes: number(),
18808
+ releases: number(),
18809
+ evictions: number(),
18810
+ staleMisses: number()
18811
+ });
18812
+ var FrameLazyMetricsSchema = object({
18813
+ node: FrameLazyCountersSchema,
18814
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18815
+ });
18736
18816
  var RunnerLocalMetricsSchema = object({
18737
18817
  nodeId: string(),
18738
18818
  activeCameras: number(),
18739
18819
  throttledCameras: number(),
18740
18820
  avgInferenceTimeMs: number(),
18741
- queueDepth: number()
18821
+ queueDepth: number(),
18822
+ frameLazy: FrameLazyMetricsSchema.optional()
18742
18823
  });
18743
18824
  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({
18744
18825
  handle: FrameHandleSchema,
@@ -20142,6 +20223,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20142
20223
  location: StorageLocationSchema,
20143
20224
  relativePath: string()
20144
20225
  }), _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" });
20226
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20227
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20228
+ var ProfileSettingsBagSchema = record(string(), unknown());
20145
20229
  /**
20146
20230
  * A live terminal session hosted by the provider addon. Output and input do
20147
20231
  * NOT flow through the capability — they use the addon data plane
@@ -20171,7 +20255,14 @@ var TerminalSessionInfoSchema = object({
20171
20255
  var TerminalProfileInfoSchema = object({
20172
20256
  profileId: string(),
20173
20257
  label: string(),
20174
- description: string().optional()
20258
+ description: string().optional(),
20259
+ /** Spawn defaults the instance form copies on create. */
20260
+ executable: string().optional(),
20261
+ args: array(string()).readonly().optional(),
20262
+ cwd: string().optional(),
20263
+ environment: array(string()).readonly().optional(),
20264
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20265
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20175
20266
  });
20176
20267
  /**
20177
20268
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20184,7 +20275,12 @@ var TerminalInstanceInfoSchema = object({
20184
20275
  profileId: string(),
20185
20276
  profileLabel: string(),
20186
20277
  name: string(),
20187
- enabled: boolean()
20278
+ enabled: boolean(),
20279
+ executable: string(),
20280
+ args: array(string()).readonly(),
20281
+ cwd: string(),
20282
+ environment: array(string()).readonly(),
20283
+ profileSettings: ProfileSettingsBagSchema
20188
20284
  });
20189
20285
  var TerminalLegacyCameraSchema = object({
20190
20286
  stableId: string(),
@@ -20214,7 +20310,23 @@ var TerminalOutputBatchSchema = object({
20214
20310
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20215
20311
  targetNodeId: string().min(1),
20216
20312
  profileId: string().min(1),
20217
- name: string().trim().min(1).max(160).optional()
20313
+ name: string().trim().min(1).max(160).optional(),
20314
+ executable: string().max(1024).optional(),
20315
+ args: array(string().max(2048)).max(64).optional(),
20316
+ cwd: string().max(1024).optional(),
20317
+ environment: array(string().max(4096)).max(64).optional(),
20318
+ profileSettings: ProfileSettingsBagSchema.optional()
20319
+ }), TerminalInstanceInfoSchema, {
20320
+ kind: "mutation",
20321
+ auth: "admin"
20322
+ }), method(object({
20323
+ instanceId: string().min(1),
20324
+ name: string().trim().min(1).max(160).optional(),
20325
+ executable: string().max(1024).optional(),
20326
+ args: array(string().max(2048)).max(64).optional(),
20327
+ cwd: string().max(1024).optional(),
20328
+ environment: array(string().max(4096)).max(64).optional(),
20329
+ profileSettings: ProfileSettingsBagSchema.optional()
20218
20330
  }), TerminalInstanceInfoSchema, {
20219
20331
  kind: "mutation",
20220
20332
  auth: "admin"
@@ -20236,7 +20348,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20236
20348
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20237
20349
  profileId: string(),
20238
20350
  cols: number().int().positive(),
20239
- rows: number().int().positive()
20351
+ rows: number().int().positive(),
20352
+ executable: string().max(1024).optional(),
20353
+ args: array(string().max(2048)).max(64).optional(),
20354
+ cwd: string().max(1024).optional(),
20355
+ environment: array(string().max(4096)).max(64).optional()
20240
20356
  }), TerminalSessionInfoSchema, {
20241
20357
  kind: "mutation",
20242
20358
  auth: "admin"
@@ -24111,10 +24227,10 @@ var lawnMowerControlCapability = {
24111
24227
  *
24112
24228
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24113
24229
  * to receive an ordered list of candidate base URLs it should race
24114
- * on connect — LAN IPv4 first (lowest latency when on same network),
24115
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24116
- * race them with short timeouts and stick with the winner for the
24117
- * session.
24230
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24231
+ * when on the same network), then public hostname (if a tunnel is
24232
+ * up). The SDK can race them with short timeouts and stick with the
24233
+ * winner for the session.
24118
24234
  *
24119
24235
  * Why hub-only: agents are not directly addressable by the operator's
24120
24236
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24269,6 +24385,17 @@ var NotificationEndpointSchema = object({
24269
24385
  /** What the ranking currently resolves to (null when nothing is reachable). */
24270
24386
  resolved: string().nullable()
24271
24387
  });
24388
+ /**
24389
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24390
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24391
+ * currently expands to, so the UI can show the effective set either way.
24392
+ */
24393
+ var ViewerEndpointsSchema = object({
24394
+ /** The operator's explicit race set, or empty for AUTO. */
24395
+ baseUrls: array(string()).readonly(),
24396
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24397
+ resolved: array(string()).readonly()
24398
+ });
24272
24399
  var AllowedAddressesSchema = object({
24273
24400
  /**
24274
24401
  * Allowlist of interface addresses operators have explicitly opted
@@ -24277,6 +24404,20 @@ var AllowedAddressesSchema = object({
24277
24404
  * Network Addresses admin page and persisted by the addon.
24278
24405
  */
24279
24406
  addresses: array(string()).readonly() });
24407
+ var TlsStatusSchema = object({
24408
+ mode: _enum([
24409
+ "generated",
24410
+ "uploaded",
24411
+ "disabled"
24412
+ ]),
24413
+ leafFingerprintSha256: string().nullable(),
24414
+ caFingerprintSha256: string().nullable(),
24415
+ validTo: string().nullable(),
24416
+ sans: array(string()),
24417
+ caCertPem: string().nullable(),
24418
+ reissueError: string().nullable(),
24419
+ restartRequired: boolean()
24420
+ });
24280
24421
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24281
24422
  /**
24282
24423
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24286,17 +24427,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24286
24427
  */
24287
24428
  port: number().int().min(1).max(65535).optional(),
24288
24429
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24289
- * candidate. Default `true`. */
24430
+ * candidate. Default `false` — loopback is not a client route. */
24290
24431
  includeLoopback: boolean().optional(),
24291
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24292
- * Default `false`. */
24432
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24433
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24434
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24293
24435
  ipv4Only: boolean().optional(),
24294
24436
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24295
24437
  * Pass `'https'` when the caller is itself loaded over HTTPS
24296
24438
  * to avoid mixed-content blocks in the browser. The public
24297
24439
  * tunnel always emits `https://` regardless. */
24298
24440
  scheme: _enum(["http", "https"]).optional()
24299
- }), 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" });
24441
+ }), 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, {
24442
+ kind: "mutation",
24443
+ auth: "admin"
24444
+ }), method(object({
24445
+ certPem: string().min(1),
24446
+ keyPem: string().min(1),
24447
+ caPem: string().optional()
24448
+ }), TlsStatusSchema, {
24449
+ kind: "mutation",
24450
+ auth: "admin"
24451
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24452
+ kind: "mutation",
24453
+ auth: "admin"
24454
+ });
24300
24455
  var LockControlStatusSchema = object({
24301
24456
  /** Lifecycle state of the lock. `jammed` means the motor reported
24302
24457
  * failure to reach the target — operator intervention required. */
@@ -32887,6 +33042,12 @@ Object.freeze({
32887
33042
  addonId: null,
32888
33043
  access: "create"
32889
33044
  },
33045
+ "localNetwork.downloadCa": {
33046
+ capName: "local-network",
33047
+ capScope: "system",
33048
+ addonId: null,
33049
+ access: "view"
33050
+ },
32890
33051
  "localNetwork.getAllowedAddresses": {
32891
33052
  capName: "local-network",
32892
33053
  capScope: "system",
@@ -32911,18 +33072,42 @@ Object.freeze({
32911
33072
  addonId: null,
32912
33073
  access: "view"
32913
33074
  },
33075
+ "localNetwork.getTlsStatus": {
33076
+ capName: "local-network",
33077
+ capScope: "system",
33078
+ addonId: null,
33079
+ access: "view"
33080
+ },
33081
+ "localNetwork.getViewerEndpoints": {
33082
+ capName: "local-network",
33083
+ capScope: "system",
33084
+ addonId: null,
33085
+ access: "view"
33086
+ },
32914
33087
  "localNetwork.list": {
32915
33088
  capName: "local-network",
32916
33089
  capScope: "system",
32917
33090
  addonId: null,
32918
33091
  access: "view"
32919
33092
  },
33093
+ "localNetwork.regenerateCertificate": {
33094
+ capName: "local-network",
33095
+ capScope: "system",
33096
+ addonId: null,
33097
+ access: "create"
33098
+ },
32920
33099
  "localNetwork.resetAllowlistToBestMatch": {
32921
33100
  capName: "local-network",
32922
33101
  capScope: "system",
32923
33102
  addonId: null,
32924
33103
  access: "delete"
32925
33104
  },
33105
+ "localNetwork.revertToGeneratedCertificate": {
33106
+ capName: "local-network",
33107
+ capScope: "system",
33108
+ addonId: null,
33109
+ access: "create"
33110
+ },
32926
33111
  "localNetwork.setAllowedAddresses": {
32927
33112
  capName: "local-network",
32928
33113
  capScope: "system",
@@ -32935,6 +33120,18 @@ Object.freeze({
32935
33120
  addonId: null,
32936
33121
  access: "create"
32937
33122
  },
33123
+ "localNetwork.setViewerEndpoints": {
33124
+ capName: "local-network",
33125
+ capScope: "system",
33126
+ addonId: null,
33127
+ access: "create"
33128
+ },
33129
+ "localNetwork.uploadCertificate": {
33130
+ capName: "local-network",
33131
+ capScope: "system",
33132
+ addonId: null,
33133
+ access: "create"
33134
+ },
32938
33135
  "lockControl.lock": {
32939
33136
  capName: "lock-control",
32940
33137
  capScope: "device",
@@ -35815,6 +36012,12 @@ Object.freeze({
35815
36012
  addonId: null,
35816
36013
  access: "create"
35817
36014
  },
36015
+ "terminalSession.updateInstance": {
36016
+ capName: "terminal-session",
36017
+ capScope: "system",
36018
+ addonId: null,
36019
+ access: "create"
36020
+ },
35818
36021
  "terminalSession.writeInput": {
35819
36022
  capName: "terminal-session",
35820
36023
  capScope: "system",
@@ -38302,6 +38505,35 @@ Object.freeze(Object.fromEntries([{
38302
38505
  }]
38303
38506
  }].map((s) => [s.stepId, s.defaultModelId])));
38304
38507
  string().min(1);
38508
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38509
+ stepId: "face-embedding",
38510
+ key: "minLandmarkFaceSize",
38511
+ label: "Min face size for recognition (detection px)",
38512
+ 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.",
38513
+ type: "slider",
38514
+ min: 0,
38515
+ max: 64,
38516
+ step: 2,
38517
+ default: 24
38518
+ }];
38519
+ function clusterStepSettingKey(stepId, fieldKey) {
38520
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38521
+ }
38522
+ var ClusterSettingNumberSchema = number().finite();
38523
+ function readClusterStepSettings(config) {
38524
+ const out = {};
38525
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38526
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38527
+ const value = parsed.success ? parsed.data : field.default;
38528
+ const existing = out[field.stepId] ?? {};
38529
+ out[field.stepId] = {
38530
+ ...existing,
38531
+ [field.key]: value
38532
+ };
38533
+ }
38534
+ return out;
38535
+ }
38536
+ readClusterStepSettings({});
38305
38537
  object({
38306
38538
  /**
38307
38539
  * 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-hikvision",
3
- "version": "1.2.33",
3
+ "version": "1.2.34",
4
4
  "description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
5
5
  "keywords": [
6
6
  "camstack",