@camstack/addon-provider-rademacher 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
@@ -9005,6 +9005,15 @@ var LabelDefinitionSchema = object({
9005
9005
  description: string().optional(),
9006
9006
  icon: string().optional()
9007
9007
  });
9008
+ var ClassMapDefinitionSchema = object({
9009
+ mapping: record(string(), _enum([
9010
+ "person",
9011
+ "vehicle",
9012
+ "animal",
9013
+ "package"
9014
+ ])),
9015
+ preserveOriginal: boolean()
9016
+ });
9008
9017
  var MODEL_FORMATS = [
9009
9018
  "onnx",
9010
9019
  "coreml",
@@ -9183,7 +9192,13 @@ var ModelCatalogEntrySchema = object({
9183
9192
  * `id` stays the source of truth for resolution/download/persistence; grouping
9184
9193
  * is a presentation overlay resolved back to an `id`.
9185
9194
  */
9186
- group: ModelVariantGroupSchema.optional()
9195
+ group: ModelVariantGroupSchema.optional(),
9196
+ /**
9197
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
9198
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
9199
+ * labels already ARE the CamStack macros (Scrypted identity map).
9200
+ */
9201
+ classMap: ClassMapDefinitionSchema.optional()
9187
9202
  });
9188
9203
  var ConvertTargetSchema = discriminatedUnion("format", [object({
9189
9204
  format: literal("openvino"),
@@ -9212,7 +9227,8 @@ var ModelConvertMetadataSchema = object({
9212
9227
  "ocr",
9213
9228
  "segmentation"
9214
9229
  ]),
9215
- faceAlignment: boolean().optional()
9230
+ faceAlignment: boolean().optional(),
9231
+ classMap: ClassMapDefinitionSchema.optional()
9216
9232
  });
9217
9233
  var ConvertResultSchema = object({
9218
9234
  entry: ModelCatalogEntrySchema,
@@ -18505,6 +18521,33 @@ var NativeCropRefSchema = object({
18505
18521
  h: number()
18506
18522
  })
18507
18523
  });
18524
+ object({
18525
+ crop: object({
18526
+ left: number(),
18527
+ top: number(),
18528
+ width: number().positive(),
18529
+ height: number().positive()
18530
+ }).optional(),
18531
+ content: object({
18532
+ width: number().int().positive(),
18533
+ height: number().int().positive()
18534
+ }),
18535
+ fit: _enum(["stretch", "contain"]),
18536
+ format: _enum([
18537
+ "rgb",
18538
+ "gray",
18539
+ "jpeg"
18540
+ ])
18541
+ });
18542
+ var FrameRefSchema = object({
18543
+ registryId: string().min(1),
18544
+ id: string().min(1),
18545
+ width: number().int().positive(),
18546
+ height: number().int().positive(),
18547
+ format: _enum(["rgb", "gray"]),
18548
+ timestamp: number(),
18549
+ capturedAt: number().optional()
18550
+ });
18508
18551
  var ModelFormatSchema$1 = _enum([
18509
18552
  "onnx",
18510
18553
  "coreml",
@@ -18749,6 +18792,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
18749
18792
  steps: array(PipelineStepInputSchema).min(1),
18750
18793
  frame: FrameInputSchema.optional(),
18751
18794
  /**
18795
+ * Process-local lazy frame. Valid only when caller and provider resolve
18796
+ * in the same execution-group process; split/cross-node callers use
18797
+ * `frame`/`image` inline compatibility instead.
18798
+ */
18799
+ frameRef: FrameRefSchema.optional(),
18800
+ /**
18752
18801
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
18753
18802
  * the decoded pixels live in. One more member of the one-of
18754
18803
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -19044,7 +19093,10 @@ var NativeCropResultSchema = object({
19044
19093
  * Which source served this crop, so a quality-sensitive consumer (the native
19045
19094
  * `keyFrame`) can reject a degraded fallback:
19046
19095
  * - `native` — cut from the decode worker's retained NATIVE surface (the
19047
- * quality path).
19096
+ * quality path). A subject-tile serve is also native-resolution and stays
19097
+ * `native` here: the public enum cannot name `tile` without a breaking cap
19098
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
19099
+ * internal crop result (`nativeHits` vs `tileHits`).
19048
19100
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
19049
19101
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
19050
19102
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -19535,12 +19587,41 @@ var RunnerLocalLoadSchema = object({
19535
19587
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
19536
19588
  * working unchanged when they switch to reading from the runner cap.
19537
19589
  */
19590
+ var FrameLazyCountersSchema = object({
19591
+ framesDecoded: number(),
19592
+ framesAdmitted: number(),
19593
+ framesDroppedPixelFree: number(),
19594
+ viewsMaterialized: number(),
19595
+ viewsSkipped: number(),
19596
+ workerToRunnerBytes: number(),
19597
+ runnerToPoolRawBytes: number(),
19598
+ runnerToPoolJpegBytes: number(),
19599
+ onDemandFullFrameRequests: number(),
19600
+ onDemandCropRequests: number(),
19601
+ nativeHits: number(),
19602
+ nativeMisses: number(),
19603
+ tileHits: number(),
19604
+ tileMisses: number(),
19605
+ fallbackHits: number(),
19606
+ fallbackMisses: number(),
19607
+ retainedWritesAvoided: number(),
19608
+ residentRefs: number(),
19609
+ residentBytes: number(),
19610
+ releases: number(),
19611
+ evictions: number(),
19612
+ staleMisses: number()
19613
+ });
19614
+ var FrameLazyMetricsSchema = object({
19615
+ node: FrameLazyCountersSchema,
19616
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
19617
+ });
19538
19618
  var RunnerLocalMetricsSchema = object({
19539
19619
  nodeId: string(),
19540
19620
  activeCameras: number(),
19541
19621
  throttledCameras: number(),
19542
19622
  avgInferenceTimeMs: number(),
19543
- queueDepth: number()
19623
+ queueDepth: number(),
19624
+ frameLazy: FrameLazyMetricsSchema.optional()
19544
19625
  });
19545
19626
  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({
19546
19627
  handle: FrameHandleSchema,
@@ -20840,6 +20921,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20840
20921
  location: StorageLocationSchema,
20841
20922
  relativePath: string()
20842
20923
  }), _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" });
20924
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20925
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20926
+ var ProfileSettingsBagSchema = record(string(), unknown());
20843
20927
  /**
20844
20928
  * A live terminal session hosted by the provider addon. Output and input do
20845
20929
  * NOT flow through the capability — they use the addon data plane
@@ -20869,7 +20953,14 @@ var TerminalSessionInfoSchema = object({
20869
20953
  var TerminalProfileInfoSchema = object({
20870
20954
  profileId: string(),
20871
20955
  label: string(),
20872
- description: string().optional()
20956
+ description: string().optional(),
20957
+ /** Spawn defaults the instance form copies on create. */
20958
+ executable: string().optional(),
20959
+ args: array(string()).readonly().optional(),
20960
+ cwd: string().optional(),
20961
+ environment: array(string()).readonly().optional(),
20962
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20963
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20873
20964
  });
20874
20965
  /**
20875
20966
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20882,7 +20973,12 @@ var TerminalInstanceInfoSchema = object({
20882
20973
  profileId: string(),
20883
20974
  profileLabel: string(),
20884
20975
  name: string(),
20885
- enabled: boolean()
20976
+ enabled: boolean(),
20977
+ executable: string(),
20978
+ args: array(string()).readonly(),
20979
+ cwd: string(),
20980
+ environment: array(string()).readonly(),
20981
+ profileSettings: ProfileSettingsBagSchema
20886
20982
  });
20887
20983
  var TerminalLegacyCameraSchema = object({
20888
20984
  stableId: string(),
@@ -20912,7 +21008,23 @@ var TerminalOutputBatchSchema = object({
20912
21008
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20913
21009
  targetNodeId: string().min(1),
20914
21010
  profileId: string().min(1),
20915
- name: string().trim().min(1).max(160).optional()
21011
+ name: string().trim().min(1).max(160).optional(),
21012
+ executable: string().max(1024).optional(),
21013
+ args: array(string().max(2048)).max(64).optional(),
21014
+ cwd: string().max(1024).optional(),
21015
+ environment: array(string().max(4096)).max(64).optional(),
21016
+ profileSettings: ProfileSettingsBagSchema.optional()
21017
+ }), TerminalInstanceInfoSchema, {
21018
+ kind: "mutation",
21019
+ auth: "admin"
21020
+ }), method(object({
21021
+ instanceId: string().min(1),
21022
+ name: string().trim().min(1).max(160).optional(),
21023
+ executable: string().max(1024).optional(),
21024
+ args: array(string().max(2048)).max(64).optional(),
21025
+ cwd: string().max(1024).optional(),
21026
+ environment: array(string().max(4096)).max(64).optional(),
21027
+ profileSettings: ProfileSettingsBagSchema.optional()
20916
21028
  }), TerminalInstanceInfoSchema, {
20917
21029
  kind: "mutation",
20918
21030
  auth: "admin"
@@ -20934,7 +21046,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20934
21046
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20935
21047
  profileId: string(),
20936
21048
  cols: number().int().positive(),
20937
- rows: number().int().positive()
21049
+ rows: number().int().positive(),
21050
+ executable: string().max(1024).optional(),
21051
+ args: array(string().max(2048)).max(64).optional(),
21052
+ cwd: string().max(1024).optional(),
21053
+ environment: array(string().max(4096)).max(64).optional()
20938
21054
  }), TerminalSessionInfoSchema, {
20939
21055
  kind: "mutation",
20940
21056
  auth: "admin"
@@ -24809,10 +24925,10 @@ var lawnMowerControlCapability = {
24809
24925
  *
24810
24926
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24811
24927
  * to receive an ordered list of candidate base URLs it should race
24812
- * on connect — LAN IPv4 first (lowest latency when on same network),
24813
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24814
- * race them with short timeouts and stick with the winner for the
24815
- * session.
24928
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24929
+ * when on the same network), then public hostname (if a tunnel is
24930
+ * up). The SDK can race them with short timeouts and stick with the
24931
+ * winner for the session.
24816
24932
  *
24817
24933
  * Why hub-only: agents are not directly addressable by the operator's
24818
24934
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24967,6 +25083,17 @@ var NotificationEndpointSchema = object({
24967
25083
  /** What the ranking currently resolves to (null when nothing is reachable). */
24968
25084
  resolved: string().nullable()
24969
25085
  });
25086
+ /**
25087
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
25088
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
25089
+ * currently expands to, so the UI can show the effective set either way.
25090
+ */
25091
+ var ViewerEndpointsSchema = object({
25092
+ /** The operator's explicit race set, or empty for AUTO. */
25093
+ baseUrls: array(string()).readonly(),
25094
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
25095
+ resolved: array(string()).readonly()
25096
+ });
24970
25097
  var AllowedAddressesSchema = object({
24971
25098
  /**
24972
25099
  * Allowlist of interface addresses operators have explicitly opted
@@ -24975,6 +25102,20 @@ var AllowedAddressesSchema = object({
24975
25102
  * Network Addresses admin page and persisted by the addon.
24976
25103
  */
24977
25104
  addresses: array(string()).readonly() });
25105
+ var TlsStatusSchema = object({
25106
+ mode: _enum([
25107
+ "generated",
25108
+ "uploaded",
25109
+ "disabled"
25110
+ ]),
25111
+ leafFingerprintSha256: string().nullable(),
25112
+ caFingerprintSha256: string().nullable(),
25113
+ validTo: string().nullable(),
25114
+ sans: array(string()),
25115
+ caCertPem: string().nullable(),
25116
+ reissueError: string().nullable(),
25117
+ restartRequired: boolean()
25118
+ });
24978
25119
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24979
25120
  /**
24980
25121
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24984,17 +25125,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24984
25125
  */
24985
25126
  port: number().int().min(1).max(65535).optional(),
24986
25127
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24987
- * candidate. Default `true`. */
25128
+ * candidate. Default `false` — loopback is not a client route. */
24988
25129
  includeLoopback: boolean().optional(),
24989
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24990
- * Default `false`. */
25130
+ /** Skip IPv6 entries. Default `false` the palette includes stable
25131
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
25132
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24991
25133
  ipv4Only: boolean().optional(),
24992
25134
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24993
25135
  * Pass `'https'` when the caller is itself loaded over HTTPS
24994
25136
  * to avoid mixed-content blocks in the browser. The public
24995
25137
  * tunnel always emits `https://` regardless. */
24996
25138
  scheme: _enum(["http", "https"]).optional()
24997
- }), 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" });
25139
+ }), 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, {
25140
+ kind: "mutation",
25141
+ auth: "admin"
25142
+ }), method(object({
25143
+ certPem: string().min(1),
25144
+ keyPem: string().min(1),
25145
+ caPem: string().optional()
25146
+ }), TlsStatusSchema, {
25147
+ kind: "mutation",
25148
+ auth: "admin"
25149
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
25150
+ kind: "mutation",
25151
+ auth: "admin"
25152
+ });
24998
25153
  var LockControlStatusSchema = object({
24999
25154
  /** Lifecycle state of the lock. `jammed` means the motor reported
25000
25155
  * failure to reach the target — operator intervention required. */
@@ -33021,6 +33176,12 @@ Object.freeze({
33021
33176
  addonId: null,
33022
33177
  access: "create"
33023
33178
  },
33179
+ "localNetwork.downloadCa": {
33180
+ capName: "local-network",
33181
+ capScope: "system",
33182
+ addonId: null,
33183
+ access: "view"
33184
+ },
33024
33185
  "localNetwork.getAllowedAddresses": {
33025
33186
  capName: "local-network",
33026
33187
  capScope: "system",
@@ -33045,18 +33206,42 @@ Object.freeze({
33045
33206
  addonId: null,
33046
33207
  access: "view"
33047
33208
  },
33209
+ "localNetwork.getTlsStatus": {
33210
+ capName: "local-network",
33211
+ capScope: "system",
33212
+ addonId: null,
33213
+ access: "view"
33214
+ },
33215
+ "localNetwork.getViewerEndpoints": {
33216
+ capName: "local-network",
33217
+ capScope: "system",
33218
+ addonId: null,
33219
+ access: "view"
33220
+ },
33048
33221
  "localNetwork.list": {
33049
33222
  capName: "local-network",
33050
33223
  capScope: "system",
33051
33224
  addonId: null,
33052
33225
  access: "view"
33053
33226
  },
33227
+ "localNetwork.regenerateCertificate": {
33228
+ capName: "local-network",
33229
+ capScope: "system",
33230
+ addonId: null,
33231
+ access: "create"
33232
+ },
33054
33233
  "localNetwork.resetAllowlistToBestMatch": {
33055
33234
  capName: "local-network",
33056
33235
  capScope: "system",
33057
33236
  addonId: null,
33058
33237
  access: "delete"
33059
33238
  },
33239
+ "localNetwork.revertToGeneratedCertificate": {
33240
+ capName: "local-network",
33241
+ capScope: "system",
33242
+ addonId: null,
33243
+ access: "create"
33244
+ },
33060
33245
  "localNetwork.setAllowedAddresses": {
33061
33246
  capName: "local-network",
33062
33247
  capScope: "system",
@@ -33069,6 +33254,18 @@ Object.freeze({
33069
33254
  addonId: null,
33070
33255
  access: "create"
33071
33256
  },
33257
+ "localNetwork.setViewerEndpoints": {
33258
+ capName: "local-network",
33259
+ capScope: "system",
33260
+ addonId: null,
33261
+ access: "create"
33262
+ },
33263
+ "localNetwork.uploadCertificate": {
33264
+ capName: "local-network",
33265
+ capScope: "system",
33266
+ addonId: null,
33267
+ access: "create"
33268
+ },
33072
33269
  "lockControl.lock": {
33073
33270
  capName: "lock-control",
33074
33271
  capScope: "device",
@@ -35949,6 +36146,12 @@ Object.freeze({
35949
36146
  addonId: null,
35950
36147
  access: "create"
35951
36148
  },
36149
+ "terminalSession.updateInstance": {
36150
+ capName: "terminal-session",
36151
+ capScope: "system",
36152
+ addonId: null,
36153
+ access: "create"
36154
+ },
35952
36155
  "terminalSession.writeInput": {
35953
36156
  capName: "terminal-session",
35954
36157
  capScope: "system",
@@ -38436,6 +38639,35 @@ Object.freeze(Object.fromEntries([{
38436
38639
  }]
38437
38640
  }].map((s) => [s.stepId, s.defaultModelId])));
38438
38641
  string().min(1);
38642
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38643
+ stepId: "face-embedding",
38644
+ key: "minLandmarkFaceSize",
38645
+ label: "Min face size for recognition (detection px)",
38646
+ 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.",
38647
+ type: "slider",
38648
+ min: 0,
38649
+ max: 64,
38650
+ step: 2,
38651
+ default: 24
38652
+ }];
38653
+ function clusterStepSettingKey(stepId, fieldKey) {
38654
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38655
+ }
38656
+ var ClusterSettingNumberSchema = number().finite();
38657
+ function readClusterStepSettings(config) {
38658
+ const out = {};
38659
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38660
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38661
+ const value = parsed.success ? parsed.data : field.default;
38662
+ const existing = out[field.stepId] ?? {};
38663
+ out[field.stepId] = {
38664
+ ...existing,
38665
+ [field.key]: value
38666
+ };
38667
+ }
38668
+ return out;
38669
+ }
38670
+ readClusterStepSettings({});
38439
38671
  object({
38440
38672
  /**
38441
38673
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -9004,6 +9004,15 @@ var LabelDefinitionSchema = object({
9004
9004
  description: string().optional(),
9005
9005
  icon: string().optional()
9006
9006
  });
9007
+ var ClassMapDefinitionSchema = object({
9008
+ mapping: record(string(), _enum([
9009
+ "person",
9010
+ "vehicle",
9011
+ "animal",
9012
+ "package"
9013
+ ])),
9014
+ preserveOriginal: boolean()
9015
+ });
9007
9016
  var MODEL_FORMATS = [
9008
9017
  "onnx",
9009
9018
  "coreml",
@@ -9182,7 +9191,13 @@ var ModelCatalogEntrySchema = object({
9182
9191
  * `id` stays the source of truth for resolution/download/persistence; grouping
9183
9192
  * is a presentation overlay resolved back to an `id`.
9184
9193
  */
9185
- group: ModelVariantGroupSchema.optional()
9194
+ group: ModelVariantGroupSchema.optional(),
9195
+ /**
9196
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
9197
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
9198
+ * labels already ARE the CamStack macros (Scrypted identity map).
9199
+ */
9200
+ classMap: ClassMapDefinitionSchema.optional()
9186
9201
  });
9187
9202
  var ConvertTargetSchema = discriminatedUnion("format", [object({
9188
9203
  format: literal("openvino"),
@@ -9211,7 +9226,8 @@ var ModelConvertMetadataSchema = object({
9211
9226
  "ocr",
9212
9227
  "segmentation"
9213
9228
  ]),
9214
- faceAlignment: boolean().optional()
9229
+ faceAlignment: boolean().optional(),
9230
+ classMap: ClassMapDefinitionSchema.optional()
9215
9231
  });
9216
9232
  var ConvertResultSchema = object({
9217
9233
  entry: ModelCatalogEntrySchema,
@@ -18504,6 +18520,33 @@ var NativeCropRefSchema = object({
18504
18520
  h: number()
18505
18521
  })
18506
18522
  });
18523
+ object({
18524
+ crop: object({
18525
+ left: number(),
18526
+ top: number(),
18527
+ width: number().positive(),
18528
+ height: number().positive()
18529
+ }).optional(),
18530
+ content: object({
18531
+ width: number().int().positive(),
18532
+ height: number().int().positive()
18533
+ }),
18534
+ fit: _enum(["stretch", "contain"]),
18535
+ format: _enum([
18536
+ "rgb",
18537
+ "gray",
18538
+ "jpeg"
18539
+ ])
18540
+ });
18541
+ var FrameRefSchema = object({
18542
+ registryId: string().min(1),
18543
+ id: string().min(1),
18544
+ width: number().int().positive(),
18545
+ height: number().int().positive(),
18546
+ format: _enum(["rgb", "gray"]),
18547
+ timestamp: number(),
18548
+ capturedAt: number().optional()
18549
+ });
18507
18550
  var ModelFormatSchema$1 = _enum([
18508
18551
  "onnx",
18509
18552
  "coreml",
@@ -18748,6 +18791,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
18748
18791
  steps: array(PipelineStepInputSchema).min(1),
18749
18792
  frame: FrameInputSchema.optional(),
18750
18793
  /**
18794
+ * Process-local lazy frame. Valid only when caller and provider resolve
18795
+ * in the same execution-group process; split/cross-node callers use
18796
+ * `frame`/`image` inline compatibility instead.
18797
+ */
18798
+ frameRef: FrameRefSchema.optional(),
18799
+ /**
18751
18800
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
18752
18801
  * the decoded pixels live in. One more member of the one-of
18753
18802
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -19043,7 +19092,10 @@ var NativeCropResultSchema = object({
19043
19092
  * Which source served this crop, so a quality-sensitive consumer (the native
19044
19093
  * `keyFrame`) can reject a degraded fallback:
19045
19094
  * - `native` — cut from the decode worker's retained NATIVE surface (the
19046
- * quality path).
19095
+ * quality path). A subject-tile serve is also native-resolution and stays
19096
+ * `native` here: the public enum cannot name `tile` without a breaking cap
19097
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
19098
+ * internal crop result (`nativeHits` vs `tileHits`).
19047
19099
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
19048
19100
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
19049
19101
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -19534,12 +19586,41 @@ var RunnerLocalLoadSchema = object({
19534
19586
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
19535
19587
  * working unchanged when they switch to reading from the runner cap.
19536
19588
  */
19589
+ var FrameLazyCountersSchema = object({
19590
+ framesDecoded: number(),
19591
+ framesAdmitted: number(),
19592
+ framesDroppedPixelFree: number(),
19593
+ viewsMaterialized: number(),
19594
+ viewsSkipped: number(),
19595
+ workerToRunnerBytes: number(),
19596
+ runnerToPoolRawBytes: number(),
19597
+ runnerToPoolJpegBytes: number(),
19598
+ onDemandFullFrameRequests: number(),
19599
+ onDemandCropRequests: number(),
19600
+ nativeHits: number(),
19601
+ nativeMisses: number(),
19602
+ tileHits: number(),
19603
+ tileMisses: number(),
19604
+ fallbackHits: number(),
19605
+ fallbackMisses: number(),
19606
+ retainedWritesAvoided: number(),
19607
+ residentRefs: number(),
19608
+ residentBytes: number(),
19609
+ releases: number(),
19610
+ evictions: number(),
19611
+ staleMisses: number()
19612
+ });
19613
+ var FrameLazyMetricsSchema = object({
19614
+ node: FrameLazyCountersSchema,
19615
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
19616
+ });
19537
19617
  var RunnerLocalMetricsSchema = object({
19538
19618
  nodeId: string(),
19539
19619
  activeCameras: number(),
19540
19620
  throttledCameras: number(),
19541
19621
  avgInferenceTimeMs: number(),
19542
- queueDepth: number()
19622
+ queueDepth: number(),
19623
+ frameLazy: FrameLazyMetricsSchema.optional()
19543
19624
  });
19544
19625
  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({
19545
19626
  handle: FrameHandleSchema,
@@ -20839,6 +20920,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
20839
20920
  location: StorageLocationSchema,
20840
20921
  relativePath: string()
20841
20922
  }), _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" });
20923
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20924
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20925
+ var ProfileSettingsBagSchema = record(string(), unknown());
20842
20926
  /**
20843
20927
  * A live terminal session hosted by the provider addon. Output and input do
20844
20928
  * NOT flow through the capability — they use the addon data plane
@@ -20868,7 +20952,14 @@ var TerminalSessionInfoSchema = object({
20868
20952
  var TerminalProfileInfoSchema = object({
20869
20953
  profileId: string(),
20870
20954
  label: string(),
20871
- description: string().optional()
20955
+ description: string().optional(),
20956
+ /** Spawn defaults the instance form copies on create. */
20957
+ executable: string().optional(),
20958
+ args: array(string()).readonly().optional(),
20959
+ cwd: string().optional(),
20960
+ environment: array(string()).readonly().optional(),
20961
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20962
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
20872
20963
  });
20873
20964
  /**
20874
20965
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -20881,7 +20972,12 @@ var TerminalInstanceInfoSchema = object({
20881
20972
  profileId: string(),
20882
20973
  profileLabel: string(),
20883
20974
  name: string(),
20884
- enabled: boolean()
20975
+ enabled: boolean(),
20976
+ executable: string(),
20977
+ args: array(string()).readonly(),
20978
+ cwd: string(),
20979
+ environment: array(string()).readonly(),
20980
+ profileSettings: ProfileSettingsBagSchema
20885
20981
  });
20886
20982
  var TerminalLegacyCameraSchema = object({
20887
20983
  stableId: string(),
@@ -20911,7 +21007,23 @@ var TerminalOutputBatchSchema = object({
20911
21007
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20912
21008
  targetNodeId: string().min(1),
20913
21009
  profileId: string().min(1),
20914
- name: string().trim().min(1).max(160).optional()
21010
+ name: string().trim().min(1).max(160).optional(),
21011
+ executable: string().max(1024).optional(),
21012
+ args: array(string().max(2048)).max(64).optional(),
21013
+ cwd: string().max(1024).optional(),
21014
+ environment: array(string().max(4096)).max(64).optional(),
21015
+ profileSettings: ProfileSettingsBagSchema.optional()
21016
+ }), TerminalInstanceInfoSchema, {
21017
+ kind: "mutation",
21018
+ auth: "admin"
21019
+ }), method(object({
21020
+ instanceId: string().min(1),
21021
+ name: string().trim().min(1).max(160).optional(),
21022
+ executable: string().max(1024).optional(),
21023
+ args: array(string().max(2048)).max(64).optional(),
21024
+ cwd: string().max(1024).optional(),
21025
+ environment: array(string().max(4096)).max(64).optional(),
21026
+ profileSettings: ProfileSettingsBagSchema.optional()
20915
21027
  }), TerminalInstanceInfoSchema, {
20916
21028
  kind: "mutation",
20917
21029
  auth: "admin"
@@ -20933,7 +21045,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20933
21045
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20934
21046
  profileId: string(),
20935
21047
  cols: number().int().positive(),
20936
- rows: number().int().positive()
21048
+ rows: number().int().positive(),
21049
+ executable: string().max(1024).optional(),
21050
+ args: array(string().max(2048)).max(64).optional(),
21051
+ cwd: string().max(1024).optional(),
21052
+ environment: array(string().max(4096)).max(64).optional()
20937
21053
  }), TerminalSessionInfoSchema, {
20938
21054
  kind: "mutation",
20939
21055
  auth: "admin"
@@ -24808,10 +24924,10 @@ var lawnMowerControlCapability = {
24808
24924
  *
24809
24925
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
24810
24926
  * to receive an ordered list of candidate base URLs it should race
24811
- * on connect — LAN IPv4 first (lowest latency when on same network),
24812
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
24813
- * race them with short timeouts and stick with the winner for the
24814
- * session.
24927
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24928
+ * when on the same network), then public hostname (if a tunnel is
24929
+ * up). The SDK can race them with short timeouts and stick with the
24930
+ * winner for the session.
24815
24931
  *
24816
24932
  * Why hub-only: agents are not directly addressable by the operator's
24817
24933
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24966,6 +25082,17 @@ var NotificationEndpointSchema = object({
24966
25082
  /** What the ranking currently resolves to (null when nothing is reachable). */
24967
25083
  resolved: string().nullable()
24968
25084
  });
25085
+ /**
25086
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
25087
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
25088
+ * currently expands to, so the UI can show the effective set either way.
25089
+ */
25090
+ var ViewerEndpointsSchema = object({
25091
+ /** The operator's explicit race set, or empty for AUTO. */
25092
+ baseUrls: array(string()).readonly(),
25093
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
25094
+ resolved: array(string()).readonly()
25095
+ });
24969
25096
  var AllowedAddressesSchema = object({
24970
25097
  /**
24971
25098
  * Allowlist of interface addresses operators have explicitly opted
@@ -24974,6 +25101,20 @@ var AllowedAddressesSchema = object({
24974
25101
  * Network Addresses admin page and persisted by the addon.
24975
25102
  */
24976
25103
  addresses: array(string()).readonly() });
25104
+ var TlsStatusSchema = object({
25105
+ mode: _enum([
25106
+ "generated",
25107
+ "uploaded",
25108
+ "disabled"
25109
+ ]),
25110
+ leafFingerprintSha256: string().nullable(),
25111
+ caFingerprintSha256: string().nullable(),
25112
+ validTo: string().nullable(),
25113
+ sans: array(string()),
25114
+ caCertPem: string().nullable(),
25115
+ reissueError: string().nullable(),
25116
+ restartRequired: boolean()
25117
+ });
24977
25118
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24978
25119
  /**
24979
25120
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24983,17 +25124,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24983
25124
  */
24984
25125
  port: number().int().min(1).max(65535).optional(),
24985
25126
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24986
- * candidate. Default `true`. */
25127
+ * candidate. Default `false` — loopback is not a client route. */
24987
25128
  includeLoopback: boolean().optional(),
24988
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24989
- * Default `false`. */
25129
+ /** Skip IPv6 entries. Default `false` the palette includes stable
25130
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
25131
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24990
25132
  ipv4Only: boolean().optional(),
24991
25133
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24992
25134
  * Pass `'https'` when the caller is itself loaded over HTTPS
24993
25135
  * to avoid mixed-content blocks in the browser. The public
24994
25136
  * tunnel always emits `https://` regardless. */
24995
25137
  scheme: _enum(["http", "https"]).optional()
24996
- }), 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" });
25138
+ }), 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, {
25139
+ kind: "mutation",
25140
+ auth: "admin"
25141
+ }), method(object({
25142
+ certPem: string().min(1),
25143
+ keyPem: string().min(1),
25144
+ caPem: string().optional()
25145
+ }), TlsStatusSchema, {
25146
+ kind: "mutation",
25147
+ auth: "admin"
25148
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
25149
+ kind: "mutation",
25150
+ auth: "admin"
25151
+ });
24997
25152
  var LockControlStatusSchema = object({
24998
25153
  /** Lifecycle state of the lock. `jammed` means the motor reported
24999
25154
  * failure to reach the target — operator intervention required. */
@@ -33020,6 +33175,12 @@ Object.freeze({
33020
33175
  addonId: null,
33021
33176
  access: "create"
33022
33177
  },
33178
+ "localNetwork.downloadCa": {
33179
+ capName: "local-network",
33180
+ capScope: "system",
33181
+ addonId: null,
33182
+ access: "view"
33183
+ },
33023
33184
  "localNetwork.getAllowedAddresses": {
33024
33185
  capName: "local-network",
33025
33186
  capScope: "system",
@@ -33044,18 +33205,42 @@ Object.freeze({
33044
33205
  addonId: null,
33045
33206
  access: "view"
33046
33207
  },
33208
+ "localNetwork.getTlsStatus": {
33209
+ capName: "local-network",
33210
+ capScope: "system",
33211
+ addonId: null,
33212
+ access: "view"
33213
+ },
33214
+ "localNetwork.getViewerEndpoints": {
33215
+ capName: "local-network",
33216
+ capScope: "system",
33217
+ addonId: null,
33218
+ access: "view"
33219
+ },
33047
33220
  "localNetwork.list": {
33048
33221
  capName: "local-network",
33049
33222
  capScope: "system",
33050
33223
  addonId: null,
33051
33224
  access: "view"
33052
33225
  },
33226
+ "localNetwork.regenerateCertificate": {
33227
+ capName: "local-network",
33228
+ capScope: "system",
33229
+ addonId: null,
33230
+ access: "create"
33231
+ },
33053
33232
  "localNetwork.resetAllowlistToBestMatch": {
33054
33233
  capName: "local-network",
33055
33234
  capScope: "system",
33056
33235
  addonId: null,
33057
33236
  access: "delete"
33058
33237
  },
33238
+ "localNetwork.revertToGeneratedCertificate": {
33239
+ capName: "local-network",
33240
+ capScope: "system",
33241
+ addonId: null,
33242
+ access: "create"
33243
+ },
33059
33244
  "localNetwork.setAllowedAddresses": {
33060
33245
  capName: "local-network",
33061
33246
  capScope: "system",
@@ -33068,6 +33253,18 @@ Object.freeze({
33068
33253
  addonId: null,
33069
33254
  access: "create"
33070
33255
  },
33256
+ "localNetwork.setViewerEndpoints": {
33257
+ capName: "local-network",
33258
+ capScope: "system",
33259
+ addonId: null,
33260
+ access: "create"
33261
+ },
33262
+ "localNetwork.uploadCertificate": {
33263
+ capName: "local-network",
33264
+ capScope: "system",
33265
+ addonId: null,
33266
+ access: "create"
33267
+ },
33071
33268
  "lockControl.lock": {
33072
33269
  capName: "lock-control",
33073
33270
  capScope: "device",
@@ -35948,6 +36145,12 @@ Object.freeze({
35948
36145
  addonId: null,
35949
36146
  access: "create"
35950
36147
  },
36148
+ "terminalSession.updateInstance": {
36149
+ capName: "terminal-session",
36150
+ capScope: "system",
36151
+ addonId: null,
36152
+ access: "create"
36153
+ },
35951
36154
  "terminalSession.writeInput": {
35952
36155
  capName: "terminal-session",
35953
36156
  capScope: "system",
@@ -38435,6 +38638,35 @@ Object.freeze(Object.fromEntries([{
38435
38638
  }]
38436
38639
  }].map((s) => [s.stepId, s.defaultModelId])));
38437
38640
  string().min(1);
38641
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38642
+ stepId: "face-embedding",
38643
+ key: "minLandmarkFaceSize",
38644
+ label: "Min face size for recognition (detection px)",
38645
+ 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.",
38646
+ type: "slider",
38647
+ min: 0,
38648
+ max: 64,
38649
+ step: 2,
38650
+ default: 24
38651
+ }];
38652
+ function clusterStepSettingKey(stepId, fieldKey) {
38653
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38654
+ }
38655
+ var ClusterSettingNumberSchema = number().finite();
38656
+ function readClusterStepSettings(config) {
38657
+ const out = {};
38658
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38659
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38660
+ const value = parsed.success ? parsed.data : field.default;
38661
+ const existing = out[field.stepId] ?? {};
38662
+ out[field.stepId] = {
38663
+ ...existing,
38664
+ [field.key]: value
38665
+ };
38666
+ }
38667
+ return out;
38668
+ }
38669
+ readClusterStepSettings({});
38438
38670
  object({
38439
38671
  /**
38440
38672
  * 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-rademacher",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",