@camstack/addon-static-turn 1.2.25 → 1.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.
@@ -8004,6 +8004,15 @@ var LabelDefinitionSchema = object({
8004
8004
  description: string().optional(),
8005
8005
  icon: string().optional()
8006
8006
  });
8007
+ var ClassMapDefinitionSchema = object({
8008
+ mapping: record(string(), _enum([
8009
+ "person",
8010
+ "vehicle",
8011
+ "animal",
8012
+ "package"
8013
+ ])),
8014
+ preserveOriginal: boolean()
8015
+ });
8007
8016
  var MODEL_FORMATS = [
8008
8017
  "onnx",
8009
8018
  "coreml",
@@ -8182,7 +8191,13 @@ var ModelCatalogEntrySchema = object({
8182
8191
  * `id` stays the source of truth for resolution/download/persistence; grouping
8183
8192
  * is a presentation overlay resolved back to an `id`.
8184
8193
  */
8185
- group: ModelVariantGroupSchema.optional()
8194
+ group: ModelVariantGroupSchema.optional(),
8195
+ /**
8196
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8197
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8198
+ * labels already ARE the CamStack macros (Scrypted identity map).
8199
+ */
8200
+ classMap: ClassMapDefinitionSchema.optional()
8186
8201
  });
8187
8202
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8188
8203
  format: literal("openvino"),
@@ -8211,7 +8226,8 @@ var ModelConvertMetadataSchema = object({
8211
8226
  "ocr",
8212
8227
  "segmentation"
8213
8228
  ]),
8214
- faceAlignment: boolean().optional()
8229
+ faceAlignment: boolean().optional(),
8230
+ classMap: ClassMapDefinitionSchema.optional()
8215
8231
  });
8216
8232
  var ConvertResultSchema = object({
8217
8233
  entry: ModelCatalogEntrySchema,
@@ -17202,6 +17218,33 @@ var NativeCropRefSchema = object({
17202
17218
  h: number()
17203
17219
  })
17204
17220
  });
