@camstack/addon-provider-ecowitt 0.2.25 → 0.2.26

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
@@ -8023,6 +8023,15 @@ var LabelDefinitionSchema = object({
8023
8023
  description: string().optional(),
8024
8024
  icon: string().optional()
8025
8025
  });
8026
+ var ClassMapDefinitionSchema = object({
8027
+ mapping: record(string(), _enum([
8028
+ "person",
8029
+ "vehicle",
8030
+ "animal",
8031
+ "package"
8032
+ ])),
8033
+ preserveOriginal: boolean()
8034
+ });
8026
8035
  var MODEL_FORMATS = [
8027
8036
  "onnx",
8028
8037
  "coreml",
@@ -8201,7 +8210,13 @@ var ModelCatalogEntrySchema = object({
8201
8210
  * `id` stays the source of truth for resolution/download/persistence; grouping
8202
8211
  * is a presentation overlay resolved back to an `id`.
8203
8212
  */
8204
- group: ModelVariantGroupSchema.optional()
8213
+ group: ModelVariantGroupSchema.optional(),
8214
+ /**
8215
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8216
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8217
+ * labels already ARE the CamStack macros (Scrypted identity map).
8218
+ */
8219
+ classMap: ClassMapDefinitionSchema.optional()
8205
8220
  });
8206
8221
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8207
8222
  format: literal("openvino"),
@@ -8230,7 +8245,8 @@ var ModelConvertMetadataSchema = object({
8230
8245
  "ocr",
8231
8246
  "segmentation"
8232
8247
  ]),
8233
- faceAlignment: boolean().optional()
8248
+ faceAlignment: boolean().optional(),
8249
+ classMap: ClassMapDefinitionSchema.optional()
8234
8250
  });
8235
8251
  var ConvertResultSchema = object({
8236
8252
  entry: ModelCatalogEntrySchema,
@@ -17523,6 +17539,33 @@ var NativeCropRefSchema = object({
17523
17539
  h: number()
17524
17540
  })
17525
17541
  });
