@camstack/system 1.2.376 → 1.2.378

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 (92) hide show
  1. package/dist/addon-runner.js +9 -4
  2. package/dist/addon-runner.mjs +10 -5
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +1 -1
  10. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  15. package/dist/builtins/calendars/calendars.addon.js +1 -1
  16. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  17. package/dist/builtins/camera-grid/index.js +1 -1
  18. package/dist/builtins/camera-grid/index.mjs +1 -1
  19. package/dist/builtins/composer/composer.addon.js +2 -2
  20. package/dist/builtins/composer/composer.addon.mjs +2 -2
  21. package/dist/builtins/console-logging/index.js +1 -1
  22. package/dist/builtins/console-logging/index.mjs +1 -1
  23. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  24. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  25. package/dist/builtins/device-manager/device-config-secrets.d.ts +21 -0
  26. package/dist/builtins/device-manager/device-manager.addon.js +85 -6
  27. package/dist/builtins/device-manager/device-manager.addon.mjs +85 -6
  28. package/dist/builtins/hub-forwarder/index.js +1 -1
  29. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  30. package/dist/builtins/keychain/index.d.ts +1 -0
  31. package/dist/builtins/keychain/index.js +1442 -0
  32. package/dist/builtins/keychain/index.mjs +1435 -0
  33. package/dist/builtins/keychain/key-sources.d.ts +37 -0
  34. package/dist/builtins/keychain/keychain-crypto.d.ts +28 -0
  35. package/dist/builtins/keychain/keychain-service.d.ts +103 -0
  36. package/dist/builtins/keychain/keychain-store.d.ts +82 -0
  37. package/dist/builtins/keychain/keychain-usage.d.ts +6 -0
  38. package/dist/builtins/keychain/keychain.addon.d.ts +11 -0
  39. package/dist/builtins/keychain/platform-key-source.d.ts +24 -0
  40. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  41. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  42. package/dist/builtins/local-auth/local-auth.addon.js +19 -2
  43. package/dist/builtins/local-auth/local-auth.addon.mjs +19 -2
  44. package/dist/builtins/local-network/local-network.addon.js +1 -1
  45. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  46. package/dist/builtins/loki-logging/index.js +1 -1
  47. package/dist/builtins/loki-logging/index.mjs +1 -1
  48. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  49. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  50. package/dist/builtins/platform-probe/index.js +1 -1
  51. package/dist/builtins/platform-probe/index.mjs +1 -1
  52. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  53. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  54. package/dist/builtins/snapshot/index.js +1 -1
  55. package/dist/builtins/snapshot/index.mjs +1 -1
  56. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  57. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  58. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  59. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  60. package/dist/builtins/storage-orchestrator/location-store.d.ts +6 -0
  61. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +15 -0
  62. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +74 -14
  63. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +74 -14
  64. package/dist/builtins/system-config/system-config.addon.js +1 -1
  65. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  66. package/dist/builtins/winston-logging/index.js +1 -1
  67. package/dist/builtins/winston-logging/index.mjs +1 -1
  68. package/dist/{child-cap-dispatch-BWtaSmWf.js → child-cap-dispatch-C9lmrWFT.js} +198 -25
  69. package/dist/{child-cap-dispatch-8qMgog1O.mjs → child-cap-dispatch-DpHovtQd.mjs} +170 -27
  70. package/dist/{composition-sources-zxQPPtP_.mjs → composition-sources-BLBd338N.mjs} +1 -1
  71. package/dist/{composition-sources-DW7CgMsg.js → composition-sources-CxhGdtdh.js} +1 -1
  72. package/dist/{dist-D732NygW.mjs → dist-Bvl5JgNt.mjs} +2336 -105
  73. package/dist/{dist-BcUWQGr9.js → dist-KxsOMQik.js} +2401 -104
  74. package/dist/{event-loop-stall-monitor-QX4RjNe7.js → event-loop-stall-monitor-CbSmCWkp.js} +8 -7
  75. package/dist/{event-loop-stall-monitor-8W4yWNVW.mjs → event-loop-stall-monitor-D8rqSWfW.mjs} +8 -7
  76. package/dist/{hub-cap-forward-BdT320dq.mjs → hub-cap-forward-CH6_VWVO.mjs} +13 -4
  77. package/dist/{hub-cap-forward-DmHNjbB0.js → hub-cap-forward-COCmYaup.js} +13 -4
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.js +20 -6
  80. package/dist/index.mjs +13 -7
  81. package/dist/kernel/config-schema.d.ts +4 -0
  82. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +6 -0
  83. package/dist/kernel/transport/cap-route-resolver.d.ts +19 -0
  84. package/dist/kernel/transport/hub-cap-forward.d.ts +22 -1
  85. package/dist/kernel/transport/index.d.ts +2 -2
  86. package/dist/kernel/transport/local-child-registry.d.ts +4 -3
  87. package/dist/logging/log-redactor.d.ts +9 -0
  88. package/dist/platform-key-source-BWlq0jjn.mjs +23 -0
  89. package/dist/platform-key-source-Di7HrlGR.js +40 -0
  90. package/dist/{retired-settings-keys-CxPOg7BF.mjs → retired-settings-keys-BAcfvFtm.mjs} +1 -1
  91. package/dist/{retired-settings-keys-MaESpO18.js → retired-settings-keys-gTsZfpmP.js} +1 -1
  92. package/package.json +17 -1
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_child_cap_dispatch = require("./child-cap-dispatch-BWtaSmWf.js");
2
+ const require_child_cap_dispatch = require("./child-cap-dispatch-C9lmrWFT.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);
@@ -44,7 +44,8 @@ async function dispatchSettings(addon, addonId, method, args) {
44
44
  case "getGlobalSettings": return typeof addon.getGlobalSettings === "function" ? await addon.getGlobalSettings(args.overlay, args.cap, args.nodeId) ?? null : null;
45
45
  case "updateGlobalSettings":
46
46
  if (typeof addon.updateGlobalSettings !== "function") throw new Error(`child-addon-call: addon "${addonId}" does not implement updateGlobalSettings`);
47
- await addon.updateGlobalSettings(args.patch ?? {}, args.nodeId);
47
+ if (typeof addon.updateGlobalSettingsAsOperator === "function") await addon.updateGlobalSettingsAsOperator(args.patch ?? {}, args.nodeId);
48
+ else await addon.updateGlobalSettings(args.patch ?? {}, args.nodeId);
48
49
  return { success: true };
49
50
  case "getIntegrationSettings": return typeof addon.getIntegrationSettings === "function" ? await addon.getIntegrationSettings(args.nodeId) ?? null : null;
50
51
  case "getDeviceSettings": return typeof addon.getDeviceSettings === "function" && typeof args.deviceId === "number" ? await addon.getDeviceSettings(args.deviceId) ?? null : null;
@@ -85,7 +86,8 @@ function createChildAddonCallDispatch(deps) {
85
86
  if (typeof action !== "string" || action.length === 0) throw new Error(`child-addon-call: addon "${addonId}" custom call missing action name`);
86
87
  const entry = deps.customActions.resolve(addonId, action);
87
88
  if (entry === null) throw new Error(`child-addon-call: addon "${addonId}" has no custom action "${action}"`);
88
- const parsedInput = entry.spec.input.safeParse(call.args);
89
+ const args = deps.resolveSecretViews !== void 0 ? await deps.resolveSecretViews(addonId, call.args) : call.args;
90
+ const parsedInput = entry.spec.input.safeParse(args);
89
91
  if (!parsedInput.success) throw new Error(`child-addon-call: addon "${addonId}" custom action "${action}" rejected its input — ` + parsedInput.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; "));
90
92
  const result = await entry.handler(parsedInput.data, call.caller);
91
93
  return entry.spec.output.parse(result);
@@ -529,11 +531,13 @@ async function main() {
529
531
  isProviderOptionalMethod: (capName, method) => (0, _camstack_types_addon.isProviderOptionalMethodName)(capName, method)
530
532
  })
531
533
  });
534
+ const addonSecrets = /* @__PURE__ */ new Map();
532
535
  udsChildClient.onAddonCall(createChildAddonCallDispatch({
533
536
  getRouteProvider: (addonId) => addonRouteProviders.get(addonId) ?? null,
534
537
  customActions: customActionRegistry,
535
538
  getAddonInstance: (addonId) => loadedAddonInstances.get(addonId) ?? null,
536
- getDataPlanes: (addonId) => addonDataPlanes.get(addonId) ?? []
539
+ getDataPlanes: (addonId) => addonDataPlanes.get(addonId) ?? [],
540
+ resolveSecretViews: (addonId, args) => (0, _camstack_types_addon.resolveSecretViewsIn)(args, addonSecrets.get(addonId))
537
541
  }));
538
542
  const { logger: runnerLog, control: runnerLogControl } = require_child_cap_dispatch.createUdsLoggerWithControl(udsChildClient, runnerId, nodeId, "addon-runner");
539
543
  udsChildClient.onSetLogLevel((level) => {
@@ -574,6 +578,7 @@ async function main() {
574
578
  addonDataPlanes.set(addonId, endpoints);
575
579
  } }
576
580
  });
