@camstack/system 1.2.355 → 1.2.357

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 (73) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/autotrack/index.js +1 -1
  10. package/dist/builtins/autotrack/index.mjs +1 -1
  11. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  13. package/dist/builtins/calendars/calendars.addon.js +1 -1
  14. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  15. package/dist/builtins/camera-grid/grid-activity-mirror.d.ts +12 -2
  16. package/dist/builtins/camera-grid/index.js +15 -3
  17. package/dist/builtins/camera-grid/index.mjs +15 -3
  18. package/dist/builtins/composer/composer.addon.js +2 -2
  19. package/dist/builtins/composer/composer.addon.mjs +2 -2
  20. package/dist/builtins/console-logging/index.js +1 -1
  21. package/dist/builtins/console-logging/index.mjs +1 -1
  22. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  23. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  24. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  25. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  26. package/dist/builtins/hub-forwarder/index.js +1 -1
  27. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  28. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  29. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  30. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  31. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  32. package/dist/builtins/local-network/local-network.addon.d.ts +7 -0
  33. package/dist/builtins/local-network/local-network.addon.js +43 -24
  34. package/dist/builtins/local-network/local-network.addon.mjs +43 -24
  35. package/dist/builtins/loki-logging/index.js +1 -1
  36. package/dist/builtins/loki-logging/index.mjs +1 -1
  37. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  38. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  39. package/dist/builtins/platform-probe/index.js +1 -1
  40. package/dist/builtins/platform-probe/index.mjs +1 -1
  41. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  42. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  43. package/dist/builtins/snapshot/index.js +1 -1
  44. package/dist/builtins/snapshot/index.mjs +1 -1
  45. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  46. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  47. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  48. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  51. package/dist/builtins/system-config/system-config.addon.js +1 -1
  52. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  53. package/dist/builtins/winston-logging/index.js +1 -1
  54. package/dist/builtins/winston-logging/index.mjs +1 -1
  55. package/dist/{child-cap-dispatch-DMx2axev.mjs → child-cap-dispatch-BcRHQBKW.mjs} +1 -1
  56. package/dist/{child-cap-dispatch-CqV-7-QZ.js → child-cap-dispatch-wbIQJctP.js} +1 -1
  57. package/dist/{composition-sources-Dpl1G0Gr.mjs → composition-sources-BBfqepyT.mjs} +1 -1
  58. package/dist/{composition-sources-Bk-MjK1D.js → composition-sources-CeO0K2cl.js} +1 -1
  59. package/dist/{dist-OCi0K-iM.mjs → dist-B7WRgEZY.mjs} +10 -1
  60. package/dist/{dist-BWicEEVA.js → dist-CFVOy8VT.js} +10 -1
  61. package/dist/index.js +22 -11
  62. package/dist/index.mjs +11 -12
  63. package/dist/kernel/config-schema.d.ts +0 -2
  64. package/dist/{retired-settings-keys-DLJ7MvIB.js → retired-settings-keys-CRlTzxaS.js} +1 -1
  65. package/dist/{retired-settings-keys-TDzxE6GA.mjs → retired-settings-keys-DKRjfz0U.mjs} +1 -1
  66. package/dist/tls/boot-tls.d.ts +29 -0
  67. package/dist/tls/https-listener.d.ts +30 -0
  68. package/dist/tls/index.d.ts +4 -1
  69. package/dist/tls/tls-actions.d.ts +29 -0
  70. package/dist/tls/tls-status.d.ts +12 -1
  71. package/dist/{tls-ue_Xefmv.js → tls-CCMX7MjX.js} +319 -54
  72. package/dist/{tls-DTlVWwAI.mjs → tls-CJHogwTl.mjs} +246 -53
  73. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_child_cap_dispatch = require("./child-cap-dispatch-CqV-7-QZ.js");
2
+ const require_child_cap_dispatch = require("./child-cap-dispatch-wbIQJctP.js");
3
3
  const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
4
4
  let node_path = require("node:path");
5
5
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { $t as RUNNER_RSS_BUDGET_ENV, Ft as resolveAddonClass, H as createUdsLoggerWithControl, Pt as installManifestNativeDeps, U as LocalChildClient, _t as getWorkerNativeCapSnapshot, f as installManifestSystemDeps, fn as startRunnerHeapWatch, g as createUdsAddonContext, gt as getWorkerNativeCapProvider, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, wn as emitHeapDiagnosticReport, xt as validateProviderRegistrations, yt as setWorkerNativeCapsChangeListener } from "./child-cap-dispatch-DMx2axev.mjs";
1
+ import { $t as RUNNER_RSS_BUDGET_ENV, Ft as resolveAddonClass, H as createUdsLoggerWithControl, Pt as installManifestNativeDeps, U as LocalChildClient, _t as getWorkerNativeCapSnapshot, f as installManifestSystemDeps, fn as startRunnerHeapWatch, g as createUdsAddonContext, gt as getWorkerNativeCapProvider, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, wn as emitHeapDiagnosticReport, xt as validateProviderRegistrations, yt as setWorkerNativeCapsChangeListener } from "./child-cap-dispatch-BcRHQBKW.mjs";
2
2
  import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