17542
+ object({
17543
+ crop: object({
17544
+ left: number(),
17545
+ top: number(),
17546
+ width: number().positive(),
17547
+ height: number().positive()
17548
+ }).optional(),
17549
+ content: object({
17550
+ width: number().int().positive(),
17551
+ height: number().int().positive()
17552
+ }),
17553
+ fit: _enum(["stretch", "contain"]),
17554
+ format: _enum([
17555
+ "rgb",
17556
+ "gray",
17557
+ "jpeg"
17558
+ ])
17559
+ });
17560
+ var FrameRefSchema = object({
17561
+ registryId: string().min(1),
17562
+ id: string().min(1),
17563
+ width: number().int().positive(),
17564
+ height: number().int().positive(),
17565
+ format: _enum(["rgb", "gray"]),
17566
+ timestamp: number(),
17567
+ capturedAt: number().optional()
17568
+ });
17526
17569
  var ModelFormatSchema$1 = _enum([
17527
17570
  "onnx",
17528
17571
  "coreml",
@@ -17767,6 +17810,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17767
17810
  steps: array(PipelineStepInputSchema).min(1),
17768
17811
  frame: FrameInputSchema.optional(),
17769
17812
  /**
17813
+ * Process-local lazy frame. Valid only when caller and provider resolve
17814
+ * in the same execution-group process; split/cross-node callers use
17815
+ * `frame`/`image` inline compatibility instead.
17816
+ */
17817
+ frameRef: FrameRefSchema.optional(),
17818
+ /**
17770
17819
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17771
17820
  * the decoded pixels live in. One more member of the one-of
17772
17821
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18062,7 +18111,10 @@ var NativeCropResultSchema = object({
18062
18111
  * Which source served this crop, so a quality-sensitive consumer (the native
18063
18112
  * `keyFrame`) can reject a degraded fallback:
18064
18113
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18065
- * quality path).
18114
+ * quality path). A subject-tile serve is also native-resolution and stays
18115
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18116
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18117
+ * internal crop result (`nativeHits` vs `tileHits`).
18066
18118
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18067
18119
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18068
18120
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18553,12 +18605,41 @@ var RunnerLocalLoadSchema = object({
18553
18605
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18554
18606
  * working unchanged when they switch to reading from the runner cap.
18555
18607
  */
18608
+ var FrameLazyCountersSchema = object({
18609
+ framesDecoded: number(),
18610
+ framesAdmitted: number(),
18611
+ framesDroppedPixelFree: number(),
18612
+ viewsMaterialized: number(),
18613
+ viewsSkipped: number(),
18614
+ workerToRunnerBytes: number(),
18615
+ runnerToPoolRawBytes: number(),
18616
+ runnerToPoolJpegBytes: number(),
18617
+ onDemandFullFrameRequests: number(),
18618
+ onDemandCropRequests: number(),
18619
+ nativeHits: number(),
18620
+ nativeMisses: number(),
18621
+ tileHits: number(),
18622
+ tileMisses: number(),
18623
+ fallbackHits: number(),
18624
+ fallbackMisses: number(),
18625
+ retainedWritesAvoided: number(),
18626
+ residentRefs: number(),
18627
+ residentBytes: number(),
18628
+ releases: number(),
18629
+ evictions: number(),
18630
+ staleMisses: number()
18631
+ });
18632
+ var FrameLazyMetricsSchema = object({
18633
+ node: FrameLazyCountersSchema,
18634
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18635
+ });
18556
18636
  var RunnerLocalMetricsSchema = object({
18557
18637
  nodeId: string(),
18558
18638
  activeCameras: number(),
18559
18639
  throttledCameras: number(),
18560
18640
  avgInferenceTimeMs: number(),
18561
- queueDepth: number()
18641
+ queueDepth: number(),
18642
+ frameLazy: FrameLazyMetricsSchema.optional()
18562
18643
  });
18563
18644
  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({
18564
18645
  handle: FrameHandleSchema,
@@ -19858,6 +19939,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19858
19939
  location: StorageLocationSchema,
19859
19940
  relativePath: string()
19860
19941
  }), _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" });
19942
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19943
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19944
+ var ProfileSettingsBagSchema = record(string(), unknown());
19861
19945
  /**
19862
19946
  * A live terminal session hosted by the provider addon. Output and input do
19863
19947
  * NOT flow through the capability — they use the addon data plane
@@ -19887,7 +19971,14 @@ var TerminalSessionInfoSchema = object({
19887
19971
  var TerminalProfileInfoSchema = object({
19888
19972
  profileId: string(),
19889
19973
  label: string(),
19890
- description: string().optional()
19974
+ description: string().optional(),
19975
+ /** Spawn defaults the instance form copies on create. */
19976
+ executable: string().optional(),
19977
+ args: array(string()).readonly().optional(),
19978
+ cwd: string().optional(),
19979
+ environment: array(string()).readonly().optional(),
19980
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19981
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19891
19982
  });
19892
19983
  /**
19893
19984
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19900,7 +19991,12 @@ var TerminalInstanceInfoSchema = object({
19900
19991
  profileId: string(),
19901
19992
  profileLabel: string(),
19902
19993
  name: string(),
19903
- enabled: boolean()
19994
+ enabled: boolean(),
19995
+ executable: string(),
19996
+ args: array(string()).readonly(),
19997
+ cwd: string(),
19998
+ environment: array(string()).readonly(),
19999
+ profileSettings: ProfileSettingsBagSchema
19904
20000
  });
19905
20001
  var TerminalLegacyCameraSchema = object({
19906
20002
  stableId: string(),
@@ -19930,7 +20026,23 @@ var TerminalOutputBatchSchema = object({
19930
20026
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19931
20027
  targetNodeId: string().min(1),
19932
20028
  profileId: string().min(1),
19933
- name: string().trim().min(1).max(160).optional()
20029
+ name: string().trim().min(1).max(160).optional(),
20030
+ executable: string().max(1024).optional(),
20031
+ args: array(string().max(2048)).max(64).optional(),
20032
+ cwd: string().max(1024).optional(),
20033
+ environment: array(string().max(4096)).max(64).optional(),
20034
+ profileSettings: ProfileSettingsBagSchema.optional()
20035
+ }), TerminalInstanceInfoSchema, {
20036
+ kind: "mutation",
20037
+ auth: "admin"
20038
+ }), method(object({
20039
+ instanceId: string().min(1),
20040
+ name: string().trim().min(1).max(160).optional(),
20041
+ executable: string().max(1024).optional(),
20042
+ args: array(string().max(2048)).max(64).optional(),
20043
+ cwd: string().max(1024).optional(),
20044
+ environment: array(string().max(4096)).max(64).optional(),
20045
+ profileSettings: ProfileSettingsBagSchema.optional()
19934
20046
  }), TerminalInstanceInfoSchema, {
19935
20047
  kind: "mutation",
19936
20048
  auth: "admin"
@@ -19952,7 +20064,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19952
20064
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19953
20065
  profileId: string(),
19954
20066
  cols: number().int().positive(),
19955
- rows: number().int().positive()
20067
+ rows: number().int().positive(),
20068
+ executable: string().max(1024).optional(),
20069
+ args: array(string().max(2048)).max(64).optional(),
20070
+ cwd: string().max(1024).optional(),
20071
+ environment: array(string().max(4096)).max(64).optional()
19956
20072
  }), TerminalSessionInfoSchema, {
19957
20073
  kind: "mutation",
19958
20074
  auth: "admin"
@@ -23827,10 +23943,10 @@ var lawnMowerControlCapability = {
23827
23943
  *
23828
23944
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23829
23945
  * to receive an ordered list of candidate base URLs it should race
23830
- * on connect — LAN IPv4 first (lowest latency when on same network),
23831
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23832
- * race them with short timeouts and stick with the winner for the
23833
- * session.
23946
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
23947
+ * when on the same network), then public hostname (if a tunnel is
23948
+ * up). The SDK can race them with short timeouts and stick with the
23949
+ * winner for the session.
23834
23950
  *
23835
23951
  * Why hub-only: agents are not directly addressable by the operator's
23836
23952
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -23985,6 +24101,17 @@ var NotificationEndpointSchema = object({
23985
24101
  /** What the ranking currently resolves to (null when nothing is reachable). */
