@camstack/addon-export-alexa 1.2.31 → 1.2.33

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.
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  //#endregion
27
27
  let node_crypto = require("node:crypto");
28
28
  node_crypto = __toESM(node_crypto);
29
- //#region ../types/dist/event-category-XfKNtfCc.mjs
29
+ //#region ../types/dist/event-category-CIa_iT6b.mjs
30
30
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
31
31
  EventCategory["SystemBoot"] = "system.boot";
32
32
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -42,6 +42,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
42
42
  */
43
43
  EventCategory["SystemRestartCompleted"] = "system.restart-completed";
44
44
  /**
45
+ * The hub reissued its own TLS certificate at boot (`ensureTlsCert`).
46
+ * Emitted only when the material on disk actually changed, so an
47
+ * operator who trusted the old certificate by hand is told rather than
48
+ * discovering it as a browser error. Payload `TlsCertChangedPayload`.
49
+ *
50
+ * Rule: docs/decisions/adr-0227-*.md
51
+ */
52
+ EventCategory["SystemTlsCertChanged"] = "system.tls-cert-changed";
53
+ /**
45
54
  * A newer addon or server-root package version was found by the
46
55
  * authoritative registry check. Emitted once when any observed
47
56
  * `latestVersion` changes (or a package/node first appears behind);
@@ -8233,6 +8242,15 @@ var LabelDefinitionSchema = object({
8233
8242
  description: string().optional(),
8234
8243
  icon: string().optional()
8235
8244
  });
8245
+ var ClassMapDefinitionSchema = object({
8246
+ mapping: record(string(), _enum([
8247
+ "person",
8248
+ "vehicle",
8249
+ "animal",
8250
+ "package"
8251
+ ])),
8252
+ preserveOriginal: boolean()
8253
+ });
8236
8254
  var MODEL_FORMATS = [
8237
8255
  "onnx",
8238
8256
  "coreml",
@@ -8411,7 +8429,13 @@ var ModelCatalogEntrySchema = object({
8411
8429
  * `id` stays the source of truth for resolution/download/persistence; grouping
8412
8430
  * is a presentation overlay resolved back to an `id`.
8413
8431
  */
8414
- group: ModelVariantGroupSchema.optional()
8432
+ group: ModelVariantGroupSchema.optional(),
8433
+ /**
8434
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8435
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8436
+ * labels already ARE the CamStack macros (Scrypted identity map).
8437
+ */
8438
+ classMap: ClassMapDefinitionSchema.optional()
8415
8439
  });
8416
8440
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8417
8441
  format: literal("openvino"),
@@ -8440,7 +8464,8 @@ var ModelConvertMetadataSchema = object({
8440
8464
  "ocr",
8441
8465
  "segmentation"
8442
8466
  ]),
8443
- faceAlignment: boolean().optional()
8467
+ faceAlignment: boolean().optional(),
8468
+ classMap: ClassMapDefinitionSchema.optional()
8444
8469
  });
8445
8470
  var ConvertResultSchema = object({
8446
8471
  entry: ModelCatalogEntrySchema,
@@ -17510,6 +17535,33 @@ var NativeCropRefSchema = object({
17510
17535
  h: number()
17511
17536
  })
17512
17537
  });