17221
+ object({
17222
+ crop: object({
17223
+ left: number(),
17224
+ top: number(),
17225
+ width: number().positive(),
17226
+ height: number().positive()
17227
+ }).optional(),
17228
+ content: object({
17229
+ width: number().int().positive(),
17230
+ height: number().int().positive()
17231
+ }),
17232
+ fit: _enum(["stretch", "contain"]),
17233
+ format: _enum([
17234
+ "rgb",
17235
+ "gray",
17236
+ "jpeg"
17237
+ ])
17238
+ });
17239
+ var FrameRefSchema = object({
17240
+ registryId: string().min(1),
17241
+ id: string().min(1),
17242
+ width: number().int().positive(),
17243
+ height: number().int().positive(),
17244
+ format: _enum(["rgb", "gray"]),
17245
+ timestamp: number(),
17246
+ capturedAt: number().optional()
17247
+ });
17205
17248
  var ModelFormatSchema$1 = _enum([
17206
17249
  "onnx",
17207
17250
  "coreml",
@@ -17446,6 +17489,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17446
17489
  steps: array(PipelineStepInputSchema).min(1),
17447
17490
  frame: FrameInputSchema.optional(),
17448
17491
  /**
17492
+ * Process-local lazy frame. Valid only when caller and provider resolve
17493
+ * in the same execution-group process; split/cross-node callers use
17494
+ * `frame`/`image` inline compatibility instead.
17495
+ */
17496
+ frameRef: FrameRefSchema.optional(),
17497
+ /**
17449
17498
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17450
17499
  * the decoded pixels live in. One more member of the one-of
17451
17500
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -17701,7 +17750,10 @@ var NativeCropResultSchema = object({
17701
17750
  * Which source served this crop, so a quality-sensitive consumer (the native
17702
17751
  * `keyFrame`) can reject a degraded fallback:
17703
17752
  * - `native` — cut from the decode worker's retained NATIVE surface (the
17704
- * quality path).
17753
+ * quality path). A subject-tile serve is also native-resolution and stays
17754
+ * `native` here: the public enum cannot name `tile` without a breaking cap
17755
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
17756
+ * internal crop result (`nativeHits` vs `tileHits`).
17705
17757
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
17706
17758
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
17707
17759
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18192,12 +18244,41 @@ var RunnerLocalLoadSchema = object({
18192
18244
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18193
18245
  * working unchanged when they switch to reading from the runner cap.
18194
18246
  */
18247
+ var FrameLazyCountersSchema = object({
18248
+ framesDecoded: number(),
18249
+ framesAdmitted: number(),
18250
+ framesDroppedPixelFree: number(),
18251
+ viewsMaterialized: number(),
18252
+ viewsSkipped: number(),
18253
+ workerToRunnerBytes: number(),
18254
+ runnerToPoolRawBytes: number(),
18255
+ runnerToPoolJpegBytes: number(),
18256
+ onDemandFullFrameRequests: number(),
18257
+ onDemandCropRequests: number(),
18258
+ nativeHits: number(),
18259
+ nativeMisses: number(),
18260
+ tileHits: number(),
18261
+ tileMisses: number(),
18262
+ fallbackHits: number(),
18263
+ fallbackMisses: number(),
18264
+ retainedWritesAvoided: number(),
18265
+ residentRefs: number(),
18266
+ residentBytes: number(),
18267
+ releases: number(),
18268
+ evictions: number(),
18269
+ staleMisses: number()
18270
+ });
18271
+ var FrameLazyMetricsSchema = object({
18272
+ node: FrameLazyCountersSchema,
18273
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18274
+ });
18195
18275
  var RunnerLocalMetricsSchema = object({
18196
18276
  nodeId: string(),
18197
18277
  activeCameras: number(),
18198
18278
  throttledCameras: number(),
18199
18279
  avgInferenceTimeMs: number(),
18200
- queueDepth: number()
18280
+ queueDepth: number(),
18281
+ frameLazy: FrameLazyMetricsSchema.optional()
18201
18282
  });
18202
18283
  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({
18203
18284
  handle: FrameHandleSchema,
@@ -19497,6 +19578,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19497
19578
  location: StorageLocationSchema,
19498
19579
  relativePath: string()
19499
19580
  }), _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" });
19581
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19582
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19583
+ var ProfileSettingsBagSchema = record(string(), unknown());
19500
19584
  /**
19501
19585
  * A live terminal session hosted by the provider addon. Output and input do
19502
19586
  * NOT flow through the capability — they use the addon data plane
@@ -19526,7 +19610,14 @@ var TerminalSessionInfoSchema = object({
19526
19610
  var TerminalProfileInfoSchema = object({
19527
19611
  profileId: string(),
19528
19612
  label: string(),
19529
- description: string().optional()
19613
+ description: string().optional(),
19614
+ /** Spawn defaults the instance form copies on create. */
19615
+ executable: string().optional(),
19616
+ args: array(string()).readonly().optional(),
19617
+ cwd: string().optional(),
19618
+ environment: array(string()).readonly().optional(),
19619
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19620
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19530
19621
  });
19531
19622
  /**
19532
19623
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19539,7 +19630,12 @@ var TerminalInstanceInfoSchema = object({
19539
19630
  profileId: string(),
19540
19631
  profileLabel: string(),
19541
19632
  name: string(),
19542
- enabled: boolean()
19633
+ enabled: boolean(),
19634
+ executable: string(),
19635
+ args: array(string()).readonly(),
19636
+ cwd: string(),
19637
+ environment: array(string()).readonly(),
19638
+ profileSettings: ProfileSettingsBagSchema
19543
19639
  });
19544
19640
  var TerminalLegacyCameraSchema = object({
19545
19641
  stableId: string(),
@@ -19569,7 +19665,23 @@ var TerminalOutputBatchSchema = object({
19569
19665
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19570
19666
  targetNodeId: string().min(1),
19571
19667
  profileId: string().min(1),
19572
- name: string().trim().min(1).max(160).optional()
19668
+ name: string().trim().min(1).max(160).optional(),
19669
+ executable: string().max(1024).optional(),
19670
+ args: array(string().max(2048)).max(64).optional(),
19671
+ cwd: string().max(1024).optional(),
19672
+ environment: array(string().max(4096)).max(64).optional(),
19673
+ profileSettings: ProfileSettingsBagSchema.optional()
19674
+ }), TerminalInstanceInfoSchema, {
19675
+ kind: "mutation",
19676
+ auth: "admin"
19677
+ }), method(object({
19678
+ instanceId: string().min(1),
19679
+ name: string().trim().min(1).max(160).optional(),
19680
+ executable: string().max(1024).optional(),
19681
+ args: array(string().max(2048)).max(64).optional(),
19682
+ cwd: string().max(1024).optional(),
19683
+ environment: array(string().max(4096)).max(64).optional(),
19684
+ profileSettings: ProfileSettingsBagSchema.optional()
19573
19685
  }), TerminalInstanceInfoSchema, {
19574
19686
  kind: "mutation",
19575
19687
  auth: "admin"
@@ -19591,7 +19703,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19591
19703
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19592
19704
  profileId: string(),
19593
19705
  cols: number().int().positive(),
19594
- rows: number().int().positive()
19706
+ rows: number().int().positive(),
19707
+ executable: string().max(1024).optional(),
19708
+ args: array(string().max(2048)).max(64).optional(),
19709
+ cwd: string().max(1024).optional(),
19710
+ environment: array(string().max(4096)).max(64).optional()
19595
19711
  }), TerminalSessionInfoSchema, {
19596
19712
  kind: "mutation",
19597
19713
  auth: "admin"
@@ -22396,10 +22512,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
22396
22512
  *
22397
22513
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
22398
22514
  * to receive an ordered list of candidate base URLs it should race
22399
- * on connect — LAN IPv4 first (lowest latency when on same network),
22400
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
22401
- * race them with short timeouts and stick with the winner for the
22402
- * session.
22515
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
22516
+ * when on the same network), then public hostname (if a tunnel is
22517
+ * up). The SDK can race them with short timeouts and stick with the
22518
+ * winner for the session.
22403
22519
  *
22404
22520
  * Why hub-only: agents are not directly addressable by the operator's
22405
22521
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -22554,6 +22670,17 @@ var NotificationEndpointSchema = object({
22554
22670
  /** What the ranking currently resolves to (null when nothing is reachable). */