3
3
  import { register } from "node:module";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, Qn as BaseAddon, U as addonPagesCapability, Zn as errMsg } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, Qn as BaseAddon, U as addonPagesCapability, Zn as errMsg } from "../../dist-B7WRgEZY.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let node_crypto = require("node:crypto");
9
9
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, G as addonWidgetsCapability, Qn as BaseAddon, Zn as errMsg } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, G as addonWidgetsCapability, Qn as BaseAddon, Zn as errMsg } from "../../dist-B7WRgEZY.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import * as path$1 from "node:path";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  //#region src/builtins/alerts/device-label.ts
8
8
  /**
9
9
  * Operator-facing device label for alert messages.
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, K as alertsCapability, Qn as BaseAddon, Zn as errMsg, cr as createEvent, n as AlertSchema } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, K as alertsCapability, Qn as BaseAddon, Zn as errMsg, cr as createEvent, n as AlertSchema } from "../../dist-B7WRgEZY.mjs";
2
2
  //#region src/builtins/alerts/device-label.ts
3
3
  /**
4
4
  * Operator-facing device label for alert messages.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  //#region src/builtins/autotrack/autotrack-config.ts
8
8
  var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
9
9
  deadZoneFraction: .5,
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, Qn as BaseAddon, S as FIRST_LEVEL_MACRO_CLASSES, Y as bareAddonId, Zn as errMsg, ln as ptzAutotrackCapability, mr as isEvent } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, Qn as BaseAddon, S as FIRST_LEVEL_MACRO_CLASSES, Y as bareAddonId, Zn as errMsg, ln as ptzAutotrackCapability, mr as isEvent } from "../../dist-B7WRgEZY.mjs";
2
2
  //#region src/builtins/autotrack/autotrack-config.ts
3
3
  var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
4
4
  deadZoneFraction: .5,
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let buffer = require("buffer");
9
9
  let node_fs_promises = require("node:fs/promises");
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, En as storageOccupancyCapability, J as backupCapability, Qn as BaseAddon, Sr as toNodeId, Yt as mayWriteToLocation, g as DATABASE_SNAPSHOT_SUFFIX, hr as nodePin } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, En as storageOccupancyCapability, J as backupCapability, Qn as BaseAddon, Sr as toNodeId, Yt as mayWriteToLocation, g as DATABASE_SNAPSHOT_SUFFIX, hr as nodePin } from "../../dist-B7WRgEZY.mjs";
2
2
  import { randomBytes, randomUUID } from "node:crypto";
3
3
  import { Buffer as Buffer$1 } from "buffer";
4
4
  import * as fsp from "node:fs/promises";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
8
8
  let zod = require("zod");
9
9
  //#region src/builtins/calendars/calendar-color.ts
@@ -1,4 +1,4 @@
1
- import { $ as calendarsCapability, Qn as BaseAddon, p as CalendarPreferencesSchema } from "../../dist-OCi0K-iM.mjs";
1
+ import { $ as calendarsCapability, Qn as BaseAddon, p as CalendarPreferencesSchema } from "../../dist-B7WRgEZY.mjs";
2
2
  import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/builtins/calendars/calendar-color.ts
@@ -1,14 +1,24 @@
1
1
  /** The grid's own motion answer, in the shape the `motion` cap publishes. */
2
2
  export interface GridMotionState {
3
3
  readonly detected: boolean;
4
- /** Ms epoch of the most recent rising edge on ANY source. Null if never. */
4
+ /** Ms epoch of the most recent rising edge on ANY source (never a heartbeat). Null if never. */
5
5
  readonly lastDetectedAt: number | null;
6
6
  }