17538
+ object({
17539
+ crop: object({
17540
+ left: number(),
17541
+ top: number(),
17542
+ width: number().positive(),
17543
+ height: number().positive()
17544
+ }).optional(),
17545
+ content: object({
17546
+ width: number().int().positive(),
17547
+ height: number().int().positive()
17548
+ }),
17549
+ fit: _enum(["stretch", "contain"]),
17550
+ format: _enum([
17551
+ "rgb",
17552
+ "gray",
17553
+ "jpeg"
17554
+ ])
17555
+ });
17556
+ var FrameRefSchema = object({
17557
+ registryId: string().min(1),
17558
+ id: string().min(1),
17559
+ width: number().int().positive(),
17560
+ height: number().int().positive(),
17561
+ format: _enum(["rgb", "gray"]),
17562
+ timestamp: number(),
17563
+ capturedAt: number().optional()
17564
+ });
17513
17565
  var ModelFormatSchema$1 = _enum([
17514
17566
  "onnx",
17515
17567
  "coreml",
@@ -17754,6 +17806,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17754
17806
  steps: array(PipelineStepInputSchema).min(1),
17755
17807
  frame: FrameInputSchema.optional(),
17756
17808
  /**
17809
+ * Process-local lazy frame. Valid only when caller and provider resolve
17810
+ * in the same execution-group process; split/cross-node callers use
17811
+ * `frame`/`image` inline compatibility instead.
17812
+ */
17813
+ frameRef: FrameRefSchema.optional(),
17814
+ /**
17757
17815
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17758
17816
  * the decoded pixels live in. One more member of the one-of
17759
17817
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18009,7 +18067,10 @@ var NativeCropResultSchema = object({
18009
18067
  * Which source served this crop, so a quality-sensitive consumer (the native
18010
18068
  * `keyFrame`) can reject a degraded fallback:
18011
18069
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18012
- * quality path).
18070
+ * quality path). A subject-tile serve is also native-resolution and stays
18071
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18072
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18073
+ * internal crop result (`nativeHits` vs `tileHits`).
18013
18074
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18014
18075
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18015
18076
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18500,12 +18561,41 @@ var RunnerLocalLoadSchema = object({
18500
18561
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18501
18562
  * working unchanged when they switch to reading from the runner cap.
18502
18563
  */
18564
+ var FrameLazyCountersSchema = object({
18565
+ framesDecoded: number(),
18566
+ framesAdmitted: number(),
18567
+ framesDroppedPixelFree: number(),
18568
+ viewsMaterialized: number(),
18569
+ viewsSkipped: number(),
18570
+ workerToRunnerBytes: number(),
18571
+ runnerToPoolRawBytes: number(),
18572
+ runnerToPoolJpegBytes: number(),
18573
+ onDemandFullFrameRequests: number(),
18574
+ onDemandCropRequests: number(),
18575
+ nativeHits: number(),
18576
+ nativeMisses: number(),
18577
+ tileHits: number(),
18578
+ tileMisses: number(),
18579
+ fallbackHits: number(),
18580
+ fallbackMisses: number(),
18581
+ retainedWritesAvoided: number(),
18582
+ residentRefs: number(),
18583
+ residentBytes: number(),
18584
+ releases: number(),
18585
+ evictions: number(),
18586
+ staleMisses: number()
18587
+ });
18588
+ var FrameLazyMetricsSchema = object({
18589
+ node: FrameLazyCountersSchema,
18590
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18591
+ });
18503
18592
  var RunnerLocalMetricsSchema = object({
18504
18593
  nodeId: string(),
18505
18594
  activeCameras: number(),
18506
18595
  throttledCameras: number(),
18507
18596
  avgInferenceTimeMs: number(),
18508
- queueDepth: number()
18597
+ queueDepth: number(),
18598
+ frameLazy: FrameLazyMetricsSchema.optional()
18509
18599
  });
18510
18600
  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({
18511
18601
  handle: FrameHandleSchema,
@@ -19805,6 +19895,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19805
19895
  location: StorageLocationSchema,
19806
19896
  relativePath: string()
19807
19897
  }), _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" });
19898
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19899
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19900
+ var ProfileSettingsBagSchema = record(string(), unknown());
19808
19901
  /**
19809
19902
  * A live terminal session hosted by the provider addon. Output and input do
19810
19903
  * NOT flow through the capability — they use the addon data plane
@@ -19834,7 +19927,14 @@ var TerminalSessionInfoSchema = object({
19834
19927
  var TerminalProfileInfoSchema = object({
19835
19928
  profileId: string(),
19836
19929
  label: string(),
19837
- description: string().optional()
19930
+ description: string().optional(),
19931
+ /** Spawn defaults the instance form copies on create. */
19932
+ executable: string().optional(),
19933
+ args: array(string()).readonly().optional(),
19934
+ cwd: string().optional(),
19935
+ environment: array(string()).readonly().optional(),
19936
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19937
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19838
19938
  });