23986
24102
  resolved: string().nullable()
23987
24103
  });
24104
+ /**
24105
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24106
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24107
+ * currently expands to, so the UI can show the effective set either way.
24108
+ */
24109
+ var ViewerEndpointsSchema = object({
24110
+ /** The operator's explicit race set, or empty for AUTO. */
24111
+ baseUrls: array(string()).readonly(),
24112
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24113
+ resolved: array(string()).readonly()
24114
+ });
23988
24115
  var AllowedAddressesSchema = object({
23989
24116
  /**
23990
24117
  * Allowlist of interface addresses operators have explicitly opted
@@ -23993,6 +24120,20 @@ var AllowedAddressesSchema = object({
23993
24120
  * Network Addresses admin page and persisted by the addon.
23994
24121
  */
23995
24122
  addresses: array(string()).readonly() });
24123
+ var TlsStatusSchema = object({
24124
+ mode: _enum([
24125
+ "generated",
24126
+ "uploaded",
24127
+ "disabled"
24128
+ ]),
24129
+ leafFingerprintSha256: string().nullable(),
24130
+ caFingerprintSha256: string().nullable(),
24131
+ validTo: string().nullable(),
24132
+ sans: array(string()),
24133
+ caCertPem: string().nullable(),
24134
+ reissueError: string().nullable(),
24135
+ restartRequired: boolean()
24136
+ });
23996
24137
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
23997
24138
  /**
23998
24139
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24002,17 +24143,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24002
24143
  */
24003
24144
  port: number().int().min(1).max(65535).optional(),
24004
24145
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24005
- * candidate. Default `true`. */
24146
+ * candidate. Default `false` — loopback is not a client route. */
24006
24147
  includeLoopback: boolean().optional(),
24007
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24008
- * Default `false`. */
24148
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24149
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24150
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24009
24151
  ipv4Only: boolean().optional(),
24010
24152
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24011
24153
  * Pass `'https'` when the caller is itself loaded over HTTPS
24012
24154
  * to avoid mixed-content blocks in the browser. The public
24013
24155
  * tunnel always emits `https://` regardless. */
24014
24156
  scheme: _enum(["http", "https"]).optional()