22555
22671
  resolved: string().nullable()
22556
22672
  });
22673
+ /**
22674
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
22675
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
22676
+ * currently expands to, so the UI can show the effective set either way.
22677
+ */
22678
+ var ViewerEndpointsSchema = object({
22679
+ /** The operator's explicit race set, or empty for AUTO. */
22680
+ baseUrls: array(string()).readonly(),
22681
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
22682
+ resolved: array(string()).readonly()
22683
+ });
22557
22684
  var AllowedAddressesSchema = object({
22558
22685
  /**
22559
22686
  * Allowlist of interface addresses operators have explicitly opted
@@ -22562,6 +22689,20 @@ var AllowedAddressesSchema = object({
22562
22689
  * Network Addresses admin page and persisted by the addon.
22563
22690
  */
22564
22691
  addresses: array(string()).readonly() });
22692
+ var TlsStatusSchema = object({
22693
+ mode: _enum([
22694
+ "generated",
22695
+ "uploaded",
22696
+ "disabled"
22697
+ ]),
22698
+ leafFingerprintSha256: string().nullable(),
22699
+ caFingerprintSha256: string().nullable(),
22700
+ validTo: string().nullable(),
22701
+ sans: array(string()),
22702
+ caCertPem: string().nullable(),
22703
+ reissueError: string().nullable(),
22704
+ restartRequired: boolean()
22705
+ });
22565
22706
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
22566
22707
  /**
22567
22708
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -22571,17 +22712,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
22571
22712
  */
22572
22713
  port: number().int().min(1).max(65535).optional(),
22573
22714
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
22574
- * candidate. Default `true`. */
22715
+ * candidate. Default `false` — loopback is not a client route. */
22575
22716
  includeLoopback: boolean().optional(),
22576
- /** Skip IPv6 entries. Some legacy clients can't parse them.
22577
- * Default `false`. */
22717
+ /** Skip IPv6 entries. Default `false` the palette includes stable
22718
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
22719
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
22578
22720
  ipv4Only: boolean().optional(),
22579
22721
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
22580
22722
  * Pass `'https'` when the caller is itself loaded over HTTPS
22581
22723
  * to avoid mixed-content blocks in the browser. The public
22582
22724
  * tunnel always emits `https://` regardless. */
22583
22725
  scheme: _enum(["http", "https"]).optional()