19839
19939
  /**
19840
19940
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19847,7 +19947,12 @@ var TerminalInstanceInfoSchema = object({
19847
19947
  profileId: string(),
19848
19948
  profileLabel: string(),
19849
19949
  name: string(),
19850
- enabled: boolean()
19950
+ enabled: boolean(),
19951
+ executable: string(),
19952
+ args: array(string()).readonly(),
19953
+ cwd: string(),
19954
+ environment: array(string()).readonly(),
19955
+ profileSettings: ProfileSettingsBagSchema
19851
19956
  });
19852
19957
  var TerminalLegacyCameraSchema = object({
19853
19958
  stableId: string(),
@@ -19877,7 +19982,23 @@ var TerminalOutputBatchSchema = object({
19877
19982
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19878
19983
  targetNodeId: string().min(1),
19879
19984
  profileId: string().min(1),
19880
- name: string().trim().min(1).max(160).optional()
19985
+ name: string().trim().min(1).max(160).optional(),
19986
+ executable: string().max(1024).optional(),
19987
+ args: array(string().max(2048)).max(64).optional(),
19988
+ cwd: string().max(1024).optional(),
19989
+ environment: array(string().max(4096)).max(64).optional(),
19990
+ profileSettings: ProfileSettingsBagSchema.optional()
19991
+ }), TerminalInstanceInfoSchema, {
19992
+ kind: "mutation",
19993
+ auth: "admin"
19994
+ }), method(object({
19995
+ instanceId: string().min(1),
19996
+ name: string().trim().min(1).max(160).optional(),
19997
+ executable: string().max(1024).optional(),
19998
+ args: array(string().max(2048)).max(64).optional(),
19999
+ cwd: string().max(1024).optional(),
20000
+ environment: array(string().max(4096)).max(64).optional(),
20001
+ profileSettings: ProfileSettingsBagSchema.optional()
19881
20002
  }), TerminalInstanceInfoSchema, {
19882
20003
  kind: "mutation",
19883
20004
  auth: "admin"
@@ -19899,7 +20020,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19899
20020
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19900
20021
  profileId: string(),
19901
20022
  cols: number().int().positive(),
19902
- rows: number().int().positive()
20023
+ rows: number().int().positive(),
20024
+ executable: string().max(1024).optional(),
20025
+ args: array(string().max(2048)).max(64).optional(),
20026
+ cwd: string().max(1024).optional(),
20027
+ environment: array(string().max(4096)).max(64).optional()
19903
20028
  }), TerminalSessionInfoSchema, {
19904
20029
  kind: "mutation",
19905
20030
  auth: "admin"
@@ -22681,10 +22806,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
22681
22806
  *
22682
22807
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
22683
22808
  * to receive an ordered list of candidate base URLs it should race
22684
- * on connect — LAN IPv4 first (lowest latency when on same network),
22685
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
22686
- * race them with short timeouts and stick with the winner for the
22687
- * session.
22809
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
22810
+ * when on the same network), then public hostname (if a tunnel is
22811
+ * up). The SDK can race them with short timeouts and stick with the
22812
+ * winner for the session.
22688
22813
  *
22689
22814
  * Why hub-only: agents are not directly addressable by the operator's
22690
22815
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -22839,6 +22964,17 @@ var NotificationEndpointSchema = object({
22839
22964
  /** What the ranking currently resolves to (null when nothing is reachable). */
22840
22965
  resolved: string().nullable()
22841
22966
  });
22967
+ /**
22968
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
22969
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
22970
+ * currently expands to, so the UI can show the effective set either way.
22971
+ */
22972
+ var ViewerEndpointsSchema = object({
22973
+ /** The operator's explicit race set, or empty for AUTO. */
22974
+ baseUrls: array(string()).readonly(),
22975
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
22976
+ resolved: array(string()).readonly()
22977
+ });
22842
22978
  var AllowedAddressesSchema = object({
22843
22979
  /**
22844
22980
  * Allowlist of interface addresses operators have explicitly opted
@@ -22847,6 +22983,20 @@ var AllowedAddressesSchema = object({
22847
22983
  * Network Addresses admin page and persisted by the addon.
22848
22984
  */
22849
22985
  addresses: array(string()).readonly() });
22986
+ var TlsStatusSchema = object({
22987
+ mode: _enum([
22988
+ "generated",
22989
+ "uploaded",
22990
+ "disabled"
22991
+ ]),
22992
+ leafFingerprintSha256: string().nullable(),
22993
+ caFingerprintSha256: string().nullable(),
22994
+ validTo: string().nullable(),
22995
+ sans: array(string()),
22996
+ caCertPem: string().nullable(),
22997
+ reissueError: string().nullable(),
22998
+ restartRequired: boolean()
22999
+ });
22850
23000
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
22851
23001
  /**
22852
23002
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -22856,17 +23006,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
22856
23006
  */
22857
23007
  port: number().int().min(1).max(65535).optional(),
22858
23008
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
22859
- * candidate. Default `true`. */
23009
+ * candidate. Default `false` — loopback is not a client route. */
22860
23010
  includeLoopback: boolean().optional(),
22861
- /** Skip IPv6 entries. Some legacy clients can't parse them.
22862
- * Default `false`. */
23011
+ /** Skip IPv6 entries. Default `false` the palette includes stable
23012
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
23013
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
22863
23014
  ipv4Only: boolean().optional(),
22864
23015
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
22865
23016
  * Pass `'https'` when the caller is itself loaded over HTTPS
22866
23017
  * to avoid mixed-content blocks in the browser. The public
22867
23018
  * tunnel always emits `https://` regardless. */
22868
23019
  scheme: _enum(["http", "https"]).optional()