7
7
  export declare class GridActivityMirror {
8
8
  private readonly motion;
9
9
  private readonly audio;
10
10
  private lastDetectedAt;
11
- /** One source's motion push. `detected: false` is as important as `true`. */
11
+ /**
12
+ * One source's motion push. `detected: false` is as important as `true`.
13
+ *
14
+ * `lastDetectedAt` moves only on a source's RISING edge — the source was not
15
+ * moving, or its last `true` had expired. A source's pushes include a
16
+ * heartbeat (the bridge's sustain ticks, every `true` a camera re-sends while
17
+ * a subject stays), and moving the stamp on each one made the grid's
18
+ * `lastDetectedAt` "the last tick of any cell" while every camera's is its
19
+ * last effective RISE (D696): the viewer's Motion order then ranked the grid
20
+ * above the very cells it shows (2026-10-06).
21
+ */
12
22
  noteMotion(sourceDeviceId: number, detected: boolean, atMs: number): void;
13
23
  /** One source's audio window. `dbfs` is the level, on the analyzer's scale. */
14
24
  noteAudio(sourceDeviceId: number, dbfs: number, atMs: number): void;
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  let zod = require("zod");
8
8
  let _camstack_types_node = require("@camstack/types/node");
9
9
  let node_path = require("node:path");
@@ -475,13 +475,25 @@ var GridActivityMirror = class {
475
475
  motion = /* @__PURE__ */ new Map();
476
476
  audio = /* @__PURE__ */ new Map();
477
477
  lastDetectedAt = null;
478
- /** One source's motion push. `detected: false` is as important as `true`. */
478
+ /**
479
+ * One source's motion push. `detected: false` is as important as `true`.
480
+ *
481
+ * `lastDetectedAt` moves only on a source's RISING edge — the source was not
482
+ * moving, or its last `true` had expired. A source's pushes include a
483
+ * heartbeat (the bridge's sustain ticks, every `true` a camera re-sends while
484
+ * a subject stays), and moving the stamp on each one made the grid's
485
+ * `lastDetectedAt` "the last tick of any cell" while every camera's is its
486
+ * last effective RISE (D696): the viewer's Motion order then ranked the grid
487
+ * above the very cells it shows (2026-10-06).
488
+ */
479
489
  noteMotion(sourceDeviceId, detected, atMs) {
490
+ const prev = this.motion.get(sourceDeviceId);
491
+ const wasMoving = prev !== void 0 && prev.detected && atMs - prev.atMs <= 15e3;
480
492
  this.motion.set(sourceDeviceId, {
481
493
  detected,
482
494
  atMs
483
495
  });
484
- if (detected) this.lastDetectedAt = Math.max(this.lastDetectedAt ?? 0, atMs);
496
+ if (detected && !wasMoving) this.lastDetectedAt = Math.max(this.lastDetectedAt ?? 0, atMs);
485
497
  }
486
498
  /** One source's audio window. `dbfs` is the level, on the analyzer's scale. */
487
499
  noteAudio(sourceDeviceId, dbfs, atMs) {
@@ -1,4 +1,4 @@
1
- import { $t as motionCapability, A as MOTION_CLOSE_AFTER_MS, Cn as snapshotCapability, Cr as EventCategory, Jn as DeviceFeature, Ln as buildFfmpegArgs, On as streamCatalogCapability, Qn as BaseAddon, Xn as DeviceType, Xt as memoizePinnedFfmpeg, Zn as errMsg, b as DeclaredDevices, cr as createEvent, et as cameraGridLayoutCapability, fr as hydrateSchema, i as BaseDevice, pt as declarationOwnerNodeId, y as DERIVED_CAMERA_SILENCED_CAP_NAMES } from "../../dist-OCi0K-iM.mjs";
1
+ import { $t as motionCapability, A as MOTION_CLOSE_AFTER_MS, Cn as snapshotCapability, Cr as EventCategory, Jn as DeviceFeature, Ln as buildFfmpegArgs, On as streamCatalogCapability, Qn as BaseAddon, Xn as DeviceType, Xt as memoizePinnedFfmpeg, Zn as errMsg, b as DeclaredDevices, cr as createEvent, et as cameraGridLayoutCapability, fr as hydrateSchema, i as BaseDevice, pt as declarationOwnerNodeId, y as DERIVED_CAMERA_SILENCED_CAP_NAMES } from "../../dist-B7WRgEZY.mjs";
2
2
  import { z } from "zod";
3
3
  import { FfmpegProcess } from "@camstack/types/node";
4
4
  import { join } from "node:path";
@@ -470,13 +470,25 @@ var GridActivityMirror = class {
470
470
  motion = /* @__PURE__ */ new Map();
471
471
  audio = /* @__PURE__ */ new Map();
472
472
  lastDetectedAt = null;
473
- /** One source's motion push. `detected: false` is as important as `true`. */
473
+ /**
474
+ * One source's motion push. `detected: false` is as important as `true`.
475
+ *
476
+ * `lastDetectedAt` moves only on a source's RISING edge — the source was not
477
+ * moving, or its last `true` had expired. A source's pushes include a
478
+ * heartbeat (the bridge's sustain ticks, every `true` a camera re-sends while
479
+ * a subject stays), and moving the stamp on each one made the grid's
480
+ * `lastDetectedAt` "the last tick of any cell" while every camera's is its
481
+ * last effective RISE (D696): the viewer's Motion order then ranked the grid
482
+ * above the very cells it shows (2026-10-06).
483
+ */
474
484
  noteMotion(sourceDeviceId, detected, atMs) {
485
+ const prev = this.motion.get(sourceDeviceId);
486
+ const wasMoving = prev !== void 0 && prev.detected && atMs - prev.atMs <= 15e3;
475
487
  this.motion.set(sourceDeviceId, {
476
488
  detected,
477
489
  atMs
478
490
  });
479
- if (detected) this.lastDetectedAt = Math.max(this.lastDetectedAt ?? 0, atMs);
491
+ if (detected && !wasMoving) this.lastDetectedAt = Math.max(this.lastDetectedAt ?? 0, atMs);
480
492
  }
481
493
  /** One source's audio window. `dbfs` is the level, on the analyzer's scale. */
482
494
  noteAudio(sourceDeviceId, dbfs, atMs) {
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
7
- const require_composition_sources = require("../../composition-sources-Bk-MjK1D.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
+ const require_composition_sources = require("../../composition-sources-CeO0K2cl.js");
8
8
  let zod = require("zod");
9
9
  //#region src/builtins/shared/device-state-changed.ts
10
10
  /** Structural narrowing helper for untrusted bus payloads. */
@@ -1,5 +1,5 @@
1
- import { Bn as composedDeviceStableId, Cr as EventCategory, Gn as createStatefulExpressionMemory, Hn as compositionItemFieldPath, In as COMPOSER_ADDON_ID, Kn as disarmRoseMemory, Ot as expressionContainsBuiltinCall, Qn as BaseAddon, Rn as cloneStatefulExpressionMemory, Tt as evaluateCompositionField, Un as compositionSliceKey, Vn as compositionFeatureEnabled, Wn as compositionSourceKey, Xn as DeviceType, Z as buildCapabilityLookup, Zn as errMsg, b as DeclaredDevices, cr as createEvent, i as BaseDevice, l as COMPOSED_ITEM_FIXED_FIELDS, nt as composerCapability, on as planComposition, qn as toExpressionValue, rt as compositionFieldKey, t as ALL_CAPABILITY_DEFINITIONS, zn as composedDeviceRef } from "../../dist-OCi0K-iM.mjs";
2
- import { n as normalizedNativeOwner } from "../../composition-sources-Dpl1G0Gr.mjs";
1
+ import { Bn as composedDeviceStableId, Cr as EventCategory, Gn as createStatefulExpressionMemory, Hn as compositionItemFieldPath, In as COMPOSER_ADDON_ID, Kn as disarmRoseMemory, Ot as expressionContainsBuiltinCall, Qn as BaseAddon, Rn as cloneStatefulExpressionMemory, Tt as evaluateCompositionField, Un as compositionSliceKey, Vn as compositionFeatureEnabled, Wn as compositionSourceKey, Xn as DeviceType, Z as buildCapabilityLookup, Zn as errMsg, b as DeclaredDevices, cr as createEvent, i as BaseDevice, l as COMPOSED_ITEM_FIXED_FIELDS, nt as composerCapability, on as planComposition, qn as toExpressionValue, rt as compositionFieldKey, t as ALL_CAPABILITY_DEFINITIONS, zn as composedDeviceRef } from "../../dist-B7WRgEZY.mjs";
2
+ import { n as normalizedNativeOwner } from "../../composition-sources-BBfqepyT.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/builtins/shared/device-state-changed.ts
5
5
  /** Structural narrowing helper for untrusted bus payloads. */
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/console-logging/console-destination.ts
9
9
  var LEVEL_RANK = {
@@ -1,4 +1,4 @@
1
- import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-OCi0K-iM.mjs";
1
+ import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-B7WRgEZY.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/console-logging/console-destination.ts
4
4
  var LEVEL_RANK = {
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-BWicEEVA.js");
4
- const require_composition_sources = require("../../composition-sources-Bk-MjK1D.js");
3
+ const require_dist = require("../../dist-CFVOy8VT.js");
4
+ const require_composition_sources = require("../../composition-sources-CeO0K2cl.js");
5
5
  let node_crypto = require("node:crypto");
6
6
  let _camstack_types_node = require("@camstack/types/node");
7
7
  let node_fs_promises = require("node:fs/promises");
@@ -1,5 +1,5 @@
1
- import { Qn as BaseAddon, Wn as compositionSourceKey, Z as buildCapabilityLookup, Zn as errMsg, _t as describeComposableCaps, at as coreBlockAddonId, b as DeclaredDevices, ct as coreBlockSourceKind, d as CORE_BLOCKS_ADDON_ID, dn as replacedFieldKeys, en as normalizeCoreBlockWrite, f as CORE_BLOCK_ADDON_PREFIX, fr as hydrateSchema, it as compositionSourceRefs, jn as validateComposition, lt as coreBlocksCapability, m as CoreBlockSchema, mn as resolveCoreBlockFiles, on as planComposition, ot as coreBlockComposition, pn as resolveCoreBlockEntry, st as coreBlockIdFromAddonId, t as ALL_CAPABILITY_DEFINITIONS, u as COMPOSER_RUNNER_ID, zn as composedDeviceRef } from "../../dist-OCi0K-iM.mjs";
2
- import { t as describeCompositionSources } from "../../composition-sources-Dpl1G0Gr.mjs";
1
+ import { Qn as BaseAddon, Wn as compositionSourceKey, Z as buildCapabilityLookup, Zn as errMsg, _t as describeComposableCaps, at as coreBlockAddonId, b as DeclaredDevices, ct as coreBlockSourceKind, d as CORE_BLOCKS_ADDON_ID, dn as replacedFieldKeys, en as normalizeCoreBlockWrite, f as CORE_BLOCK_ADDON_PREFIX, fr as hydrateSchema, it as compositionSourceRefs, jn as validateComposition, lt as coreBlocksCapability, m as CoreBlockSchema, mn as resolveCoreBlockFiles, on as planComposition, ot as coreBlockComposition, pn as resolveCoreBlockEntry, st as coreBlockIdFromAddonId, t as ALL_CAPABILITY_DEFINITIONS, u as COMPOSER_RUNNER_ID, zn as composedDeviceRef } from "../../dist-B7WRgEZY.mjs";
2
+ import { t as describeCompositionSources } from "../../composition-sources-BBfqepyT.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { customizationBlockName } from "@camstack/types/node";
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
7
- const require_retired_settings_keys = require("../../retired-settings-keys-DLJ7MvIB.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
+ const require_retired_settings_keys = require("../../retired-settings-keys-CRlTzxaS.js");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
10
10
  let _camstack_types_node = require("@camstack/types/node");
@@ -1,5 +1,5 @@
1
- import { Bt as legacyAutoLinkIds, C as FieldClaimModeSchema, Cr as EventCategory, Ct as enumerateItemArrayFields, D as LocationIconIdSchema, Dt as expandContainer, I as STREAM_PROFILE_META, Jn as DeviceFeature, Mt as formatMinutes, Q as buildStreamParamsConfigSchema, Qn as BaseAddon, Sn as siteZoneKey, Wt as locationIconKey, Xn as DeviceType, Yn as DeviceRole, Zn as errMsg, _n as runtimeStatePolicyFor, bt as deviceStateCapability, c as CAP_NAMES_WITH_STATUS, ht as defineExtensionSlotProvider, in as parseStreamParamsFormPatch, ir as WELL_KNOWN_TAB_MAP, k as MINUTES_PER_DAY, o as CAMERA_SWITCH_ORDER, pr as isDeviceConfigCap, t as ALL_CAPABILITY_DEFINITIONS, tn as normalizeUnit, ut as createDeviceExtensionProvider, v as DAY_NAMES, vt as deviceExtensionCapability, w as FieldClaimSchema, wt as enumerateSchemaFields, x as DeviceStatusSchema, xr as sleep$1, xt as deviceStatusCapability, yt as deviceManagerCapability } from "../../dist-OCi0K-iM.mjs";
2
- import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-TDzxE6GA.mjs";
1
+ import { Bt as legacyAutoLinkIds, C as FieldClaimModeSchema, Cr as EventCategory, Ct as enumerateItemArrayFields, D as LocationIconIdSchema, Dt as expandContainer, I as STREAM_PROFILE_META, Jn as DeviceFeature, Mt as formatMinutes, Q as buildStreamParamsConfigSchema, Qn as BaseAddon, Sn as siteZoneKey, Wt as locationIconKey, Xn as DeviceType, Yn as DeviceRole, Zn as errMsg, _n as runtimeStatePolicyFor, bt as deviceStateCapability, c as CAP_NAMES_WITH_STATUS, ht as defineExtensionSlotProvider, in as parseStreamParamsFormPatch, ir as WELL_KNOWN_TAB_MAP, k as MINUTES_PER_DAY, o as CAMERA_SWITCH_ORDER, pr as isDeviceConfigCap, t as ALL_CAPABILITY_DEFINITIONS, tn as normalizeUnit, ut as createDeviceExtensionProvider, v as DAY_NAMES, vt as deviceExtensionCapability, w as FieldClaimSchema, wt as enumerateSchemaFields, x as DeviceStatusSchema, xr as sleep$1, xt as deviceStatusCapability, yt as deviceManagerCapability } from "../../dist-B7WRgEZY.mjs";
2
+ import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-DKRjfz0U.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
9
9
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,4 +1,4 @@
1
- import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-OCi0K-iM.mjs";
1
+ import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-B7WRgEZY.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
4
4
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-BWicEEVA.js");
3
+ const require_dist = require("../../dist-CFVOy8VT.js");
4
4
  //#region src/builtins/liveness-monitor/liveness-checks.ts
5
5
  var NO_DEVICES = "liveness:no-devices";
6
6
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -1,4 +1,4 @@
1
- import { Cr as EventCategory, P as RecordingStatusSchema, Qn as BaseAddon, Zn as errMsg, cr as createEvent, j as RECORDING_SOURCE_CAMSTACK_ADDON } from "../../dist-OCi0K-iM.mjs";
1
+ import { Cr as EventCategory, P as RecordingStatusSchema, Qn as BaseAddon, Zn as errMsg, cr as createEvent, j as RECORDING_SOURCE_CAMSTACK_ADDON } from "../../dist-B7WRgEZY.mjs";
2
2
  //#region src/builtins/liveness-monitor/liveness-checks.ts
3
3
  var NO_DEVICES = "liveness:no-devices";
4
4
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_chunk.__toESM(node_crypto);
9
9
  let crypto$1 = require("crypto");
@@ -1,5 +1,5 @@
1
1
  import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
2
- import { An as userManagementCapability, H as UserRecordSchema, L as ScopedTokenSchema, Qn as BaseAddon, q as authProviderCapability, r as ApiKeyRecordSchema } from "../../dist-OCi0K-iM.mjs";
2
+ import { An as userManagementCapability, H as UserRecordSchema, L as ScopedTokenSchema, Qn as BaseAddon, q as authProviderCapability, r as ApiKeyRecordSchema } from "../../dist-B7WRgEZY.mjs";
3
3
  import * as crypto$2 from "node:crypto";
4
4
  import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
5
5
  import nodeCrypto from "crypto";
@@ -120,6 +120,13 @@ export declare class LocalNetworkAddon extends BaseAddon<LocalNetworkConfig> {
120
120
  private resolvedHttpPort;
121
121
  private tlsDataDir;
122
122
  private snapshotTls;
123
+ /**
124
+ * Hot-swap the HTTPS listener onto the pair now on disk. A failure is not
125
+ * thrown — the files are already written and the status reports
126
+ * `restartRequired` from the served-vs-disk fingerprints — but it is logged:
127
+ * a certificate change that did not reach the listener must say so.
128
+ */
129
+ private putCertificateOnListener;
123
130
  /**
124
131
  * Bind or unbind the LAN HTTP sibling from the addon's own settings, and
125
132
  * keep the leaf SAN in sync with `localHostname`. This is the settings
@@ -1,9 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-BWicEEVA.js");
4
- const require_tls = require("../../tls-ue_Xefmv.js");
5
- let node_fs_promises = require("node:fs/promises");
6
- let node_path = require("node:path");
3
+ const require_dist = require("../../dist-CFVOy8VT.js");
4
+ const require_tls = require("../../tls-CCMX7MjX.js");
7
5
  let node_os = require("node:os");
8
6
  node_os = require_chunk.__toESM(node_os);
9
7
  let node_fs = require("node:fs");
@@ -326,32 +324,30 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
326
324
  } });
327
325
  return { success: true };
328
326
  },
329
- getTlsStatus: async () => this.snapshotTls(false),
327
+ getTlsStatus: async () => this.snapshotTls(),
330
328
  regenerateCertificate: async (_input) => {
331
- if (require_tls.readTlsMode(this.tlsDataDir()) === "uploaded") throw new Error("Cannot regenerate an uploaded certificate — revert to generated first.");
332
329
  const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
333
- await require_tls.reissueTlsLeaf(this.tlsDataDir(), { extraSans });
334
- return this.snapshotTls(true);
330
+ await require_tls.regenerateCertificate(this.tlsDataDir(), { extraSans });
331
+ this.putCertificateOnListener("regenerate");
332
+ return this.snapshotTls();
335
333
  },
336
334
  uploadCertificate: async ({ certPem, keyPem, caPem }) => {
337
- const valid = require_tls.validateUploadedTls(certPem, keyPem);
338
- if (!valid.ok) throw new Error(valid.error);
339
- const dir = (0, node_path.join)(this.tlsDataDir(), "tls");
340
- await (0, node_fs_promises.mkdir)(dir, { recursive: true });
341
- await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.crt"), certPem.endsWith("\n") ? certPem : `${certPem}\n`);
342
- await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.key"), keyPem.endsWith("\n") ? keyPem : `${keyPem}\n`, { mode: 384 });
343
- if (caPem && caPem.trim() !== "") await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack-ca.crt"), caPem.endsWith("\n") ? caPem : `${caPem}\n`);
344
- require_tls.writeTlsMode(this.tlsDataDir(), "uploaded");
345
- return this.snapshotTls(true);
335
+ await require_tls.storeUploadedCertificate(this.tlsDataDir(), {
336
+ certPem,
337
+ keyPem,
338
+ caPem
339
+ });
340
+ this.putCertificateOnListener("upload");
341
+ return this.snapshotTls();
346
342
  },
347
343
  downloadCa: async () => {
348
- return { pem: this.snapshotTls(false).caCertPem ?? "" };
344
+ return { pem: this.snapshotTls().caCertPem ?? "" };
349
345
  },
350
346
  revertToGeneratedCertificate: async () => {
351
- require_tls.writeTlsMode(this.tlsDataDir(), "generated");
352
347
  const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
353
- await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans });
354
- return this.snapshotTls(true);
348
+ await require_tls.revertToGeneratedCertificate(this.tlsDataDir(), { extraSans });
349
+ this.putCertificateOnListener("revert");
350
+ return this.snapshotTls();
355
351
  }
356
352
  };
357
353
  this.lastSnapshotKey = snapshotKey(this.enumerate());
@@ -510,14 +506,35 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
510
506
  tlsDataDir() {
511
507
  return this.ctx.nodeDataDir ?? this.ctx.dataDir;
512
508
  }
513
- snapshotTls(restartRequired) {
514
- const status = require_tls.readTlsAccessStatus(this.tlsDataDir(), restartRequired);
509
+ snapshotTls() {
510
+ const status = require_tls.readTlsAccessStatus(this.tlsDataDir(), require_tls.servedHttpsLeafFingerprint());
515
511
  return {
516
512
  ...status,
517
513
  sans: [...status.sans]
518
514
  };
519
515
  }
520
516
  /**
517
+ * Hot-swap the HTTPS listener onto the pair now on disk. A failure is not
518
+ * thrown — the files are already written and the status reports
519
+ * `restartRequired` from the served-vs-disk fingerprints — but it is logged:
520
+ * a certificate change that did not reach the listener must say so.
521
+ */
522
+ putCertificateOnListener(action) {
523
+ const outcome = require_tls.applyCertificateToListener(this.tlsDataDir());
524
+ if (outcome.kind === "reloaded") {
525
+ this.ctx.logger.info("local-network: HTTPS listener now serves the new certificate", { meta: {
526
+ action,
527
+ leafFingerprintSha256: outcome.servedLeafFingerprint
528
+ } });
529
+ return;
530
+ }
531
+ this.ctx.logger.warn("local-network: certificate changed on disk but NOT on the listener", { meta: {
532
+ action,
533
+ reason: outcome.kind,
534
+ ...outcome.kind === "failed" ? { error: outcome.error } : {}
535
+ } });
536
+ }
537
+ /**
521
538
  * Bind or unbind the LAN HTTP sibling from the addon's own settings, and
522
539
  * keep the leaf SAN in sync with `localHostname`. This is the settings
523
540
  * side-effect path — there is no second persist API.
@@ -536,7 +553,9 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
536
553
  });
537
554
  if (hostname !== "") {
538
555
  require_tls.writeExtraSans(this.tlsDataDir(), [hostname]);
539
- if (require_tls.readTlsMode(this.tlsDataDir()) === "generated") await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] });
556
+ if (require_tls.readTlsMode(this.tlsDataDir()) === "generated") {
557
+ if ((await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] })).generated) this.putCertificateOnListener("hostname");
558
+ }
540
559
  } else require_tls.writeExtraSans(this.tlsDataDir(), []);
541
560
  }
542
561
  /**
@@ -1,7 +1,5 @@
1
- import { Cr as EventCategory, Qn as BaseAddon, Ut as localNetworkCapability, an as pickAppLinkHub, s as CAMSTACK_APP_LINK_ORIGIN } from "../../dist-OCi0K-iM.mjs";
2
- import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-DTlVWwAI.mjs";
3
- import { mkdir, writeFile } from "node:fs/promises";
4
- import { join } from "node:path";
1
+ import { Cr as EventCategory, Qn as BaseAddon, Ut as localNetworkCapability, an as pickAppLinkHub, s as CAMSTACK_APP_LINK_ORIGIN } from "../../dist-B7WRgEZY.mjs";
2
+ import { P as readLanHttpState, _ as writeExtraSans, h as readTlsMode, i as storeUploadedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, m as readTlsAccessStatus, n as regenerateCertificate, p as readExtraSans, r as revertToGeneratedCertificate, t as applyCertificateToListener, u as servedHttpsLeafFingerprint, y as ensureTlsCert } from "../../tls-CJHogwTl.mjs";
5
3
  import * as os from "node:os";
6
4
  import { readFileSync } from "node:fs";
7
5
  import { isIP } from "node:net";
@@ -323,32 +321,30 @@ var LocalNetworkAddon = class extends BaseAddon {
323
321
  } });
324
322
  return { success: true };
325
323
  },
326
- getTlsStatus: async () => this.snapshotTls(false),
324
+ getTlsStatus: async () => this.snapshotTls(),
327
325
  regenerateCertificate: async (_input) => {
328
- if (readTlsMode(this.tlsDataDir()) === "uploaded") throw new Error("Cannot regenerate an uploaded certificate — revert to generated first.");
329
326
  const extraSans = [...readExtraSans(this.tlsDataDir())];
330
- await reissueTlsLeaf(this.tlsDataDir(), { extraSans });
331
- return this.snapshotTls(true);
327
+ await regenerateCertificate(this.tlsDataDir(), { extraSans });
328
+ this.putCertificateOnListener("regenerate");
329
+ return this.snapshotTls();
332
330
  },
333
331
  uploadCertificate: async ({ certPem, keyPem, caPem }) => {
334
- const valid = validateUploadedTls(certPem, keyPem);
335
- if (!valid.ok) throw new Error(valid.error);
336
- const dir = join(this.tlsDataDir(), "tls");
337
- await mkdir(dir, { recursive: true });
338
- await writeFile(join(dir, "camstack.crt"), certPem.endsWith("\n") ? certPem : `${certPem}\n`);
339
- await writeFile(join(dir, "camstack.key"), keyPem.endsWith("\n") ? keyPem : `${keyPem}\n`, { mode: 384 });
340
- if (caPem && caPem.trim() !== "") await writeFile(join(dir, "camstack-ca.crt"), caPem.endsWith("\n") ? caPem : `${caPem}\n`);
341
- writeTlsMode(this.tlsDataDir(), "uploaded");
342
- return this.snapshotTls(true);
332
+ await storeUploadedCertificate(this.tlsDataDir(), {
333
+ certPem,
334
+ keyPem,
335
+ caPem
336
+ });
337
+ this.putCertificateOnListener("upload");
338
+ return this.snapshotTls();
343
339
  },
344
340
  downloadCa: async () => {
345
- return { pem: this.snapshotTls(false).caCertPem ?? "" };
341
+ return { pem: this.snapshotTls().caCertPem ?? "" };
346
342
  },
347
343
  revertToGeneratedCertificate: async () => {
348
- writeTlsMode(this.tlsDataDir(), "generated");
349
344
  const extraSans = [...readExtraSans(this.tlsDataDir())];
350
- await ensureTlsCert(this.tlsDataDir(), { extraSans });
351
- return this.snapshotTls(true);
345
+ await revertToGeneratedCertificate(this.tlsDataDir(), { extraSans });
346
+ this.putCertificateOnListener("revert");
347
+ return this.snapshotTls();
352
348
  }
353
349
  };
354
350
  this.lastSnapshotKey = snapshotKey(this.enumerate());
@@ -507,14 +503,35 @@ var LocalNetworkAddon = class extends BaseAddon {
507
503
  tlsDataDir() {
508
504
  return this.ctx.nodeDataDir ?? this.ctx.dataDir;
509
505
  }
510
- snapshotTls(restartRequired) {
511
- const status = readTlsAccessStatus(this.tlsDataDir(), restartRequired);
506
+ snapshotTls() {
507
+ const status = readTlsAccessStatus(this.tlsDataDir(), servedHttpsLeafFingerprint());
512
508
  return {
513
509
  ...status,
514
510
  sans: [...status.sans]
515
511
  };
516
512
  }
517
513
  /**
514
+ * Hot-swap the HTTPS listener onto the pair now on disk. A failure is not
515
+ * thrown — the files are already written and the status reports
516
+ * `restartRequired` from the served-vs-disk fingerprints — but it is logged:
517
+ * a certificate change that did not reach the listener must say so.
518
+ */
519
+ putCertificateOnListener(action) {
520
+ const outcome = applyCertificateToListener(this.tlsDataDir());
521
+ if (outcome.kind === "reloaded") {
522
+ this.ctx.logger.info("local-network: HTTPS listener now serves the new certificate", { meta: {
523
+ action,
524
+ leafFingerprintSha256: outcome.servedLeafFingerprint
525
+ } });
526
+ return;
527
+ }
528
+ this.ctx.logger.warn("local-network: certificate changed on disk but NOT on the listener", { meta: {
529
+ action,
530
+ reason: outcome.kind,
531
+ ...outcome.kind === "failed" ? { error: outcome.error } : {}
532
+ } });
533
+ }
534
+ /**
518
535
  * Bind or unbind the LAN HTTP sibling from the addon's own settings, and
519
536
  * keep the leaf SAN in sync with `localHostname`. This is the settings
520
537
  * side-effect path — there is no second persist API.
@@ -533,7 +550,9 @@ var LocalNetworkAddon = class extends BaseAddon {
533
550
  });
534
551
  if (hostname !== "") {
535
552
  writeExtraSans(this.tlsDataDir(), [hostname]);
536
- if (readTlsMode(this.tlsDataDir()) === "generated") await ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] });
553
+ if (readTlsMode(this.tlsDataDir()) === "generated") {
554
+ if ((await ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] })).generated) this.putCertificateOnListener("hostname");
555
+ }
537
556
  } else writeExtraSans(this.tlsDataDir(), []);
538
557
  }
539
558
  /**
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BWicEEVA.js");
6
+ const require_dist = require("../../dist-CFVOy8VT.js");
7
7
  //#region src/builtins/loki-logging/loki-payload.ts
8
8
  /**
9
9
  * Loki rejects a label name that is not a valid Prometheus label
@@ -1,4 +1,4 @@
1
- import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-OCi0K-iM.mjs";
1
+ import { Gt as logDestinationCapability, Qn as BaseAddon } from "../../dist-B7WRgEZY.mjs";
2
2
  //#region src/builtins/loki-logging/loki-payload.ts
3
3
  /**
4
4
  * Loki rejects a label name that is not a valid Prometheus label