22584
- }), 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" });
22726
+ }), 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, {
22727
+ kind: "mutation",
22728
+ auth: "admin"
22729
+ }), method(object({
22730
+ certPem: string().min(1),
22731
+ keyPem: string().min(1),
22732
+ caPem: string().optional()
22733
+ }), TlsStatusSchema, {
22734
+ kind: "mutation",
22735
+ auth: "admin"
22736
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
22737
+ kind: "mutation",
22738
+ auth: "admin"
22739
+ });
22585
22740
  object({
22586
22741
  /** Lifecycle state of the lock. `jammed` means the motor reported
22587
22742
  * failure to reach the target — operator intervention required. */
@@ -28344,6 +28499,12 @@ Object.freeze({
28344
28499
  addonId: null,
28345
28500
  access: "create"
28346
28501
  },
28502
+ "localNetwork.downloadCa": {
28503
+ capName: "local-network",
28504
+ capScope: "system",
28505
+ addonId: null,
28506
+ access: "view"
28507
+ },
28347
28508
  "localNetwork.getAllowedAddresses": {
28348
28509
  capName: "local-network",
28349
28510
  capScope: "system",
@@ -28368,18 +28529,42 @@ Object.freeze({
28368
28529
  addonId: null,
28369
28530
  access: "view"
28370
28531
  },
28532
+ "localNetwork.getTlsStatus": {
28533
+ capName: "local-network",
28534
+ capScope: "system",
28535
+ addonId: null,
28536
+ access: "view"
28537
+ },
28538
+ "localNetwork.getViewerEndpoints": {
28539
+ capName: "local-network",
28540
+ capScope: "system",
28541
+ addonId: null,
28542
+ access: "view"
28543
+ },
28371
28544
  "localNetwork.list": {
28372
28545
  capName: "local-network",
28373
28546
  capScope: "system",
28374
28547
  addonId: null,
28375
28548
  access: "view"
28376
28549
  },
28550
+ "localNetwork.regenerateCertificate": {
28551
+ capName: "local-network",
28552
+ capScope: "system",
28553
+ addonId: null,
28554
+ access: "create"
28555
+ },
28377
28556
  "localNetwork.resetAllowlistToBestMatch": {
28378
28557
  capName: "local-network",
28379
28558
  capScope: "system",
28380
28559
  addonId: null,
28381
28560
  access: "delete"
28382
28561
  },
28562
+ "localNetwork.revertToGeneratedCertificate": {
28563
+ capName: "local-network",
28564
+ capScope: "system",
28565
+ addonId: null,
28566
+ access: "create"
28567
+ },
28383
28568
  "localNetwork.setAllowedAddresses": {
28384
28569
  capName: "local-network",
28385
28570
  capScope: "system",
@@ -28392,6 +28577,18 @@ Object.freeze({
28392
28577
  addonId: null,
28393
28578
  access: "create"
28394
28579
  },
28580
+ "localNetwork.setViewerEndpoints": {
28581
+ capName: "local-network",
28582
+ capScope: "system",
28583
+ addonId: null,
28584
+ access: "create"
28585
+ },
28586
+ "localNetwork.uploadCertificate": {
28587
+ capName: "local-network",
28588
+ capScope: "system",
28589
+ addonId: null,
28590
+ access: "create"
28591
+ },
28395
28592
  "lockControl.lock": {
28396
28593
  capName: "lock-control",
28397
28594
  capScope: "device",
@@ -31272,6 +31469,12 @@ Object.freeze({
31272
31469
  addonId: null,
31273
31470
  access: "create"
31274
31471
  },
31472
+ "terminalSession.updateInstance": {
31473
+ capName: "terminal-session",
31474
+ capScope: "system",
31475
+ addonId: null,
31476
+ access: "create"
31477
+ },
31275
31478
  "terminalSession.writeInput": {
31276
31479
  capName: "terminal-session",
31277
31480
  capScope: "system",
@@ -33759,6 +33962,35 @@ Object.freeze(Object.fromEntries([{
33759
33962
  }]
33760
33963
  }].map((s) => [s.stepId, s.defaultModelId])));
33761
33964
  string().min(1);
33965
+ var CLUSTER_STEP_SETTING_FIELDS = [{
33966
+ stepId: "face-embedding",
33967
+ key: "minLandmarkFaceSize",
33968
+ label: "Min face size for recognition (detection px)",
33969
+ 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.",
33970
+ type: "slider",
33971
+ min: 0,
33972
+ max: 64,
33973
+ step: 2,
33974
+ default: 24
33975
+ }];
33976
+ function clusterStepSettingKey(stepId, fieldKey) {
33977
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
33978
+ }
33979
+ var ClusterSettingNumberSchema = number().finite();
33980
+ function readClusterStepSettings(config) {
33981
+ const out = {};
33982
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
33983
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
33984
+ const value = parsed.success ? parsed.data : field.default;
33985
+ const existing = out[field.stepId] ?? {};
33986
+ out[field.stepId] = {
33987
+ ...existing,
33988
+ [field.key]: value
33989
+ };
33990
+ }
33991
+ return out;
33992
+ }
33993
+ readClusterStepSettings({});
33762
33994
  object({
33763
33995
  /**
33764
33996
  * Fraction of the box's own size added on EACH side before cutting.
@@ -8003,6 +8003,15 @@ var LabelDefinitionSchema = object({
8003
8003
  description: string().optional(),
8004
8004
  icon: string().optional()
8005
8005
  });
8006
+ var ClassMapDefinitionSchema = object({
8007
+ mapping: record(string(), _enum([
8008
+ "person",
8009
+ "vehicle",
8010
+ "animal",
8011
+ "package"
8012
+ ])),
8013
+ preserveOriginal: boolean()
8014
+ });
8006
8015
  var MODEL_FORMATS = [
8007
8016
  "onnx",
8008
8017
  "coreml",
@@ -8181,7 +8190,13 @@ var ModelCatalogEntrySchema = object({
8181
8190
  * `id` stays the source of truth for resolution/download/persistence; grouping
8182
8191
  * is a presentation overlay resolved back to an `id`.
8183
8192
  */
8184
- group: ModelVariantGroupSchema.optional()
8193
+ group: ModelVariantGroupSchema.optional(),
8194
+ /**
8195
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8196
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8197
+ * labels already ARE the CamStack macros (Scrypted identity map).
8198
+ */
8199
+ classMap: ClassMapDefinitionSchema.optional()
8185
8200
  });
8186
8201
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8187
8202
  format: literal("openvino"),
@@ -8210,7 +8225,8 @@ var ModelConvertMetadataSchema = object({
8210
8225
  "ocr",
8211
8226
  "segmentation"
8212
8227
  ]),
8213
- faceAlignment: boolean().optional()
8228
+ faceAlignment: boolean().optional(),
8229
+ classMap: ClassMapDefinitionSchema.optional()
8214
8230
  });
8215
8231
  var ConvertResultSchema = object({
8216
8232
  entry: ModelCatalogEntrySchema,
@@ -17201,6 +17217,33 @@ var NativeCropRefSchema = object({
17201
17217
  h: number()
17202
17218
  })
17203
17219
  });
17220
+ object({
17221
+ crop: object({
17222
+ left: number(),
17223
+ top: number(),
17224
+ width: number().positive(),
17225
+ height: number().positive()
17226
+ }).optional(),
17227
+ content: object({
17228
+ width: number().int().positive(),
17229
+ height: number().int().positive()
17230
+ }),
17231
+ fit: _enum(["stretch", "contain"]),
17232
+ format: _enum([
17233
+ "rgb",
17234
+ "gray",
17235
+ "jpeg"
17236
+ ])
17237
+ });
17238
+ var FrameRefSchema = object({
17239
+ registryId: string().min(1),
17240
+ id: string().min(1),
17241
+ width: number().int().positive(),
17242
+ height: number().int().positive(),
17243
+ format: _enum(["rgb", "gray"]),
17244
+ timestamp: number(),
17245
+ capturedAt: number().optional()
17246
+ });
17204
17247
  var ModelFormatSchema$1 = _enum([
17205
17248
  "onnx",
17206
17249
  "coreml",
@@ -17445,6 +17488,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17445
17488
  steps: array(PipelineStepInputSchema).min(1),
17446
17489
  frame: FrameInputSchema.optional(),
17447
17490
  /**
17491
+ * Process-local lazy frame. Valid only when caller and provider resolve
17492
+ * in the same execution-group process; split/cross-node callers use
17493
+ * `frame`/`image` inline compatibility instead.
17494
+ */
17495
+ frameRef: FrameRefSchema.optional(),
17496
+ /**
17448
17497
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17449
17498
  * the decoded pixels live in. One more member of the one-of
17450
17499
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -17700,7 +17749,10 @@ var NativeCropResultSchema = object({
17700
17749
  * Which source served this crop, so a quality-sensitive consumer (the native
17701
17750
  * `keyFrame`) can reject a degraded fallback:
17702
17751
  * - `native` — cut from the decode worker's retained NATIVE surface (the
17703
- * quality path).
17752
+ * quality path). A subject-tile serve is also native-resolution and stays
17753
+ * `native` here: the public enum cannot name `tile` without a breaking cap
17754
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
17755
+ * internal crop result (`nativeHits` vs `tileHits`).
17704
17756
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
17705
17757
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
17706
17758
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18191,12 +18243,41 @@ var RunnerLocalLoadSchema = object({
18191
18243
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18192
18244
  * working unchanged when they switch to reading from the runner cap.
18193
18245
  */
18246
+ var FrameLazyCountersSchema = object({
18247
+ framesDecoded: number(),
18248
+ framesAdmitted: number(),
18249
+ framesDroppedPixelFree: number(),
18250
+ viewsMaterialized: number(),
18251
+ viewsSkipped: number(),
18252
+ workerToRunnerBytes: number(),
18253
+ runnerToPoolRawBytes: number(),
18254
+ runnerToPoolJpegBytes: number(),
18255
+ onDemandFullFrameRequests: number(),
18256
+ onDemandCropRequests: number(),
18257
+ nativeHits: number(),
18258
+ nativeMisses: number(),
18259
+ tileHits: number(),
18260
+ tileMisses: number(),
18261
+ fallbackHits: number(),
18262
+ fallbackMisses: number(),
18263
+ retainedWritesAvoided: number(),
18264
+ residentRefs: number(),
18265
+ residentBytes: number(),
18266
+ releases: number(),
18267
+ evictions: number(),
18268
+ staleMisses: number()
18269
+ });
18270
+ var FrameLazyMetricsSchema = object({
18271
+ node: FrameLazyCountersSchema,
18272
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18273
+ });
18194
18274
  var RunnerLocalMetricsSchema = object({
18195
18275
  nodeId: string(),
18196
18276
  activeCameras: number(),
18197
18277
  throttledCameras: number(),
18198
18278
  avgInferenceTimeMs: number(),
18199
- queueDepth: number()
18279
+ queueDepth: number(),
18280
+ frameLazy: FrameLazyMetricsSchema.optional()
18200
18281
  });
18201
18282
  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({
18202
18283
  handle: FrameHandleSchema,
@@ -19496,6 +19577,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19496
19577
  location: StorageLocationSchema,
19497
19578
  relativePath: string()
19498
19579
  }), _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" });
19580
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19581
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19582
+ var ProfileSettingsBagSchema = record(string(), unknown());
19499
19583
  /**
19500
19584
  * A live terminal session hosted by the provider addon. Output and input do
19501
19585
  * NOT flow through the capability — they use the addon data plane
@@ -19525,7 +19609,14 @@ var TerminalSessionInfoSchema = object({
19525
19609
  var TerminalProfileInfoSchema = object({
19526
19610
  profileId: string(),
19527
19611
  label: string(),
19528
- description: string().optional()
19612
+ description: string().optional(),
19613
+ /** Spawn defaults the instance form copies on create. */
19614
+ executable: string().optional(),
19615
+ args: array(string()).readonly().optional(),
19616
+ cwd: string().optional(),
19617
+ environment: array(string()).readonly().optional(),
19618
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19619
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19529
19620
  });
19530
19621
  /**
19531
19622
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19538,7 +19629,12 @@ var TerminalInstanceInfoSchema = object({
19538
19629
  profileId: string(),
19539
19630
  profileLabel: string(),
19540
19631
  name: string(),
19541
- enabled: boolean()
19632
+ enabled: boolean(),
19633
+ executable: string(),
19634
+ args: array(string()).readonly(),
19635
+ cwd: string(),
19636
+ environment: array(string()).readonly(),
19637
+ profileSettings: ProfileSettingsBagSchema
19542
19638
  });
19543
19639
  var TerminalLegacyCameraSchema = object({
19544
19640
  stableId: string(),
@@ -19568,7 +19664,23 @@ var TerminalOutputBatchSchema = object({
19568
19664
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19569
19665
  targetNodeId: string().min(1),
19570
19666
  profileId: string().min(1),
19571
- name: string().trim().min(1).max(160).optional()
19667
+ name: string().trim().min(1).max(160).optional(),
19668
+ executable: string().max(1024).optional(),
19669
+ args: array(string().max(2048)).max(64).optional(),
19670
+ cwd: string().max(1024).optional(),
19671
+ environment: array(string().max(4096)).max(64).optional(),
19672
+ profileSettings: ProfileSettingsBagSchema.optional()
19673
+ }), TerminalInstanceInfoSchema, {
19674
+ kind: "mutation",
19675
+ auth: "admin"
19676
+ }), method(object({
19677
+ instanceId: string().min(1),
19678
+ name: string().trim().min(1).max(160).optional(),
19679
+ executable: string().max(1024).optional(),
19680
+ args: array(string().max(2048)).max(64).optional(),
19681
+ cwd: string().max(1024).optional(),
19682
+ environment: array(string().max(4096)).max(64).optional(),
19683
+ profileSettings: ProfileSettingsBagSchema.optional()
19572
19684
  }), TerminalInstanceInfoSchema, {
19573
19685
  kind: "mutation",
19574
19686
  auth: "admin"
@@ -19590,7 +19702,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19590
19702
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19591
19703
  profileId: string(),
19592
19704
  cols: number().int().positive(),
19593
- rows: number().int().positive()
19705
+ rows: number().int().positive(),
19706
+ executable: string().max(1024).optional(),
19707
+ args: array(string().max(2048)).max(64).optional(),
19708
+ cwd: string().max(1024).optional(),
19709
+ environment: array(string().max(4096)).max(64).optional()
19594
19710
  }), TerminalSessionInfoSchema, {
19595
19711
  kind: "mutation",
19596
19712
  auth: "admin"
@@ -22395,10 +22511,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
22395
22511
  *
22396
22512
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
22397
22513
  * to receive an ordered list of candidate base URLs it should race
22398
- * on connect — LAN IPv4 first (lowest latency when on same network),
22399
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
22400
- * race them with short timeouts and stick with the winner for the
22401
- * session.
22514
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
22515
+ * when on the same network), then public hostname (if a tunnel is
22516
+ * up). The SDK can race them with short timeouts and stick with the
22517
+ * winner for the session.
22402
22518
  *
22403
22519
  * Why hub-only: agents are not directly addressable by the operator's
22404
22520
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -22553,6 +22669,17 @@ var NotificationEndpointSchema = object({
22553
22669
  /** What the ranking currently resolves to (null when nothing is reachable). */
22554
22670
  resolved: string().nullable()
22555
22671
  });
22672
+ /**
22673
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
22674
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
22675
+ * currently expands to, so the UI can show the effective set either way.
22676
+ */
22677
+ var ViewerEndpointsSchema = object({
22678
+ /** The operator's explicit race set, or empty for AUTO. */
22679
+ baseUrls: array(string()).readonly(),
22680
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
22681
+ resolved: array(string()).readonly()
22682
+ });
22556
22683
  var AllowedAddressesSchema = object({
22557
22684
  /**
22558
22685
  * Allowlist of interface addresses operators have explicitly opted
@@ -22561,6 +22688,20 @@ var AllowedAddressesSchema = object({
22561
22688
  * Network Addresses admin page and persisted by the addon.
22562
22689
  */
22563
22690
  addresses: array(string()).readonly() });
22691
+ var TlsStatusSchema = object({
22692
+ mode: _enum([
22693
+ "generated",
22694
+ "uploaded",
22695
+ "disabled"
22696
+ ]),
22697
+ leafFingerprintSha256: string().nullable(),
22698
+ caFingerprintSha256: string().nullable(),
22699
+ validTo: string().nullable(),
22700
+ sans: array(string()),
22701
+ caCertPem: string().nullable(),
22702
+ reissueError: string().nullable(),
22703
+ restartRequired: boolean()
22704
+ });
22564
22705
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
22565
22706
  /**
22566
22707
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -22570,17 +22711,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
22570
22711
  */
22571
22712
  port: number().int().min(1).max(65535).optional(),
22572
22713
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
22573
- * candidate. Default `true`. */
22714
+ * candidate. Default `false` — loopback is not a client route. */
22574
22715
  includeLoopback: boolean().optional(),
22575
- /** Skip IPv6 entries. Some legacy clients can't parse them.
22576
- * Default `false`. */
22716
+ /** Skip IPv6 entries. Default `false` the palette includes stable
22717
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
22718
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
22577
22719
  ipv4Only: boolean().optional(),
22578
22720
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
22579
22721
  * Pass `'https'` when the caller is itself loaded over HTTPS
22580
22722
  * to avoid mixed-content blocks in the browser. The public
22581
22723
  * tunnel always emits `https://` regardless. */
22582
22724
  scheme: _enum(["http", "https"]).optional()
22583
- }), 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" });
22725
+ }), 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, {
22726
+ kind: "mutation",
22727
+ auth: "admin"
22728
+ }), method(object({
22729
+ certPem: string().min(1),
22730
+ keyPem: string().min(1),
22731
+ caPem: string().optional()
22732
+ }), TlsStatusSchema, {
22733
+ kind: "mutation",
22734
+ auth: "admin"
22735
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
22736
+ kind: "mutation",
22737
+ auth: "admin"
22738
+ });
22584
22739
  object({
22585
22740
  /** Lifecycle state of the lock. `jammed` means the motor reported
22586
22741
  * failure to reach the target — operator intervention required. */
@@ -28343,6 +28498,12 @@ Object.freeze({
28343
28498
  addonId: null,
28344
28499
  access: "create"
28345
28500
  },
28501
+ "localNetwork.downloadCa": {
28502
+ capName: "local-network",
28503
+ capScope: "system",
28504
+ addonId: null,
28505
+ access: "view"
28506
+ },
28346
28507
  "localNetwork.getAllowedAddresses": {
28347
28508
  capName: "local-network",
28348
28509
  capScope: "system",
@@ -28367,18 +28528,42 @@ Object.freeze({
28367
28528
  addonId: null,
28368
28529
  access: "view"
28369
28530
  },
28531
+ "localNetwork.getTlsStatus": {
28532
+ capName: "local-network",
28533
+ capScope: "system",
28534
+ addonId: null,
28535
+ access: "view"
28536
+ },
28537
+ "localNetwork.getViewerEndpoints": {
28538
+ capName: "local-network",
28539
+ capScope: "system",
28540
+ addonId: null,
28541
+ access: "view"
28542
+ },
28370
28543
  "localNetwork.list": {
28371
28544
  capName: "local-network",
28372
28545
  capScope: "system",
28373
28546
  addonId: null,
28374
28547
  access: "view"
28375
28548
  },
28549
+ "localNetwork.regenerateCertificate": {
28550
+ capName: "local-network",
28551
+ capScope: "system",
28552
+ addonId: null,
28553
+ access: "create"
28554
+ },
28376
28555
  "localNetwork.resetAllowlistToBestMatch": {
28377
28556
  capName: "local-network",
28378
28557
  capScope: "system",
28379
28558
  addonId: null,
28380
28559
  access: "delete"
28381
28560
  },
28561
+ "localNetwork.revertToGeneratedCertificate": {
28562
+ capName: "local-network",
28563
+ capScope: "system",
28564
+ addonId: null,
28565
+ access: "create"
28566
+ },
28382
28567
  "localNetwork.setAllowedAddresses": {
28383
28568
  capName: "local-network",
28384
28569
  capScope: "system",
@@ -28391,6 +28576,18 @@ Object.freeze({
28391
28576
  addonId: null,
28392
28577
  access: "create"
28393
28578
  },
28579
+ "localNetwork.setViewerEndpoints": {
28580
+ capName: "local-network",
28581
+ capScope: "system",
28582
+ addonId: null,
28583
+ access: "create"
28584
+ },
28585
+ "localNetwork.uploadCertificate": {
28586
+ capName: "local-network",
28587
+ capScope: "system",
28588
+ addonId: null,
28589
+ access: "create"
28590
+ },
28394
28591
  "lockControl.lock": {
28395
28592
  capName: "lock-control",
28396
28593
  capScope: "device",
@@ -31271,6 +31468,12 @@ Object.freeze({
31271
31468
  addonId: null,
31272
31469
  access: "create"
31273
31470
  },
31471
+ "terminalSession.updateInstance": {
31472
+ capName: "terminal-session",
31473
+ capScope: "system",
31474
+ addonId: null,
31475
+ access: "create"
31476
+ },
31274
31477
  "terminalSession.writeInput": {
31275
31478
  capName: "terminal-session",
31276
31479
  capScope: "system",
@@ -33758,6 +33961,35 @@ Object.freeze(Object.fromEntries([{
33758
33961
  }]
33759
33962
  }].map((s) => [s.stepId, s.defaultModelId])));
33760
33963
  string().min(1);
33964
+ var CLUSTER_STEP_SETTING_FIELDS = [{
33965
+ stepId: "face-embedding",
33966
+ key: "minLandmarkFaceSize",
33967
+ label: "Min face size for recognition (detection px)",
33968
+ 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.",
33969
+ type: "slider",
33970
+ min: 0,
33971
+ max: 64,
33972
+ step: 2,
33973
+ default: 24
33974
+ }];
33975
+ function clusterStepSettingKey(stepId, fieldKey) {
33976
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
33977
+ }
33978
+ var ClusterSettingNumberSchema = number().finite();
33979
+ function readClusterStepSettings(config) {
33980
+ const out = {};
33981
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
33982
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
33983
+ const value = parsed.success ? parsed.data : field.default;
33984
+ const existing = out[field.stepId] ?? {};
33985
+ out[field.stepId] = {
33986
+ ...existing,
33987
+ [field.key]: value
33988
+ };
33989
+ }
33990
+ return out;
33991
+ }
33992
+ readClusterStepSettings({});
33761
33993
  object({
33762
33994
  /**
33763
33995
  * 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-static-turn",
3
- "version": "1.2.25",
3
+ "version": "1.2.26",
4
4
  "description": "Static / self-hosted (coturn) TURN provider for CamStack",
5
5
  "keywords": [
6
6
  "camstack",