581
+ if (context.secrets !== void 0) addonSecrets.set(spec.addonId, context.secrets);
577
582
  try {
578
583
  const pkgRaw = JSON.parse(node_fs.readFileSync(node_path.join(spec.addonDir, "package.json"), "utf-8"));
579
584
  await require_child_cap_dispatch.installManifestNativeDeps(spec.addonDir, pkgRaw, context.logger);
@@ -1,10 +1,10 @@
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-8qMgog1O.mjs";
1
+ import { Ft as installManifestNativeDeps, H as createUdsLoggerWithControl, It as resolveAddonClass, St as validateProviderRegistrations, U as LocalChildClient, _n as startRunnerHeapWatch, _t as getWorkerNativeCapProvider, bt as setWorkerNativeCapsChangeListener, f as installManifestSystemDeps, g as createUdsAddonContext, i as killOwnRunnerGroupAfterParentLoss, in as RUNNER_RSS_BUDGET_ENV, kn as emitHeapDiagnosticReport, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, vt as getWorkerNativeCapSnapshot } from "./child-cap-dispatch-DpHovtQd.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";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import * as fs from "node:fs";
7
- import { ReadinessRegistry, ReadinessTimeoutError, errMsg, isCollectionArrayMethodName, isProviderOptionalMethodName, normalizeAddonInitResult } from "@camstack/types/addon";
7
+ import { ReadinessRegistry, ReadinessTimeoutError, errMsg, isCollectionArrayMethodName, isProviderOptionalMethodName, normalizeAddonInitResult, resolveSecretViewsIn } from "@camstack/types/addon";
8
8
  //#region src/kernel/moleculer/child-addon-call-dispatch.ts
9
9
  function isRecord$1(value) {
10
10
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -41,7 +41,8 @@ async function dispatchSettings(addon, addonId, method, args) {
41
41
  case "getGlobalSettings": return typeof addon.getGlobalSettings === "function" ? await addon.getGlobalSettings(args.overlay, args.cap, args.nodeId) ?? null : null;
42
42
  case "updateGlobalSettings":
43
43
  if (typeof addon.updateGlobalSettings !== "function") throw new Error(`child-addon-call: addon "${addonId}" does not implement updateGlobalSettings`);
44
- await addon.updateGlobalSettings(args.patch ?? {}, args.nodeId);
44
+ if (typeof addon.updateGlobalSettingsAsOperator === "function") await addon.updateGlobalSettingsAsOperator(args.patch ?? {}, args.nodeId);
45
+ else await addon.updateGlobalSettings(args.patch ?? {}, args.nodeId);
45
46
  return { success: true };
46
47
  case "getIntegrationSettings": return typeof addon.getIntegrationSettings === "function" ? await addon.getIntegrationSettings(args.nodeId) ?? null : null;
47
48
  case "getDeviceSettings": return typeof addon.getDeviceSettings === "function" && typeof args.deviceId === "number" ? await addon.getDeviceSettings(args.deviceId) ?? null : null;
@@ -82,7 +83,8 @@ function createChildAddonCallDispatch(deps) {
82
83
  if (typeof action !== "string" || action.length === 0) throw new Error(`child-addon-call: addon "${addonId}" custom call missing action name`);
83
84
  const entry = deps.customActions.resolve(addonId, action);
84
85
  if (entry === null) throw new Error(`child-addon-call: addon "${addonId}" has no custom action "${action}"`);
85
- const parsedInput = entry.spec.input.safeParse(call.args);
86
+ const args = deps.resolveSecretViews !== void 0 ? await deps.resolveSecretViews(addonId, call.args) : call.args;
87
+ const parsedInput = entry.spec.input.safeParse(args);
86
88
  if (!parsedInput.success) throw new Error(`child-addon-call: addon "${addonId}" custom action "${action}" rejected its input — ` + parsedInput.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; "));
87
89
  const result = await entry.handler(parsedInput.data, call.caller);
88
90
  return entry.spec.output.parse(result);
@@ -526,11 +528,13 @@ async function main() {
526
528
  isProviderOptionalMethod: (capName, method) => isProviderOptionalMethodName(capName, method)
527
529
  })
528
530
  });
531
+ const addonSecrets = /* @__PURE__ */ new Map();
529
532
  udsChildClient.onAddonCall(createChildAddonCallDispatch({
530
533
  getRouteProvider: (addonId) => addonRouteProviders.get(addonId) ?? null,
531
534
  customActions: customActionRegistry,
532
535
  getAddonInstance: (addonId) => loadedAddonInstances.get(addonId) ?? null,
533
- getDataPlanes: (addonId) => addonDataPlanes.get(addonId) ?? []
536
+ getDataPlanes: (addonId) => addonDataPlanes.get(addonId) ?? [],
537
+ resolveSecretViews: (addonId, args) => resolveSecretViewsIn(args, addonSecrets.get(addonId))
534
538
  }));
535
539
  const { logger: runnerLog, control: runnerLogControl } = createUdsLoggerWithControl(udsChildClient, runnerId, nodeId, "addon-runner");
536
540
  udsChildClient.onSetLogLevel((level) => {
@@ -571,6 +575,7 @@ async function main() {
571
575
  addonDataPlanes.set(addonId, endpoints);
572
576
  } }
573
577
  });
578
+ if (context.secrets !== void 0) addonSecrets.set(spec.addonId, context.secrets);
574
579
  try {
575
580
  const pkgRaw = JSON.parse(fs.readFileSync(path$1.join(spec.addonDir, "package.json"), "utf-8"));
576
581
  await installManifestNativeDeps(spec.addonDir, pkgRaw, context.logger);
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("./chunk-Cek0wNdY.js");
3
- const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-QX4RjNe7.js");
3
+ const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-CbSmCWkp.js");
4
4
  const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
5
5
  const require_snapshot_courtesy = require("./snapshot-courtesy-D_C5-nC0.js");
6
6
  exports.COURTESY_DEFAULT_WIDTH = require_snapshot_courtesy.COURTESY_DEFAULT_WIDTH;
@@ -1,4 +1,4 @@
1
- import { C as resolveFormatRevision, S as isModelDownloaded, a as createFileDataPlaneHandler, b as getModelFilePath, c as parseRangeHeader, d as ModelDownloadService, f as ModelDownloadHttpError, g as downloadFile, h as deleteModelFromDisk, i as startEventLoopStallMonitor, m as collectModelFiles, n as STALL_TICK_MS, o as contentTypeFor, p as adoptModelRevisions, r as attributeStall, t as STALL_REPORT_MS, v as ensureModel, x as isModelDownloadHttpError } from "./event-loop-stall-monitor-8W4yWNVW.mjs";
1
+ import { C as resolveFormatRevision, S as isModelDownloaded, a as createFileDataPlaneHandler, b as getModelFilePath, c as parseRangeHeader, d as ModelDownloadService, f as ModelDownloadHttpError, g as downloadFile, h as deleteModelFromDisk, i as startEventLoopStallMonitor, m as collectModelFiles, n as STALL_TICK_MS, o as contentTypeFor, p as adoptModelRevisions, r as attributeStall, t as STALL_REPORT_MS, v as ensureModel, x as isModelDownloadHttpError } from "./event-loop-stall-monitor-D8rqSWfW.mjs";
2
2
  import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
3
3
  import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg, t as COURTESY_DEFAULT_WIDTH } from "./snapshot-courtesy-CyFs1M3I.mjs";
4
4
  export { COURTESY_DEFAULT_WIDTH, CustomActionRegistry, ModelDownloadHttpError, ModelDownloadService, STALL_REPORT_MS, STALL_TICK_MS, adoptModelRevisions, attributeStall, collectModelFiles, contentTypeFor, courtesyCacheKey, createFileDataPlaneHandler, deleteModelFromDisk, downloadFile, ensureModel, getModelFilePath, isModelDownloadHttpError, isModelDownloaded, parseRangeHeader, renderCourtesyJpeg, renderCourtesyOverlayJpeg, resolveFormatRevision, startEventLoopStallMonitor };
@@ -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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { G as addonPagesCapability, Pr as EventCategory, cr as BaseAddon, sr as errMsg } from "../../dist-D732NygW.mjs";
1
+ import { Gr as EventCategory, W as addonPagesCapability, cr as errMsg, lr as BaseAddon } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { Pr as EventCategory, cr as BaseAddon, q as addonWidgetsCapability, sr as errMsg } from "../../dist-D732NygW.mjs";
1
+ import { Gr as EventCategory, K as addonWidgetsCapability, cr as errMsg, lr as BaseAddon } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { J as alertsCapability, Pr as EventCategory, cr as BaseAddon, n as AlertSchema, sr as errMsg, yr as createEvent } from "../../dist-D732NygW.mjs";
1
+ import { Gr as EventCategory, Sr as createEvent, cr as errMsg, lr as BaseAddon, n as AlertSchema, q as alertsCapability } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { Pr as EventCategory, S as FIRST_LEVEL_MACRO_CLASSES, Tr as isEvent, Z as bareAddonId, cr as BaseAddon, hn as ptzAutotrackCapability, sr as errMsg } from "../../dist-D732NygW.mjs";
1
+ import { Gr as EventCategory, S as FIRST_LEVEL_MACRO_CLASSES, X as bareAddonId, cr as errMsg, gn as ptzAutotrackCapability, kr as isEvent, lr as BaseAddon } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { Er as nodePin, Fn as storageOccupancyCapability, Nr as toNodeId, Pr as EventCategory, X as backupCapability, cr as BaseAddon, g as DATABASE_SNAPSHOT_SUFFIX, tn as mayWriteToLocation } from "../../dist-D732NygW.mjs";
1
+ import { Gr as EventCategory, In as storageOccupancyCapability, Ur as toNodeId, Y as backupCapability, g as DATABASE_SNAPSHOT_SUFFIX, jr as nodePin, lr as BaseAddon, nn as mayWriteToLocation } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { cr as BaseAddon, p as CalendarPreferencesSchema, tt as calendarsCapability } from "../../dist-D732NygW.mjs";
1
+ import { et as calendarsCapability, lr as BaseAddon, p as CalendarPreferencesSchema } from "../../dist-Bvl5JgNt.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
@@ -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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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");
@@ -1,4 +1,4 @@
1
- import { Cr as hydrateSchema, Ln as streamCatalogCapability, M as MOTION_CLOSE_AFTER_MS, Mn as snapshotCapability, Pr as EventCategory, an as motionCapability, b as DeclaredDevices, cr as BaseAddon, gt as declarationOwnerNodeId, i as BaseDevice, ir as DeviceFeature, nn as memoizePinnedFfmpeg, nt as cameraGridLayoutCapability, or as DeviceType, qn as buildFfmpegArgs, sr as errMsg, y as DERIVED_CAMERA_SILENCED_CAP_NAMES, yr as createEvent } from "../../dist-D732NygW.mjs";
1
+ import { Dr as hydrateSchema, Gr as EventCategory, Jn as buildFfmpegArgs, M as MOTION_CLOSE_AFTER_MS, Nn as snapshotCapability, Rn as streamCatalogCapability, Sr as createEvent, ar as DeviceFeature, b as DeclaredDevices, cr as errMsg, i as BaseDevice, lr as BaseAddon, mt as declarationOwnerNodeId, on as motionCapability, rn as memoizePinnedFfmpeg, sr as DeviceType, tt as cameraGridLayoutCapability, y as DERIVED_CAMERA_SILENCED_CAP_NAMES } from "../../dist-Bvl5JgNt.mjs";
2
2
  import { z } from "zod";
3
3
  import { FfmpegProcess } from "@camstack/types/node";
4
4
  import { join } from "node:path";
@@ -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-BcUWQGr9.js");
7
- const require_composition_sources = require("../../composition-sources-DW7CgMsg.js");
6
+ const require_dist = require("../../dist-KxsOMQik.js");
7
+ const require_composition_sources = require("../../composition-sources-CxhGdtdh.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 { $ as buildCapabilityLookup, $n as compositionSliceKey, Jn as cloneStatefulExpressionMemory, Kn as COMPOSER_ADDON_ID, Ot as evaluateCompositionField, Pr as EventCategory, Qn as compositionItemFieldPath, Xn as composedDeviceStableId, Yn as composedDeviceRef, Zn as compositionFeatureEnabled, at as composerCapability, b as DeclaredDevices, cr as BaseAddon, er as compositionSourceKey, fn as planComposition, i as BaseDevice, jt as expressionContainsBuiltinCall, l as COMPOSED_ITEM_FIXED_FIELDS, nr as disarmRoseMemory, or as DeviceType, ot as compositionFieldKey, rr as toExpressionValue, sr as errMsg, t as ALL_CAPABILITY_DEFINITIONS, tr as createStatefulExpressionMemory, yr as createEvent } from "../../dist-D732NygW.mjs";
2
- import { n as normalizedNativeOwner } from "../../composition-sources-zxQPPtP_.mjs";
1
+ import { $n as compositionItemFieldPath, Et as evaluateCompositionField, Gr as EventCategory, Q as buildCapabilityLookup, Qn as compositionFeatureEnabled, Sr as createEvent, Xn as composedDeviceRef, Yn as cloneStatefulExpressionMemory, Zn as composedDeviceStableId, b as DeclaredDevices, cr as errMsg, er as compositionSliceKey, i as BaseDevice, ir as toExpressionValue, it as compositionFieldKey, kt as expressionContainsBuiltinCall, l as COMPOSED_ITEM_FIXED_FIELDS, lr as BaseAddon, nr as createStatefulExpressionMemory, pn as planComposition, qn as COMPOSER_ADDON_ID, rr as disarmRoseMemory, rt as composerCapability, sr as DeviceType, t as ALL_CAPABILITY_DEFINITIONS, tr as compositionSourceKey } from "../../dist-Bvl5JgNt.mjs";
2
+ import { n as normalizedNativeOwner } from "../../composition-sources-BLBd338N.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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { Zt as logDestinationCapability, cr as BaseAddon } from "../../dist-D732NygW.mjs";
1
+ import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-Bvl5JgNt.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-BcUWQGr9.js");
4
- const require_composition_sources = require("../../composition-sources-DW7CgMsg.js");
3
+ const require_dist = require("../../dist-KxsOMQik.js");
4
+ const require_composition_sources = require("../../composition-sources-CxhGdtdh.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 { $ as buildCapabilityLookup, Bn as validateComposition, Cr as hydrateSchema, Yn as composedDeviceRef, _n as replacedFieldKeys, b as DeclaredDevices, bn as resolveCoreBlockEntry, bt as describeComposableCaps, cr as BaseAddon, ct as coreBlockAddonId, d as CORE_BLOCKS_ADDON_ID, dt as coreBlockSourceKind, er as compositionSourceKey, f as CORE_BLOCK_ADDON_PREFIX, fn as planComposition, ft as coreBlocksCapability, lt as coreBlockComposition, m as CoreBlockSchema, on as normalizeCoreBlockWrite, sr as errMsg, st as compositionSourceRefs, t as ALL_CAPABILITY_DEFINITIONS, u as COMPOSER_RUNNER_ID, ut as coreBlockIdFromAddonId, xn as resolveCoreBlockFiles } from "../../dist-D732NygW.mjs";
2
- import { t as describeCompositionSources } from "../../composition-sources-zxQPPtP_.mjs";
1
+ import { Dr as hydrateSchema, Q as buildCapabilityLookup, Sn as resolveCoreBlockFiles, Vn as validateComposition, Xn as composedDeviceRef, at as compositionSourceRefs, b as DeclaredDevices, cr as errMsg, ct as coreBlockIdFromAddonId, d as CORE_BLOCKS_ADDON_ID, f as CORE_BLOCK_ADDON_PREFIX, lr as BaseAddon, lt as coreBlockSourceKind, m as CoreBlockSchema, ot as coreBlockAddonId, pn as planComposition, sn as normalizeCoreBlockWrite, st as coreBlockComposition, t as ALL_CAPABILITY_DEFINITIONS, tr as compositionSourceKey, u as COMPOSER_RUNNER_ID, ut as coreBlocksCapability, vn as replacedFieldKeys, vt as describeComposableCaps, xn as resolveCoreBlockEntry } from "../../dist-Bvl5JgNt.mjs";
2
+ import { t as describeCompositionSources } from "../../composition-sources-BLBd338N.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { customizationBlockName } from "@camstack/types/node";
@@ -0,0 +1,21 @@
1
+ import { AddonContext } from '@camstack/types';
2
+ export interface DeviceConfigSecretDeps {
3
+ readonly ctx: AddonContext;
4
+ readonly readStored: () => Promise<Record<string, unknown>>;
5
+ readonly write: (patch: Record<string, unknown>) => Promise<void>;
6
+ }
7
+ /** Persist a device config patch with its declared secrets kept in the keychain. */
8
+ export declare function persistDeviceConfigWithSecrets(deps: DeviceConfigSecretDeps, input: {
9
+ readonly deviceId: number;
10
+ readonly ownerAddonId: string;
11
+ readonly data: Record<string, unknown>;
12
+ readonly secretPaths: readonly string[];
13
+ /** The write was made by the operator (no driver stamped it). */
14
+ readonly operatorWrite: boolean;
15
+ }): Promise<void>;
16
+ /** A stored device config with its markers resolved for the driver. */
17
+ export declare function loadDeviceConfigWithSecrets(ctx: AddonContext, input: {
18
+ readonly deviceId: number;
19
+ readonly ownerAddonId: string;
20
+ readonly stored: Record<string, unknown>;
21
+ }): Promise<Record<string, unknown>>;
@@ -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-BcUWQGr9.js");
7
- const require_retired_settings_keys = require("../../retired-settings-keys-MaESpO18.js");
6
+ const require_dist = require("../../dist-KxsOMQik.js");
7
+ const require_retired_settings_keys = require("../../retired-settings-keys-gTsZfpmP.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");
@@ -5102,6 +5102,69 @@ async function swapHardwareState(settings, sourceId, targetId) {
5102
5102
  };
5103
5103
  }
5104
5104
  //#endregion
5105
+ //#region src/builtins/device-manager/device-config-secrets.ts
5106
+ /**
5107
+ * The device-config door of the keychain (D787) — device CONNECTION config
5108
+ * (camera passwords, controller API keys) lives in device-manager's per-device
5109
+ * store, written by the driver's `persistConfig` and read back by its
5110
+ * `loadConfig`. Resolving HERE, at the door, means no driver ever sees a
5111
+ * marker and no driver has to change.
5112
+ *
5113
+ * - WRITE: the paths the device's own schema declares secret (D783:
5114
+ * `secretConfigPaths`, from the persist call or from its last
5115
+ * `registerDevice`) go through the keychain save path, owned by the DRIVER
5116
+ * addon (`device/<id>` scope). A value equal to an inline pre-keychain one
5117
+ * stays inline (no silent migration); `''` keeps.
5118
+ * - READ: every marker in the stored blob is resolved for the driver; one that
5119
+ * cannot be is LEFT OUT (the driver's schema default applies) and logged by
5120
+ * ref — never answered as `''`, never written back.
5121
+ *
5122
+ * device-manager runs in hub-main, so it acts for the driver through
5123
+ * `ctx.secrets.forOwner` — the in-process delegate no forked addon has.
5124
+ */
5125
+ function ownerSecrets(ctx, ownerAddonId) {
5126
+ const forOwner = ctx.secrets?.forOwner ?? null;
5127
+ return forOwner === null ? null : forOwner(ownerAddonId);
5128
+ }
5129
+ /** Persist a device config patch with its declared secrets kept in the keychain. */
5130
+ async function persistDeviceConfigWithSecrets(deps, input) {
5131
+ const secrets = ownerSecrets(deps.ctx, input.ownerAddonId);
5132
+ const tree = require_dist.secretTreeFromPaths(input.secretPaths);
5133
+ if (secrets === null || tree.size === 0) return deps.write(input.data);
5134
+ const stored = await deps.readStored();
5135
+ const result = await require_dist.transformSecretWrite({
5136
+ tree,
5137
+ secrets,
5138
+ patch: input.data,
5139
+ stored,
5140
+ scope: {
5141
+ kind: "device",
5142
+ deviceId: input.deviceId
5143
+ },
5144
+ operatorWrite: input.operatorWrite
5145
+ });
5146
+ if (Object.keys(result.patch).length > 0) await deps.write(result.patch);
5147
+ const { orphaned } = await result.afterWrite();
5148
+ if (orphaned.length > 0) deps.ctx.logger.warn("device config: dropped keychain refs could not be deleted", {
5149
+ tags: { deviceId: input.deviceId },
5150
+ meta: { refs: [...orphaned] }
5151
+ });
5152
+ }
5153
+ /** A stored device config with its markers resolved for the driver. */
5154
+ async function loadDeviceConfigWithSecrets(ctx, input) {
5155
+ const secrets = ownerSecrets(ctx, input.ownerAddonId);
5156
+ if (secrets === null) return input.stored;
5157
+ const { value, unresolved } = await require_dist.resolveSecretMarkers(input.stored, secrets);
5158
+ if (unresolved.length > 0) ctx.logger.error("device config: secret unavailable — the device starts without it", {
5159
+ tags: { deviceId: input.deviceId },
5160
+ meta: { secrets: unresolved.map((u) => ({
5161
+ ref: u.ref,
5162
+ reason: u.reason
5163
+ })) }
5164
+ });
5165
+ return value;
5166
+ }
5167
+ //#endregion
5105
5168
  //#region src/builtins/device-manager/location-alignment.ts
5106
5169
  /**
5107
5170
  * Location alignment — closes the RETROACTIVITY hole D252/D329 left open, and
@@ -5759,13 +5822,29 @@ async function removeDevice(pctx, input) {
5759
5822
  }
5760
5823
  async function persistConfig(pctx, input) {
5761
5824
  const { deviceId, data } = input;
5762
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] persistConfig: unknown device id=${deviceId}`);
5763
- await pctx.settings.writeDeviceStore(deviceId, data);
5825
+ const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
5826
+ if (!persisted) throw new Error(`[device-manager] persistConfig: unknown device id=${deviceId}`);
5827
+ await persistDeviceConfigWithSecrets({
5828
+ ctx: pctx.host.ctx,
5829
+ readStored: () => pctx.settings.readDeviceStore(deviceId),
5830
+ write: (patch) => pctx.settings.writeDeviceStore(deviceId, patch)
5831
+ }, {
5832
+ deviceId,
5833
+ ownerAddonId: persisted.addonId,
5834
+ data,
5835
+ secretPaths: input.secretConfigPaths ?? pctx.secretConfigPaths.get(deviceId) ?? [],
5836
+ operatorWrite: typeof Reflect.get(input, "callerAddonId") !== "string"
5837
+ });
5764
5838
  }
5765
5839
  async function loadConfig(pctx, input) {
5766
5840
  const { deviceId } = input;
5767
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) return {};
5768
- return pctx.settings.readDeviceStore(deviceId);
5841
+ const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
5842
+ if (!persisted) return {};
5843
+ return loadDeviceConfigWithSecrets(pctx.host.ctx, {
5844
+ deviceId,
5845
+ ownerAddonId: persisted.addonId,
5846
+ stored: await pctx.settings.readDeviceStore(deviceId)
5847
+ });
5769
5848
  }
5770
5849
  /**
5771
5850
  * Load the operator-organisational meta surface for one device
@@ -1,5 +1,5 @@
1
- import { A as MINUTES_PER_DAY, At as expandContainer, C as FieldClaimModeSchema, Ct as deviceStateCapability, Dt as enumerateSchemaFields, En as runtimeStatePolicyFor, Et as enumerateItemArrayFields, Ft as formatMinutes, Kt as legacyAutoLinkIds, Mr as sleep$1, O as LocationIconIdSchema, Pr as EventCategory, R as STREAM_PROFILE_META, St as deviceManagerCapability, Xt as locationIconKey, ar as DeviceRole, c as CAP_NAMES_WITH_STATUS, cr as BaseAddon, et as buildStreamParamsConfigSchema, ir as DeviceFeature, jn as siteZoneKey, mr as WELL_KNOWN_TAB_MAP, o as CAMERA_SWITCH_ORDER, or as DeviceType, pt as createDeviceExtensionProvider, sn as normalizeUnit, sr as errMsg, t as ALL_CAPABILITY_DEFINITIONS, un as parseStreamParamsFormPatch, v as DAY_NAMES, vr as collectZodSecretPaths, vt as defineExtensionSlotProvider, w as FieldClaimSchema, wr as isDeviceConfigCap, wt as deviceStatusCapability, x as DeviceStatusSchema, xt as deviceExtensionCapability } from "../../dist-D732NygW.mjs";
2
- import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-CxPOg7BF.mjs";
1
+ import { $ as buildStreamParamsConfigSchema, A as MINUTES_PER_DAY, C as FieldClaimModeSchema, Dn as runtimeStatePolicyFor, Gr as EventCategory, Hr as sleep$1, Kt as legacyAutoLinkIds, L as STREAM_PROFILE_META, Mn as siteZoneKey, Nt as formatMinutes, O as LocationIconIdSchema, Or as isDeviceConfigCap, Ot as expandContainer, Rr as resolveSecretMarkers, St as deviceStatusCapability, Tt as enumerateSchemaFields, Vr as secretTreeFromPaths, Wr as transformSecretWrite, Xt as locationIconKey, ar as DeviceFeature, bt as deviceManagerCapability, c as CAP_NAMES_WITH_STATUS, cn as normalizeUnit, cr as errMsg, dn as parseStreamParamsFormPatch, dt as createDeviceExtensionProvider, gr as WELL_KNOWN_TAB_MAP, gt as defineExtensionSlotProvider, lr as BaseAddon, o as CAMERA_SWITCH_ORDER, or as DeviceRole, sr as DeviceType, t as ALL_CAPABILITY_DEFINITIONS, v as DAY_NAMES, w as FieldClaimSchema, wt as enumerateItemArrayFields, x as DeviceStatusSchema, xr as collectZodSecretPaths, xt as deviceStateCapability, yt as deviceExtensionCapability } from "../../dist-Bvl5JgNt.mjs";
2
+ import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-BAcfvFtm.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
@@ -5097,6 +5097,69 @@ async function swapHardwareState(settings, sourceId, targetId) {
5097
5097
  };
5098
5098
  }
5099
5099
  //#endregion
5100
+ //#region src/builtins/device-manager/device-config-secrets.ts
5101
+ /**
5102
+ * The device-config door of the keychain (D787) — device CONNECTION config
5103
+ * (camera passwords, controller API keys) lives in device-manager's per-device
5104
+ * store, written by the driver's `persistConfig` and read back by its
5105
+ * `loadConfig`. Resolving HERE, at the door, means no driver ever sees a
5106
+ * marker and no driver has to change.
5107
+ *
5108
+ * - WRITE: the paths the device's own schema declares secret (D783:
5109
+ * `secretConfigPaths`, from the persist call or from its last
5110
+ * `registerDevice`) go through the keychain save path, owned by the DRIVER
5111
+ * addon (`device/<id>` scope). A value equal to an inline pre-keychain one
5112
+ * stays inline (no silent migration); `''` keeps.
5113
+ * - READ: every marker in the stored blob is resolved for the driver; one that
5114
+ * cannot be is LEFT OUT (the driver's schema default applies) and logged by
5115
+ * ref — never answered as `''`, never written back.
5116
+ *
5117
+ * device-manager runs in hub-main, so it acts for the driver through
5118
+ * `ctx.secrets.forOwner` — the in-process delegate no forked addon has.
5119
+ */
5120
+ function ownerSecrets(ctx, ownerAddonId) {
5121
+ const forOwner = ctx.secrets?.forOwner ?? null;
5122
+ return forOwner === null ? null : forOwner(ownerAddonId);
5123
+ }
5124
+ /** Persist a device config patch with its declared secrets kept in the keychain. */
5125
+ async function persistDeviceConfigWithSecrets(deps, input) {
5126
+ const secrets = ownerSecrets(deps.ctx, input.ownerAddonId);
5127
+ const tree = secretTreeFromPaths(input.secretPaths);
5128
+ if (secrets === null || tree.size === 0) return deps.write(input.data);
5129
+ const stored = await deps.readStored();
5130
+ const result = await transformSecretWrite({
5131
+ tree,
5132
+ secrets,
5133
+ patch: input.data,
5134
+ stored,
5135
+ scope: {
5136
+ kind: "device",
5137
+ deviceId: input.deviceId
5138
+ },
5139
+ operatorWrite: input.operatorWrite
5140
+ });
5141
+ if (Object.keys(result.patch).length > 0) await deps.write(result.patch);
5142
+ const { orphaned } = await result.afterWrite();
5143
+ if (orphaned.length > 0) deps.ctx.logger.warn("device config: dropped keychain refs could not be deleted", {
5144
+ tags: { deviceId: input.deviceId },
5145
+ meta: { refs: [...orphaned] }
5146
+ });
5147
+ }
5148
+ /** A stored device config with its markers resolved for the driver. */
5149
+ async function loadDeviceConfigWithSecrets(ctx, input) {
5150
+ const secrets = ownerSecrets(ctx, input.ownerAddonId);
5151
+ if (secrets === null) return input.stored;
5152
+ const { value, unresolved } = await resolveSecretMarkers(input.stored, secrets);
5153
+ if (unresolved.length > 0) ctx.logger.error("device config: secret unavailable — the device starts without it", {
5154
+ tags: { deviceId: input.deviceId },
5155
+ meta: { secrets: unresolved.map((u) => ({
5156
+ ref: u.ref,
5157
+ reason: u.reason
5158
+ })) }
5159
+ });
5160
+ return value;
5161
+ }
5162
+ //#endregion
5100
5163
  //#region src/builtins/device-manager/location-alignment.ts
5101
5164
  /**
5102
5165
  * Location alignment — closes the RETROACTIVITY hole D252/D329 left open, and
@@ -5754,13 +5817,29 @@ async function removeDevice(pctx, input) {
5754
5817
  }
5755
5818
  async function persistConfig(pctx, input) {
5756
5819
  const { deviceId, data } = input;
5757
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] persistConfig: unknown device id=${deviceId}`);
5758
- await pctx.settings.writeDeviceStore(deviceId, data);
5820
+ const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
5821
+ if (!persisted) throw new Error(`[device-manager] persistConfig: unknown device id=${deviceId}`);
5822
+ await persistDeviceConfigWithSecrets({
5823
+ ctx: pctx.host.ctx,
5824
+ readStored: () => pctx.settings.readDeviceStore(deviceId),
5825
+ write: (patch) => pctx.settings.writeDeviceStore(deviceId, patch)
5826
+ }, {
5827
+ deviceId,
5828
+ ownerAddonId: persisted.addonId,
5829
+ data,
5830
+ secretPaths: input.secretConfigPaths ?? pctx.secretConfigPaths.get(deviceId) ?? [],
5831
+ operatorWrite: typeof Reflect.get(input, "callerAddonId") !== "string"
5832
+ });
5759
5833
  }
5760
5834
  async function loadConfig(pctx, input) {
5761
5835
  const { deviceId } = input;
5762
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) return {};
5763
- return pctx.settings.readDeviceStore(deviceId);
5836
+ const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
5837
+ if (!persisted) return {};
5838
+ return loadDeviceConfigWithSecrets(pctx.host.ctx, {
5839
+ deviceId,
5840
+ ownerAddonId: persisted.addonId,
5841
+ stored: await pctx.settings.readDeviceStore(deviceId)
5842
+ });
5764
5843
  }
5765
5844
  /**
5766
5845
  * Load the operator-organisational meta surface for one device
@@ -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-BcUWQGr9.js");
6
+ const require_dist = require("../../dist-KxsOMQik.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 { Zt as logDestinationCapability, cr as BaseAddon } from "../../dist-D732NygW.mjs";
1
+ import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-Bvl5JgNt.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;
@@ -0,0 +1 @@
1
+ export { KeychainAddon, default } from './keychain.addon.js';