24015
- }), 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" });
24157
+ }), 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, {
24158
+ kind: "mutation",
24159
+ auth: "admin"
24160
+ }), method(object({
24161
+ certPem: string().min(1),
24162
+ keyPem: string().min(1),
24163
+ caPem: string().optional()
24164
+ }), TlsStatusSchema, {
24165
+ kind: "mutation",
24166
+ auth: "admin"
24167
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24168
+ kind: "mutation",
24169
+ auth: "admin"
24170
+ });
24016
24171
  var LockControlStatusSchema = object({
24017
24172
  /** Lifecycle state of the lock. `jammed` means the motor reported
24018
24173
  * failure to reach the target — operator intervention required. */
@@ -32039,6 +32194,12 @@ Object.freeze({
32039
32194
  addonId: null,
32040
32195
  access: "create"
32041
32196
  },
32197
+ "localNetwork.downloadCa": {
32198
+ capName: "local-network",
32199
+ capScope: "system",
32200
+ addonId: null,
32201
+ access: "view"
32202
+ },
32042
32203
  "localNetwork.getAllowedAddresses": {
32043
32204
  capName: "local-network",
32044
32205
  capScope: "system",
@@ -32063,18 +32224,42 @@ Object.freeze({
32063
32224
  addonId: null,
32064
32225
  access: "view"
32065
32226
  },
32227
+ "localNetwork.getTlsStatus": {
32228
+ capName: "local-network",
32229
+ capScope: "system",
32230
+ addonId: null,
32231
+ access: "view"
32232
+ },
32233
+ "localNetwork.getViewerEndpoints": {
32234
+ capName: "local-network",
32235
+ capScope: "system",
32236
+ addonId: null,
32237
+ access: "view"
32238
+ },
32066
32239
  "localNetwork.list": {
32067
32240
  capName: "local-network",
32068
32241
  capScope: "system",
32069
32242
  addonId: null,
32070
32243
  access: "view"
32071
32244
  },
32245
+ "localNetwork.regenerateCertificate": {
32246
+ capName: "local-network",
32247
+ capScope: "system",
32248
+ addonId: null,
32249
+ access: "create"
32250
+ },
32072
32251
  "localNetwork.resetAllowlistToBestMatch": {
32073
32252
  capName: "local-network",
32074
32253
  capScope: "system",
32075
32254
  addonId: null,
32076
32255
  access: "delete"
32077
32256
  },
32257
+ "localNetwork.revertToGeneratedCertificate": {
32258
+ capName: "local-network",
32259
+ capScope: "system",
32260
+ addonId: null,
32261
+ access: "create"
32262
+ },
32078
32263
  "localNetwork.setAllowedAddresses": {
32079
32264
  capName: "local-network",
32080
32265
  capScope: "system",
@@ -32087,6 +32272,18 @@ Object.freeze({
32087
32272
  addonId: null,
32088
32273
  access: "create"
32089
32274
  },
32275
+ "localNetwork.setViewerEndpoints": {
32276
+ capName: "local-network",
32277
+ capScope: "system",
32278
+ addonId: null,
32279
+ access: "create"
32280
+ },
32281
+ "localNetwork.uploadCertificate": {
32282
+ capName: "local-network",
32283
+ capScope: "system",
32284
+ addonId: null,
32285
+ access: "create"
32286
+ },
32090
32287
  "lockControl.lock": {
32091
32288
  capName: "lock-control",
32092
32289
  capScope: "device",
@@ -34967,6 +35164,12 @@ Object.freeze({
34967
35164
  addonId: null,
34968
35165
  access: "create"
34969
35166
  },
35167
+ "terminalSession.updateInstance": {
35168
+ capName: "terminal-session",
35169
+ capScope: "system",
35170
+ addonId: null,
35171
+ access: "create"
35172
+ },
34970
35173
  "terminalSession.writeInput": {
34971
35174
  capName: "terminal-session",
34972
35175
  capScope: "system",
@@ -37454,6 +37657,35 @@ Object.freeze(Object.fromEntries([{
37454
37657
  }]
37455
37658
  }].map((s) => [s.stepId, s.defaultModelId])));
37456
37659
  string().min(1);
37660
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37661
+ stepId: "face-embedding",
37662
+ key: "minLandmarkFaceSize",
37663
+ label: "Min face size for recognition (detection px)",
37664
+ 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.",
37665
+ type: "slider",
37666
+ min: 0,
37667
+ max: 64,
37668
+ step: 2,
37669
+ default: 24
37670
+ }];
37671
+ function clusterStepSettingKey(stepId, fieldKey) {
37672
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37673
+ }
37674
+ var ClusterSettingNumberSchema = number().finite();
37675
+ function readClusterStepSettings(config) {
37676
+ const out = {};
37677
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37678
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37679
+ const value = parsed.success ? parsed.data : field.default;
37680
+ const existing = out[field.stepId] ?? {};
37681
+ out[field.stepId] = {
37682
+ ...existing,
37683
+ [field.key]: value
37684
+ };
37685
+ }
37686
+ return out;
37687
+ }
37688
+ readClusterStepSettings({});
37457
37689
  object({
37458
37690
  /**
37459
37691
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -8022,6 +8022,15 @@ var LabelDefinitionSchema = object({
8022
8022
  description: string().optional(),
8023
8023
  icon: string().optional()
8024
8024
  });
8025
+ var ClassMapDefinitionSchema = object({
8026
+ mapping: record(string(), _enum([
8027
+ "person",
8028
+ "vehicle",
8029
+ "animal",
8030
+ "package"
8031
+ ])),
8032
+ preserveOriginal: boolean()
8033
+ });
8025
8034
  var MODEL_FORMATS = [
8026
8035
  "onnx",
8027
8036
  "coreml",
@@ -8200,7 +8209,13 @@ var ModelCatalogEntrySchema = object({
8200
8209
  * `id` stays the source of truth for resolution/download/persistence; grouping
8201
8210
  * is a presentation overlay resolved back to an `id`.
8202
8211
  */
8203
- group: ModelVariantGroupSchema.optional()
8212
+ group: ModelVariantGroupSchema.optional(),
8213
+ /**
8214
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8215
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8216
+ * labels already ARE the CamStack macros (Scrypted identity map).
8217
+ */
8218
+ classMap: ClassMapDefinitionSchema.optional()
8204
8219
  });
8205
8220
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8206
8221
  format: literal("openvino"),
@@ -8229,7 +8244,8 @@ var ModelConvertMetadataSchema = object({
8229
8244
  "ocr",
8230
8245
  "segmentation"
8231
8246
  ]),
8232
- faceAlignment: boolean().optional()
8247
+ faceAlignment: boolean().optional(),
8248
+ classMap: ClassMapDefinitionSchema.optional()
8233
8249
  });
8234
8250
  var ConvertResultSchema = object({
8235
8251
  entry: ModelCatalogEntrySchema,
@@ -17522,6 +17538,33 @@ var NativeCropRefSchema = object({
17522
17538
  h: number()
17523
17539
  })
17524
17540
  });
17541
+ object({
17542
+ crop: object({
17543
+ left: number(),
17544
+ top: number(),
17545
+ width: number().positive(),
17546
+ height: number().positive()
17547
+ }).optional(),
17548
+ content: object({
17549
+ width: number().int().positive(),
17550
+ height: number().int().positive()
17551
+ }),
17552
+ fit: _enum(["stretch", "contain"]),
17553
+ format: _enum([
17554
+ "rgb",
17555
+ "gray",
17556
+ "jpeg"
17557
+ ])
17558
+ });
17559
+ var FrameRefSchema = object({
17560
+ registryId: string().min(1),
17561
+ id: string().min(1),
17562
+ width: number().int().positive(),
17563
+ height: number().int().positive(),
17564
+ format: _enum(["rgb", "gray"]),
17565
+ timestamp: number(),
17566
+ capturedAt: number().optional()
17567
+ });
17525
17568
  var ModelFormatSchema$1 = _enum([
17526
17569
  "onnx",
17527
17570
  "coreml",
@@ -17766,6 +17809,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17766
17809
  steps: array(PipelineStepInputSchema).min(1),
17767
17810
  frame: FrameInputSchema.optional(),
17768
17811
  /**
17812
+ * Process-local lazy frame. Valid only when caller and provider resolve
17813
+ * in the same execution-group process; split/cross-node callers use
17814
+ * `frame`/`image` inline compatibility instead.
17815
+ */
17816
+ frameRef: FrameRefSchema.optional(),
17817
+ /**
17769
17818
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17770
17819
  * the decoded pixels live in. One more member of the one-of
17771
17820
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18061,7 +18110,10 @@ var NativeCropResultSchema = object({
18061
18110
  * Which source served this crop, so a quality-sensitive consumer (the native
18062
18111
  * `keyFrame`) can reject a degraded fallback:
18063
18112
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18064
- * quality path).
18113
+ * quality path). A subject-tile serve is also native-resolution and stays
18114
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18115
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18116
+ * internal crop result (`nativeHits` vs `tileHits`).
18065
18117
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18066
18118
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18067
18119
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18552,12 +18604,41 @@ var RunnerLocalLoadSchema = object({
18552
18604
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18553
18605
  * working unchanged when they switch to reading from the runner cap.
18554
18606
  */
18607
+ var FrameLazyCountersSchema = object({
18608
+ framesDecoded: number(),
18609
+ framesAdmitted: number(),
18610
+ framesDroppedPixelFree: number(),
18611
+ viewsMaterialized: number(),
18612
+ viewsSkipped: number(),
18613
+ workerToRunnerBytes: number(),
18614
+ runnerToPoolRawBytes: number(),
18615
+ runnerToPoolJpegBytes: number(),
18616
+ onDemandFullFrameRequests: number(),
18617
+ onDemandCropRequests: number(),
18618
+ nativeHits: number(),
18619
+ nativeMisses: number(),
18620
+ tileHits: number(),
18621
+ tileMisses: number(),
18622
+ fallbackHits: number(),
18623
+ fallbackMisses: number(),
18624
+ retainedWritesAvoided: number(),
18625
+ residentRefs: number(),
18626
+ residentBytes: number(),
18627
+ releases: number(),
18628
+ evictions: number(),
18629
+ staleMisses: number()
18630
+ });
18631
+ var FrameLazyMetricsSchema = object({
18632
+ node: FrameLazyCountersSchema,
18633
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18634
+ });
18555
18635
  var RunnerLocalMetricsSchema = object({
18556
18636
  nodeId: string(),
18557
18637
  activeCameras: number(),
18558
18638
  throttledCameras: number(),
18559
18639
  avgInferenceTimeMs: number(),
18560
- queueDepth: number()
18640
+ queueDepth: number(),
18641
+ frameLazy: FrameLazyMetricsSchema.optional()
18561
18642
  });
18562
18643
  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({
18563
18644
  handle: FrameHandleSchema,
@@ -19857,6 +19938,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19857
19938
  location: StorageLocationSchema,
19858
19939
  relativePath: string()
19859
19940
  }), _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" });
19941
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19942
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19943
+ var ProfileSettingsBagSchema = record(string(), unknown());
19860
19944
  /**
19861
19945
  * A live terminal session hosted by the provider addon. Output and input do
19862
19946
  * NOT flow through the capability — they use the addon data plane
@@ -19886,7 +19970,14 @@ var TerminalSessionInfoSchema = object({
19886
19970
  var TerminalProfileInfoSchema = object({
19887
19971
  profileId: string(),
19888
19972
  label: string(),
19889
- description: string().optional()
19973
+ description: string().optional(),
19974
+ /** Spawn defaults the instance form copies on create. */
19975
+ executable: string().optional(),
19976
+ args: array(string()).readonly().optional(),
19977
+ cwd: string().optional(),
19978
+ environment: array(string()).readonly().optional(),
19979
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19980
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19890
19981
  });
19891
19982
  /**
19892
19983
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19899,7 +19990,12 @@ var TerminalInstanceInfoSchema = object({
19899
19990
  profileId: string(),
19900
19991
  profileLabel: string(),
19901
19992
  name: string(),
19902
- enabled: boolean()
19993
+ enabled: boolean(),
19994
+ executable: string(),
19995
+ args: array(string()).readonly(),
19996
+ cwd: string(),
19997
+ environment: array(string()).readonly(),
19998
+ profileSettings: ProfileSettingsBagSchema
19903
19999
  });
19904
20000
  var TerminalLegacyCameraSchema = object({
19905
20001
  stableId: string(),
@@ -19929,7 +20025,23 @@ var TerminalOutputBatchSchema = object({
19929
20025
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19930
20026
  targetNodeId: string().min(1),
19931
20027
  profileId: string().min(1),
19932
- name: string().trim().min(1).max(160).optional()
20028
+ name: string().trim().min(1).max(160).optional(),
20029
+ executable: string().max(1024).optional(),
20030
+ args: array(string().max(2048)).max(64).optional(),
20031
+ cwd: string().max(1024).optional(),
20032
+ environment: array(string().max(4096)).max(64).optional(),
20033
+ profileSettings: ProfileSettingsBagSchema.optional()
20034
+ }), TerminalInstanceInfoSchema, {
20035
+ kind: "mutation",
20036
+ auth: "admin"
20037
+ }), method(object({
20038
+ instanceId: string().min(1),
20039
+ name: string().trim().min(1).max(160).optional(),
20040
+ executable: string().max(1024).optional(),
20041
+ args: array(string().max(2048)).max(64).optional(),
20042
+ cwd: string().max(1024).optional(),
20043
+ environment: array(string().max(4096)).max(64).optional(),
20044
+ profileSettings: ProfileSettingsBagSchema.optional()
19933
20045
  }), TerminalInstanceInfoSchema, {
19934
20046
  kind: "mutation",
19935
20047
  auth: "admin"
@@ -19951,7 +20063,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19951
20063
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19952
20064
  profileId: string(),
19953
20065
  cols: number().int().positive(),
19954
- rows: number().int().positive()
20066
+ rows: number().int().positive(),
20067
+ executable: string().max(1024).optional(),
20068
+ args: array(string().max(2048)).max(64).optional(),
20069
+ cwd: string().max(1024).optional(),
20070
+ environment: array(string().max(4096)).max(64).optional()
19955
20071
  }), TerminalSessionInfoSchema, {
19956
20072
  kind: "mutation",
19957
20073
  auth: "admin"
@@ -23826,10 +23942,10 @@ var lawnMowerControlCapability = {
23826
23942
  *
23827
23943
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23828
23944
  * to receive an ordered list of candidate base URLs it should race
23829
- * on connect — LAN IPv4 first (lowest latency when on same network),
23830
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23831
- * race them with short timeouts and stick with the winner for the
23832
- * session.
23945
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
23946
+ * when on the same network), then public hostname (if a tunnel is
23947
+ * up). The SDK can race them with short timeouts and stick with the
23948
+ * winner for the session.
23833
23949
  *
23834
23950
  * Why hub-only: agents are not directly addressable by the operator's
23835
23951
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -23984,6 +24100,17 @@ var NotificationEndpointSchema = object({
23984
24100
  /** What the ranking currently resolves to (null when nothing is reachable). */
23985
24101
  resolved: string().nullable()
23986
24102
  });
24103
+ /**
24104
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24105
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24106
+ * currently expands to, so the UI can show the effective set either way.
24107
+ */
24108
+ var ViewerEndpointsSchema = object({
24109
+ /** The operator's explicit race set, or empty for AUTO. */
24110
+ baseUrls: array(string()).readonly(),
24111
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24112
+ resolved: array(string()).readonly()
24113
+ });
23987
24114
  var AllowedAddressesSchema = object({
23988
24115
  /**
23989
24116
  * Allowlist of interface addresses operators have explicitly opted
@@ -23992,6 +24119,20 @@ var AllowedAddressesSchema = object({
23992
24119
  * Network Addresses admin page and persisted by the addon.
23993
24120
  */
23994
24121
  addresses: array(string()).readonly() });
24122
+ var TlsStatusSchema = object({
24123
+ mode: _enum([
24124
+ "generated",
24125
+ "uploaded",
24126
+ "disabled"
24127
+ ]),
24128
+ leafFingerprintSha256: string().nullable(),
24129
+ caFingerprintSha256: string().nullable(),
24130
+ validTo: string().nullable(),
24131
+ sans: array(string()),
24132
+ caCertPem: string().nullable(),
24133
+ reissueError: string().nullable(),
24134
+ restartRequired: boolean()
24135
+ });
23995
24136
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
23996
24137
  /**
23997
24138
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24001,17 +24142,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24001
24142
  */
24002
24143
  port: number().int().min(1).max(65535).optional(),
24003
24144
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24004
- * candidate. Default `true`. */
24145
+ * candidate. Default `false` — loopback is not a client route. */
24005
24146
  includeLoopback: boolean().optional(),
24006
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24007
- * Default `false`. */
24147
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24148
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24149
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24008
24150
  ipv4Only: boolean().optional(),
24009
24151
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24010
24152
  * Pass `'https'` when the caller is itself loaded over HTTPS
24011
24153
  * to avoid mixed-content blocks in the browser. The public
24012
24154
  * tunnel always emits `https://` regardless. */
24013
24155
  scheme: _enum(["http", "https"]).optional()
24014
- }), 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" });
24156
+ }), 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, {
24157
+ kind: "mutation",
24158
+ auth: "admin"
24159
+ }), method(object({
24160
+ certPem: string().min(1),
24161
+ keyPem: string().min(1),
24162
+ caPem: string().optional()
24163
+ }), TlsStatusSchema, {
24164
+ kind: "mutation",
24165
+ auth: "admin"
24166
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24167
+ kind: "mutation",
24168
+ auth: "admin"
24169
+ });
24015
24170
  var LockControlStatusSchema = object({
24016
24171
  /** Lifecycle state of the lock. `jammed` means the motor reported
24017
24172
  * failure to reach the target — operator intervention required. */
@@ -32038,6 +32193,12 @@ Object.freeze({
32038
32193
  addonId: null,
32039
32194
  access: "create"
32040
32195
  },
32196
+ "localNetwork.downloadCa": {
32197
+ capName: "local-network",
32198
+ capScope: "system",
32199
+ addonId: null,
32200
+ access: "view"
32201
+ },
32041
32202
  "localNetwork.getAllowedAddresses": {
32042
32203
  capName: "local-network",
32043
32204
  capScope: "system",
@@ -32062,18 +32223,42 @@ Object.freeze({
32062
32223
  addonId: null,
32063
32224
  access: "view"
32064
32225
  },
32226
+ "localNetwork.getTlsStatus": {
32227
+ capName: "local-network",
32228
+ capScope: "system",
32229
+ addonId: null,
32230
+ access: "view"
32231
+ },
32232
+ "localNetwork.getViewerEndpoints": {
32233
+ capName: "local-network",
32234
+ capScope: "system",
32235
+ addonId: null,
32236
+ access: "view"
32237
+ },
32065
32238
  "localNetwork.list": {
32066
32239
  capName: "local-network",
32067
32240
  capScope: "system",
32068
32241
  addonId: null,
32069
32242
  access: "view"
32070
32243
  },
32244
+ "localNetwork.regenerateCertificate": {
32245
+ capName: "local-network",
32246
+ capScope: "system",
32247
+ addonId: null,
32248
+ access: "create"
32249
+ },
32071
32250
  "localNetwork.resetAllowlistToBestMatch": {
32072
32251
  capName: "local-network",
32073
32252
  capScope: "system",
32074
32253
  addonId: null,
32075
32254
  access: "delete"
32076
32255
  },
32256
+ "localNetwork.revertToGeneratedCertificate": {
32257
+ capName: "local-network",
32258
+ capScope: "system",
32259
+ addonId: null,
32260
+ access: "create"
32261
+ },
32077
32262
  "localNetwork.setAllowedAddresses": {
32078
32263
  capName: "local-network",
32079
32264
  capScope: "system",
@@ -32086,6 +32271,18 @@ Object.freeze({
32086
32271
  addonId: null,
32087
32272
  access: "create"
32088
32273
  },
32274
+ "localNetwork.setViewerEndpoints": {
32275
+ capName: "local-network",
32276
+ capScope: "system",
32277
+ addonId: null,
32278
+ access: "create"
32279
+ },
32280
+ "localNetwork.uploadCertificate": {
32281
+ capName: "local-network",
32282
+ capScope: "system",
32283
+ addonId: null,
32284
+ access: "create"
32285
+ },
32089
32286
  "lockControl.lock": {
32090
32287
  capName: "lock-control",
32091
32288
  capScope: "device",
@@ -34966,6 +35163,12 @@ Object.freeze({
34966
35163
  addonId: null,
34967
35164
  access: "create"
34968
35165
  },
35166
+ "terminalSession.updateInstance": {
35167
+ capName: "terminal-session",
35168
+ capScope: "system",
35169
+ addonId: null,
35170
+ access: "create"
35171
+ },
34969
35172
  "terminalSession.writeInput": {
34970
35173
  capName: "terminal-session",
34971
35174
  capScope: "system",
@@ -37453,6 +37656,35 @@ Object.freeze(Object.fromEntries([{
37453
37656
  }]
37454
37657
  }].map((s) => [s.stepId, s.defaultModelId])));
37455
37658
  string().min(1);
37659
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37660
+ stepId: "face-embedding",
37661
+ key: "minLandmarkFaceSize",
37662
+ label: "Min face size for recognition (detection px)",
37663
+ 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.",
37664
+ type: "slider",
37665
+ min: 0,
37666
+ max: 64,
37667
+ step: 2,
37668
+ default: 24
37669
+ }];
37670
+ function clusterStepSettingKey(stepId, fieldKey) {
37671
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37672
+ }
37673
+ var ClusterSettingNumberSchema = number().finite();
37674
+ function readClusterStepSettings(config) {
37675
+ const out = {};
37676
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37677
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37678
+ const value = parsed.success ? parsed.data : field.default;
37679
+ const existing = out[field.stepId] ?? {};
37680
+ out[field.stepId] = {
37681
+ ...existing,
37682
+ [field.key]: value
37683
+ };
37684
+ }
37685
+ return out;
37686
+ }
37687
+ readClusterStepSettings({});
37456
37688
  object({
37457
37689
  /**
37458
37690
  * 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-ecowitt",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Ecowitt weather-station device-provider addon for CamStack — wraps the @apocaliss92/nodewitt local-poll / push client",
5
5
  "keywords": [
6
6
  "camstack",