22869
- }), 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" });
23020
+ }), 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, {
23021
+ kind: "mutation",
23022
+ auth: "admin"
23023
+ }), method(object({
23024
+ certPem: string().min(1),
23025
+ keyPem: string().min(1),
23026
+ caPem: string().optional()
23027
+ }), TlsStatusSchema, {
23028
+ kind: "mutation",
23029
+ auth: "admin"
23030
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
23031
+ kind: "mutation",
23032
+ auth: "admin"
23033
+ });
22870
23034
  object({
22871
23035
  /** Lifecycle state of the lock. `jammed` means the motor reported
22872
23036
  * failure to reach the target — operator intervention required. */
@@ -28629,6 +28793,12 @@ Object.freeze({
28629
28793
  addonId: null,
28630
28794
  access: "create"
28631
28795
  },
28796
+ "localNetwork.downloadCa": {
28797
+ capName: "local-network",
28798
+ capScope: "system",
28799
+ addonId: null,
28800
+ access: "view"
28801
+ },
28632
28802
  "localNetwork.getAllowedAddresses": {
28633
28803
  capName: "local-network",
28634
28804
  capScope: "system",
@@ -28653,18 +28823,42 @@ Object.freeze({
28653
28823
  addonId: null,
28654
28824
  access: "view"
28655
28825
  },
28826
+ "localNetwork.getTlsStatus": {
28827
+ capName: "local-network",
28828
+ capScope: "system",
28829
+ addonId: null,
28830
+ access: "view"
28831
+ },
28832
+ "localNetwork.getViewerEndpoints": {
28833
+ capName: "local-network",
28834
+ capScope: "system",
28835
+ addonId: null,
28836
+ access: "view"
28837
+ },
28656
28838
  "localNetwork.list": {
28657
28839
  capName: "local-network",
28658
28840
  capScope: "system",
28659
28841
  addonId: null,
28660
28842
  access: "view"
28661
28843
  },
28844
+ "localNetwork.regenerateCertificate": {
28845
+ capName: "local-network",
28846
+ capScope: "system",
28847
+ addonId: null,
28848
+ access: "create"
28849
+ },
28662
28850
  "localNetwork.resetAllowlistToBestMatch": {
28663
28851
  capName: "local-network",
28664
28852
  capScope: "system",
28665
28853
  addonId: null,
28666
28854
  access: "delete"
28667
28855
  },
28856
+ "localNetwork.revertToGeneratedCertificate": {
28857
+ capName: "local-network",
28858
+ capScope: "system",
28859
+ addonId: null,
28860
+ access: "create"
28861
+ },
28668
28862
  "localNetwork.setAllowedAddresses": {
28669
28863
  capName: "local-network",
28670
28864
  capScope: "system",
@@ -28677,6 +28871,18 @@ Object.freeze({
28677
28871
  addonId: null,
28678
28872
  access: "create"
28679
28873
  },
28874
+ "localNetwork.setViewerEndpoints": {
28875
+ capName: "local-network",
28876
+ capScope: "system",
28877
+ addonId: null,
28878
+ access: "create"
28879
+ },
28880
+ "localNetwork.uploadCertificate": {
28881
+ capName: "local-network",
28882
+ capScope: "system",
28883
+ addonId: null,
28884
+ access: "create"
28885
+ },
28680
28886
  "lockControl.lock": {
28681
28887
  capName: "lock-control",
28682
28888
  capScope: "device",
@@ -31557,6 +31763,12 @@ Object.freeze({
31557
31763
  addonId: null,
31558
31764
  access: "create"
31559
31765
  },
31766
+ "terminalSession.updateInstance": {
31767
+ capName: "terminal-session",
31768
+ capScope: "system",
31769
+ addonId: null,
31770
+ access: "create"
31771
+ },
31560
31772
  "terminalSession.writeInput": {
31561
31773
  capName: "terminal-session",
31562
31774
  capScope: "system",
@@ -34044,6 +34256,35 @@ Object.freeze(Object.fromEntries([{
34044
34256
  }]
34045
34257
  }].map((s) => [s.stepId, s.defaultModelId])));
34046
34258
  string().min(1);
34259
+ var CLUSTER_STEP_SETTING_FIELDS = [{
34260
+ stepId: "face-embedding",
34261
+ key: "minLandmarkFaceSize",
34262
+ label: "Min face size for recognition (detection px)",
34263
+ 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.",
34264
+ type: "slider",
34265
+ min: 0,
34266
+ max: 64,
34267
+ step: 2,
34268
+ default: 24
34269
+ }];
34270
+ function clusterStepSettingKey(stepId, fieldKey) {
34271
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
34272
+ }
34273
+ var ClusterSettingNumberSchema = number().finite();
34274
+ function readClusterStepSettings(config) {
34275
+ const out = {};
34276
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
34277
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
34278
+ const value = parsed.success ? parsed.data : field.default;
34279
+ const existing = out[field.stepId] ?? {};
34280
+ out[field.stepId] = {
34281
+ ...existing,
34282
+ [field.key]: value
34283
+ };
34284
+ }
34285
+ return out;
34286
+ }
34287
+ readClusterStepSettings({});
34047
34288
  object({
34048
34289
  /**
34049
34290
  * Fraction of the box's own size added on EACH side before cutting.
@@ -1,5 +1,5 @@
1
1
  import * as crypto$1 from "node:crypto";
2
- //#region ../types/dist/event-category-XfKNtfCc.mjs
2
+ //#region ../types/dist/event-category-CIa_iT6b.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -15,6 +15,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
15
15
  */
16
16
  EventCategory["SystemRestartCompleted"] = "system.restart-completed";
17
17
  /**
18
+ * The hub reissued its own TLS certificate at boot (`ensureTlsCert`).
19
+ * Emitted only when the material on disk actually changed, so an
20
+ * operator who trusted the old certificate by hand is told rather than
21
+ * discovering it as a browser error. Payload `TlsCertChangedPayload`.
22
+ *
23
+ * Rule: docs/decisions/adr-0227-*.md
24
+ */
25
+ EventCategory["SystemTlsCertChanged"] = "system.tls-cert-changed";
26
+ /**
18
27
  * A newer addon or server-root package version was found by the
19
28
  * authoritative registry check. Emitted once when any observed
20
29
  * `latestVersion` changes (or a package/node first appears behind);
@@ -8206,6 +8215,15 @@ var LabelDefinitionSchema = object({
8206
8215
  description: string().optional(),
8207
8216
  icon: string().optional()
8208
8217
  });
8218
+ var ClassMapDefinitionSchema = object({
8219
+ mapping: record(string(), _enum([
8220
+ "person",
8221
+ "vehicle",
8222
+ "animal",
8223
+ "package"
8224
+ ])),
8225
+ preserveOriginal: boolean()
8226
+ });
8209
8227
  var MODEL_FORMATS = [
8210
8228
  "onnx",
8211
8229
  "coreml",
@@ -8384,7 +8402,13 @@ var ModelCatalogEntrySchema = object({
8384
8402
  * `id` stays the source of truth for resolution/download/persistence; grouping
8385
8403
  * is a presentation overlay resolved back to an `id`.
8386
8404
  */
8387
- group: ModelVariantGroupSchema.optional()
8405
+ group: ModelVariantGroupSchema.optional(),
8406
+ /**
8407
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8408
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8409
+ * labels already ARE the CamStack macros (Scrypted identity map).
8410
+ */
8411
+ classMap: ClassMapDefinitionSchema.optional()
8388
8412
  });
8389
8413
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8390
8414
  format: literal("openvino"),
@@ -8413,7 +8437,8 @@ var ModelConvertMetadataSchema = object({
8413
8437
  "ocr",
8414
8438
  "segmentation"
8415
8439
  ]),
8416
- faceAlignment: boolean().optional()
8440
+ faceAlignment: boolean().optional(),
8441
+ classMap: ClassMapDefinitionSchema.optional()
8417
8442
  });
8418
8443
  var ConvertResultSchema = object({
8419
8444
  entry: ModelCatalogEntrySchema,
@@ -17483,6 +17508,33 @@ var NativeCropRefSchema = object({
17483
17508
  h: number()
17484
17509
  })
17485
17510
  });
17511
+ object({
17512
+ crop: object({
17513
+ left: number(),
17514
+ top: number(),
17515
+ width: number().positive(),
17516
+ height: number().positive()
17517
+ }).optional(),
17518
+ content: object({
17519
+ width: number().int().positive(),
17520
+ height: number().int().positive()
17521
+ }),
17522
+ fit: _enum(["stretch", "contain"]),
17523
+ format: _enum([
17524
+ "rgb",
17525
+ "gray",
17526
+ "jpeg"
17527
+ ])
17528
+ });
17529
+ var FrameRefSchema = object({
17530
+ registryId: string().min(1),
17531
+ id: string().min(1),
17532
+ width: number().int().positive(),
17533
+ height: number().int().positive(),
17534
+ format: _enum(["rgb", "gray"]),
17535
+ timestamp: number(),
17536
+ capturedAt: number().optional()
17537
+ });
17486
17538
  var ModelFormatSchema$1 = _enum([
17487
17539
  "onnx",
17488
17540
  "coreml",
@@ -17727,6 +17779,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17727
17779
  steps: array(PipelineStepInputSchema).min(1),
17728
17780
  frame: FrameInputSchema.optional(),
17729
17781
  /**
17782
+ * Process-local lazy frame. Valid only when caller and provider resolve
17783
+ * in the same execution-group process; split/cross-node callers use
17784
+ * `frame`/`image` inline compatibility instead.
17785
+ */
17786
+ frameRef: FrameRefSchema.optional(),
17787
+ /**
17730
17788
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17731
17789
  * the decoded pixels live in. One more member of the one-of
17732
17790
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -17982,7 +18040,10 @@ var NativeCropResultSchema = object({
17982
18040
  * Which source served this crop, so a quality-sensitive consumer (the native
17983
18041
  * `keyFrame`) can reject a degraded fallback:
17984
18042
  * - `native` — cut from the decode worker's retained NATIVE surface (the
17985
- * quality path).
18043
+ * quality path). A subject-tile serve is also native-resolution and stays
18044
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18045
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18046
+ * internal crop result (`nativeHits` vs `tileHits`).
17986
18047
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
17987
18048
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
17988
18049
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18473,12 +18534,41 @@ var RunnerLocalLoadSchema = object({
18473
18534
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18474
18535
  * working unchanged when they switch to reading from the runner cap.
18475
18536
  */
18537
+ var FrameLazyCountersSchema = object({
18538
+ framesDecoded: number(),
18539
+ framesAdmitted: number(),
18540
+ framesDroppedPixelFree: number(),
18541
+ viewsMaterialized: number(),
18542
+ viewsSkipped: number(),
18543
+ workerToRunnerBytes: number(),
18544
+ runnerToPoolRawBytes: number(),
18545
+ runnerToPoolJpegBytes: number(),
18546
+ onDemandFullFrameRequests: number(),
18547
+ onDemandCropRequests: number(),
18548
+ nativeHits: number(),
18549
+ nativeMisses: number(),
18550
+ tileHits: number(),
18551
+ tileMisses: number(),
18552
+ fallbackHits: number(),
18553
+ fallbackMisses: number(),
18554
+ retainedWritesAvoided: number(),
18555
+ residentRefs: number(),
18556
+ residentBytes: number(),
18557
+ releases: number(),
18558
+ evictions: number(),
18559
+ staleMisses: number()
18560
+ });
18561
+ var FrameLazyMetricsSchema = object({
18562
+ node: FrameLazyCountersSchema,
18563
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18564
+ });
18476
18565
  var RunnerLocalMetricsSchema = object({
18477
18566
  nodeId: string(),
18478
18567
  activeCameras: number(),
18479
18568
  throttledCameras: number(),
18480
18569
  avgInferenceTimeMs: number(),
18481
- queueDepth: number()
18570
+ queueDepth: number(),
18571
+ frameLazy: FrameLazyMetricsSchema.optional()
18482
18572
  });
18483
18573
  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({
18484
18574
  handle: FrameHandleSchema,
@@ -19778,6 +19868,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19778
19868
  location: StorageLocationSchema,
19779
19869
  relativePath: string()
19780
19870
  }), _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" });
19871
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19872
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19873
+ var ProfileSettingsBagSchema = record(string(), unknown());
19781
19874
  /**
19782
19875
  * A live terminal session hosted by the provider addon. Output and input do
19783
19876
  * NOT flow through the capability — they use the addon data plane
@@ -19807,7 +19900,14 @@ var TerminalSessionInfoSchema = object({
19807
19900
  var TerminalProfileInfoSchema = object({
19808
19901
  profileId: string(),
19809
19902
  label: string(),
19810
- description: string().optional()
19903
+ description: string().optional(),
19904
+ /** Spawn defaults the instance form copies on create. */
19905
+ executable: string().optional(),
19906
+ args: array(string()).readonly().optional(),
19907
+ cwd: string().optional(),
19908
+ environment: array(string()).readonly().optional(),
19909
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
19910
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19811
19911
  });
19812
19912
  /**
19813
19913
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19820,7 +19920,12 @@ var TerminalInstanceInfoSchema = object({
19820
19920
  profileId: string(),
19821
19921
  profileLabel: string(),
19822
19922
  name: string(),
19823
- enabled: boolean()
19923
+ enabled: boolean(),
19924
+ executable: string(),
19925
+ args: array(string()).readonly(),
19926
+ cwd: string(),
19927
+ environment: array(string()).readonly(),
19928
+ profileSettings: ProfileSettingsBagSchema
19824
19929
  });
19825
19930
  var TerminalLegacyCameraSchema = object({
19826
19931
  stableId: string(),
@@ -19850,7 +19955,23 @@ var TerminalOutputBatchSchema = object({
19850
19955
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19851
19956
  targetNodeId: string().min(1),
19852
19957
  profileId: string().min(1),
19853
- name: string().trim().min(1).max(160).optional()
19958
+ name: string().trim().min(1).max(160).optional(),
19959
+ executable: string().max(1024).optional(),
19960
+ args: array(string().max(2048)).max(64).optional(),
19961
+ cwd: string().max(1024).optional(),
19962
+ environment: array(string().max(4096)).max(64).optional(),
19963
+ profileSettings: ProfileSettingsBagSchema.optional()
19964
+ }), TerminalInstanceInfoSchema, {
19965
+ kind: "mutation",
19966
+ auth: "admin"
19967
+ }), method(object({
19968
+ instanceId: string().min(1),
19969
+ name: string().trim().min(1).max(160).optional(),
19970
+ executable: string().max(1024).optional(),
19971
+ args: array(string().max(2048)).max(64).optional(),
19972
+ cwd: string().max(1024).optional(),
19973
+ environment: array(string().max(4096)).max(64).optional(),
19974
+ profileSettings: ProfileSettingsBagSchema.optional()
19854
19975
  }), TerminalInstanceInfoSchema, {
19855
19976
  kind: "mutation",
19856
19977
  auth: "admin"
@@ -19872,7 +19993,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19872
19993
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19873
19994
  profileId: string(),
19874
19995
  cols: number().int().positive(),
19875
- rows: number().int().positive()
19996
+ rows: number().int().positive(),
19997
+ executable: string().max(1024).optional(),
19998
+ args: array(string().max(2048)).max(64).optional(),
19999
+ cwd: string().max(1024).optional(),
20000
+ environment: array(string().max(4096)).max(64).optional()
19876
20001
  }), TerminalSessionInfoSchema, {
19877
20002
  kind: "mutation",
19878
20003
  auth: "admin"
@@ -22654,10 +22779,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
22654
22779
  *
22655
22780
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
22656
22781
  * to receive an ordered list of candidate base URLs it should race
22657
- * on connect — LAN IPv4 first (lowest latency when on same network),
22658
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
22659
- * race them with short timeouts and stick with the winner for the
22660
- * session.
22782
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
22783
+ * when on the same network), then public hostname (if a tunnel is
22784
+ * up). The SDK can race them with short timeouts and stick with the
22785
+ * winner for the session.
22661
22786
  *
22662
22787
  * Why hub-only: agents are not directly addressable by the operator's
22663
22788
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -22812,6 +22937,17 @@ var NotificationEndpointSchema = object({
22812
22937
  /** What the ranking currently resolves to (null when nothing is reachable). */
22813
22938
  resolved: string().nullable()
22814
22939
  });
22940
+ /**
22941
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
22942
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
22943
+ * currently expands to, so the UI can show the effective set either way.
22944
+ */
22945
+ var ViewerEndpointsSchema = object({
22946
+ /** The operator's explicit race set, or empty for AUTO. */
22947
+ baseUrls: array(string()).readonly(),
22948
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
22949
+ resolved: array(string()).readonly()
22950
+ });
22815
22951
  var AllowedAddressesSchema = object({
22816
22952
  /**
22817
22953
  * Allowlist of interface addresses operators have explicitly opted
@@ -22820,6 +22956,20 @@ var AllowedAddressesSchema = object({
22820
22956
  * Network Addresses admin page and persisted by the addon.
22821
22957
  */
22822
22958
  addresses: array(string()).readonly() });
22959
+ var TlsStatusSchema = object({
22960
+ mode: _enum([
22961
+ "generated",
22962
+ "uploaded",
22963
+ "disabled"
22964
+ ]),
22965
+ leafFingerprintSha256: string().nullable(),
22966
+ caFingerprintSha256: string().nullable(),
22967
+ validTo: string().nullable(),
22968
+ sans: array(string()),
22969
+ caCertPem: string().nullable(),
22970
+ reissueError: string().nullable(),
22971
+ restartRequired: boolean()
22972
+ });
22823
22973
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
22824
22974
  /**
22825
22975
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -22829,17 +22979,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
22829
22979
  */
22830
22980
  port: number().int().min(1).max(65535).optional(),
22831
22981
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
22832
- * candidate. Default `true`. */
22982
+ * candidate. Default `false` — loopback is not a client route. */
22833
22983
  includeLoopback: boolean().optional(),
22834
- /** Skip IPv6 entries. Some legacy clients can't parse them.
22835
- * Default `false`. */
22984
+ /** Skip IPv6 entries. Default `false` the palette includes stable
22985
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
22986
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
22836
22987
  ipv4Only: boolean().optional(),
22837
22988
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
22838
22989
  * Pass `'https'` when the caller is itself loaded over HTTPS
22839
22990
  * to avoid mixed-content blocks in the browser. The public
22840
22991
  * tunnel always emits `https://` regardless. */
22841
22992
  scheme: _enum(["http", "https"]).optional()
22842
- }), 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" });
22993
+ }), 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, {
22994
+ kind: "mutation",
22995
+ auth: "admin"
22996
+ }), method(object({
22997
+ certPem: string().min(1),
22998
+ keyPem: string().min(1),
22999
+ caPem: string().optional()
23000
+ }), TlsStatusSchema, {
23001
+ kind: "mutation",
23002
+ auth: "admin"
23003
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
23004
+ kind: "mutation",
23005
+ auth: "admin"
23006
+ });
22843
23007
  object({
22844
23008
  /** Lifecycle state of the lock. `jammed` means the motor reported
22845
23009
  * failure to reach the target — operator intervention required. */
@@ -28602,6 +28766,12 @@ Object.freeze({
28602
28766
  addonId: null,
28603
28767
  access: "create"
28604
28768
  },
28769
+ "localNetwork.downloadCa": {
28770
+ capName: "local-network",
28771
+ capScope: "system",
28772
+ addonId: null,
28773
+ access: "view"
28774
+ },
28605
28775
  "localNetwork.getAllowedAddresses": {
28606
28776
  capName: "local-network",
28607
28777
  capScope: "system",
@@ -28626,18 +28796,42 @@ Object.freeze({
28626
28796
  addonId: null,
28627
28797
  access: "view"
28628
28798
  },
28799
+ "localNetwork.getTlsStatus": {
28800
+ capName: "local-network",
28801
+ capScope: "system",
28802
+ addonId: null,
28803
+ access: "view"
28804
+ },
28805
+ "localNetwork.getViewerEndpoints": {
28806
+ capName: "local-network",
28807
+ capScope: "system",
28808
+ addonId: null,
28809
+ access: "view"
28810
+ },
28629
28811
  "localNetwork.list": {
28630
28812
  capName: "local-network",
28631
28813
  capScope: "system",
28632
28814
  addonId: null,
28633
28815
  access: "view"
28634
28816
  },
28817
+ "localNetwork.regenerateCertificate": {
28818
+ capName: "local-network",
28819
+ capScope: "system",
28820
+ addonId: null,
28821
+ access: "create"
28822
+ },
28635
28823
  "localNetwork.resetAllowlistToBestMatch": {
28636
28824
  capName: "local-network",
28637
28825
  capScope: "system",
28638
28826
  addonId: null,
28639
28827
  access: "delete"
28640
28828
  },
28829
+ "localNetwork.revertToGeneratedCertificate": {
28830
+ capName: "local-network",
28831
+ capScope: "system",
28832
+ addonId: null,
28833
+ access: "create"
28834
+ },
28641
28835
  "localNetwork.setAllowedAddresses": {
28642
28836
  capName: "local-network",
28643
28837
  capScope: "system",
@@ -28650,6 +28844,18 @@ Object.freeze({
28650
28844
  addonId: null,
28651
28845
  access: "create"
28652
28846
  },
28847
+ "localNetwork.setViewerEndpoints": {
28848
+ capName: "local-network",
28849
+ capScope: "system",
28850
+ addonId: null,
28851
+ access: "create"
28852
+ },
28853
+ "localNetwork.uploadCertificate": {
28854
+ capName: "local-network",
28855
+ capScope: "system",
28856
+ addonId: null,
28857
+ access: "create"
28858
+ },
28653
28859
  "lockControl.lock": {
28654
28860
  capName: "lock-control",
28655
28861
  capScope: "device",
@@ -31530,6 +31736,12 @@ Object.freeze({
31530
31736
  addonId: null,
31531
31737
  access: "create"
31532
31738
  },
31739
+ "terminalSession.updateInstance": {
31740
+ capName: "terminal-session",
31741
+ capScope: "system",
31742
+ addonId: null,
31743
+ access: "create"
31744
+ },
31533
31745
  "terminalSession.writeInput": {
31534
31746
  capName: "terminal-session",
31535
31747
  capScope: "system",
@@ -34017,6 +34229,35 @@ Object.freeze(Object.fromEntries([{
34017
34229
  }]
34018
34230
  }].map((s) => [s.stepId, s.defaultModelId])));
34019
34231
  string().min(1);
34232
+ var CLUSTER_STEP_SETTING_FIELDS = [{
34233
+ stepId: "face-embedding",
34234
+ key: "minLandmarkFaceSize",
34235
+ label: "Min face size for recognition (detection px)",
34236
+ 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.",
34237
+ type: "slider",
34238
+ min: 0,
34239
+ max: 64,
34240
+ step: 2,
34241
+ default: 24
34242
+ }];
34243
+ function clusterStepSettingKey(stepId, fieldKey) {
34244
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
34245
+ }
34246
+ var ClusterSettingNumberSchema = number().finite();
34247
+ function readClusterStepSettings(config) {
34248
+ const out = {};
34249
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
34250
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
34251
+ const value = parsed.success ? parsed.data : field.default;
34252
+ const existing = out[field.stepId] ?? {};
34253
+ out[field.stepId] = {
34254
+ ...existing,
34255
+ [field.key]: value
34256
+ };
34257
+ }
34258
+ return out;
34259
+ }
34260
+ readClusterStepSettings({});
34020
34261
  object({
34021
34262
  /**
34022
34263
  * 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-export-alexa",
3
- "version": "1.2.31",
3
+ "version": "1.2.33",
4
4
  "description": "Alexa Smart Home Skill export — hub-side OAuth provider + directive handler. The companion AWS Lambda forwards Alexa directives to this addon's /addon/export-alexa/directive endpoint.",
5
5
  "keywords": [
6
6
  "camstack",