@camstack/system 1.2.375 → 1.2.377

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 (99) 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/auth/external-identity-manager.d.ts +43 -0
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  10. package/dist/builtins/alerts/alerts.addon.js +1 -1
  11. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  12. package/dist/builtins/autotrack/index.js +1 -1
  13. package/dist/builtins/autotrack/index.mjs +1 -1
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  16. package/dist/builtins/calendars/calendars.addon.js +1 -1
  17. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  18. package/dist/builtins/camera-grid/index.js +1 -1
  19. package/dist/builtins/camera-grid/index.mjs +1 -1
  20. package/dist/builtins/composer/composer.addon.js +2 -2
  21. package/dist/builtins/composer/composer.addon.mjs +2 -2
  22. package/dist/builtins/console-logging/index.js +1 -1
  23. package/dist/builtins/console-logging/index.mjs +1 -1
  24. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  25. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  26. package/dist/builtins/device-manager/device-config-secrets.d.ts +21 -0
  27. package/dist/builtins/device-manager/device-manager.addon.d.ts +2 -0
  28. package/dist/builtins/device-manager/device-manager.addon.js +119 -6
  29. package/dist/builtins/device-manager/device-manager.addon.mjs +119 -6
  30. package/dist/builtins/device-manager/device-projection.d.ts +2 -1
  31. package/dist/builtins/device-manager/device-provider-context.d.ts +3 -0
  32. package/dist/builtins/device-manager/secret-config-paths.d.ts +24 -0
  33. package/dist/builtins/hub-forwarder/index.js +1 -1
  34. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  35. package/dist/builtins/keychain/index.d.ts +1 -0
  36. package/dist/builtins/keychain/index.js +1416 -0
  37. package/dist/builtins/keychain/index.mjs +1409 -0
  38. package/dist/builtins/keychain/key-sources.d.ts +37 -0
  39. package/dist/builtins/keychain/keychain-crypto.d.ts +28 -0
  40. package/dist/builtins/keychain/keychain-service.d.ts +103 -0
  41. package/dist/builtins/keychain/keychain-store.d.ts +82 -0
  42. package/dist/builtins/keychain/keychain-usage.d.ts +6 -0
  43. package/dist/builtins/keychain/keychain.addon.d.ts +11 -0
  44. package/dist/builtins/keychain/platform-key-source.d.ts +24 -0
  45. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  46. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  47. package/dist/builtins/local-auth/auth-schema.d.ts +14 -0
  48. package/dist/builtins/local-auth/local-auth.addon.d.ts +1 -0
  49. package/dist/builtins/local-auth/local-auth.addon.js +1358 -1129
  50. package/dist/builtins/local-auth/local-auth.addon.mjs +1358 -1129
  51. package/dist/builtins/local-network/local-network.addon.js +1 -1
  52. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  53. package/dist/builtins/loki-logging/index.js +1 -1
  54. package/dist/builtins/loki-logging/index.mjs +1 -1
  55. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  56. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  57. package/dist/builtins/platform-probe/index.js +1 -1
  58. package/dist/builtins/platform-probe/index.mjs +1 -1
  59. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  60. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  61. package/dist/builtins/snapshot/index.js +1 -1
  62. package/dist/builtins/snapshot/index.mjs +1 -1
  63. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  64. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  65. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  66. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  67. package/dist/builtins/storage-orchestrator/location-store.d.ts +6 -0
  68. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +15 -0
  69. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +74 -14
  70. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +74 -14
  71. package/dist/builtins/system-config/system-config.addon.js +1 -1
  72. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  73. package/dist/builtins/winston-logging/index.js +1 -1
  74. package/dist/builtins/winston-logging/index.mjs +1 -1
  75. package/dist/{child-cap-dispatch-B9kziY4L.mjs → child-cap-dispatch-CgmOo0yl.mjs} +184 -29
  76. package/dist/{child-cap-dispatch-Bfdgkbq3.js → child-cap-dispatch-DlDSoqm1.js} +212 -27
  77. package/dist/{composition-sources-DYlXX2qW.js → composition-sources-BNyXPSs_.js} +1 -1
  78. package/dist/{composition-sources-BfZgiTYD.mjs → composition-sources-D39bl0nP.mjs} +1 -1
  79. package/dist/{dist-ZdSg09GJ.mjs → dist-BWNoS-1S.mjs} +2454 -108
  80. package/dist/{dist-CNbnikIh.js → dist-D_a9mUiM.js} +2525 -107
  81. package/dist/{event-loop-stall-monitor-DKcYBHdH.mjs → event-loop-stall-monitor-ClPhfx7Y.mjs} +1 -1
  82. package/dist/{event-loop-stall-monitor-CpEH3CoV.js → event-loop-stall-monitor-DuOn8H1n.js} +1 -1
  83. package/dist/{hub-cap-forward-BdT320dq.mjs → hub-cap-forward-CH6_VWVO.mjs} +13 -4
  84. package/dist/{hub-cap-forward-DmHNjbB0.js → hub-cap-forward-COCmYaup.js} +13 -4
  85. package/dist/index.d.ts +2 -0
  86. package/dist/index.js +20 -6
  87. package/dist/index.mjs +13 -7
  88. package/dist/kernel/config-schema.d.ts +4 -0
  89. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +6 -0
  90. package/dist/kernel/transport/cap-route-resolver.d.ts +19 -0
  91. package/dist/kernel/transport/hub-cap-forward.d.ts +22 -1
  92. package/dist/kernel/transport/index.d.ts +2 -2
  93. package/dist/kernel/transport/local-child-registry.d.ts +4 -3
  94. package/dist/logging/log-redactor.d.ts +9 -0
  95. package/dist/platform-key-source-BWlq0jjn.mjs +23 -0
  96. package/dist/platform-key-source-Di7HrlGR.js +40 -0
  97. package/dist/{retired-settings-keys-CcWvdy6u.js → retired-settings-keys-CDyOGAje.js} +1 -1
  98. package/dist/{retired-settings-keys-B4ZeKrbR.mjs → retired-settings-keys-iGcmzwLV.mjs} +1 -1
  99. package/package.json +17 -1
@@ -1,5 +1,5 @@
1
- import { A as MINUTES_PER_DAY, At as expandContainer, C as FieldClaimModeSchema, Cr as isDeviceConfigCap, Ct as deviceStateCapability, Dt as enumerateSchemaFields, En as runtimeStatePolicyFor, Et as enumerateItemArrayFields, Ft as formatMinutes, Kt as legacyAutoLinkIds, Nr as EventCategory, O as LocationIconIdSchema, 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, jr as sleep$1, 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, vt as defineExtensionSlotProvider, w as FieldClaimSchema, wt as deviceStatusCapability, x as DeviceStatusSchema, xt as deviceExtensionCapability } from "../../dist-ZdSg09GJ.mjs";
2
- import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-B4ZeKrbR.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-BWNoS-1S.mjs";
2
+ import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-iGcmzwLV.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { canonicalDeviceFingerprint } from "@camstack/types/node";
@@ -391,6 +391,13 @@ function isDeviceRole(value) {
391
391
  function toDeviceRole(value) {
392
392
  return value != null && isDeviceRole(value) ? value : null;
393
393
  }
394
+ /** The secret paths a live device's config schema declares (D783), as a spreadable field. */
395
+ function liveSecretConfigPaths(device) {
396
+ const schema = device.config?.schema;
397
+ if (schema === void 0 || schema === null || typeof schema !== "object") return {};
398
+ const paths = collectZodSecretPaths(schema);
399
+ return paths.length > 0 ? { secretConfigPaths: [...paths] } : {};
400
+ }
394
401
  function toDeviceInfo(addonId, device, metadata = null, metaRow = null) {
395
402
  const configValues = {};
396
403
  for (const entry of device.config.entries()) configValues[entry.key] = entry.value;
@@ -414,6 +421,7 @@ function toDeviceInfo(addonId, device, metadata = null, metaRow = null) {
414
421
  features: device.features.length > 0 ? [...device.features] : persistedFeatures(metaRow?.features),
415
422
  isCamera: isCameraDevice(device),
416
423
  config: configValues,
424
+ ...liveSecretConfigPaths(device),
417
425
  metadata,
418
426
  ...metaRow?.integrationId !== void 0 ? { integrationId: metaRow.integrationId } : {},
419
427
  ...metaRow?.linkDeviceId !== void 0 ? { linkDeviceId: metaRow.linkDeviceId } : {},
@@ -2486,6 +2494,24 @@ function persistedOnlineFallback(input) {
2486
2494
  return Object.keys(input.config ?? {}).length > 0;
2487
2495
  }
2488
2496
  //#endregion
2497
+ //#region src/builtins/device-manager/secret-config-paths.ts
2498
+ function createSecretConfigPathRegistry() {
2499
+ const byDevice = /* @__PURE__ */ new Map();
2500
+ return {
2501
+ get: (deviceId) => byDevice.get(deviceId),
2502
+ set: (deviceId, paths) => {
2503
+ byDevice.set(deviceId, Object.freeze([...new Set(paths)]));
2504
+ },
2505
+ delete: (deviceId) => {
2506
+ byDevice.delete(deviceId);
2507
+ }
2508
+ };
2509
+ }
2510
+ /** `{ secretConfigPaths }` when any are known, `{}` otherwise — spread into a `DeviceInfo`. */
2511
+ function secretConfigPathsField(paths) {
2512
+ return paths !== void 0 && paths.length > 0 ? { secretConfigPaths: [...paths] } : {};
2513
+ }
2514
+ //#endregion
2489
2515
  //#region src/builtins/device-manager/device-queries.ts
2490
2516
  /**
2491
2517
  * The ORIGINATING addon id off a cap-channel call's `args`, or `undefined`.
@@ -2624,6 +2650,7 @@ async function listAll(pctx, input) {
2624
2650
  features: persistedFeatures(m.features),
2625
2651
  isCamera: persistedIsCamera(persistedType),
2626
2652
  config: persistedConfig ?? {},
2653
+ ...secretConfigPathsField(pctx.secretConfigPaths.get(m.id)),
2627
2654
  metadata,
2628
2655
  ...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
2629
2656
  ...m.linkDeviceId !== void 0 ? { linkDeviceId: m.linkDeviceId } : {},
@@ -2673,6 +2700,7 @@ async function getDevice(pctx, input) {
2673
2700
  features: persistedFeatures(m.features),
2674
2701
  isCamera: persistedIsCamera(m.type),
2675
2702
  config: persistedConfig ?? {},
2703
+ ...secretConfigPathsField(pctx.secretConfigPaths.get(deviceId)),
2676
2704
  metadata,
2677
2705
  ...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
2678
2706
  ...m.linkDeviceId !== void 0 ? { linkDeviceId: m.linkDeviceId } : {},
@@ -2749,6 +2777,7 @@ function projectChildren(pctx, parentDeviceId, ownerAddonId, childRows, liveChil
2749
2777
  features: persistedFeatures(m.features),
2750
2778
  isCamera: persistedIsCamera(m.type),
2751
2779
  config: persistedConfig,
2780
+ ...secretConfigPathsField(pctx.secretConfigPaths.get(m.id)),
2752
2781
  metadata,
2753
2782
  ...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
2754
2783
  ...m.linkDeviceId !== void 0 ? { linkDeviceId: m.linkDeviceId } : {},
@@ -5068,6 +5097,69 @@ async function swapHardwareState(settings, sourceId, targetId) {
5068
5097
  };
5069
5098
  }
5070
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
5071
5163
  //#region src/builtins/device-manager/location-alignment.ts
5072
5164
  /**
5073
5165
  * Location alignment — closes the RETROACTIVITY hole D252/D329 left open, and
@@ -5542,6 +5634,7 @@ async function registerDevice(pctx, input) {
5542
5634
  });
5543
5635
  throw new Error(`[device-manager] registerDevice: device ${id} (${addonId}/${stableId}) was removed — refusing to resurrect it`);
5544
5636
  }
5637
+ if (Array.isArray(input.secretConfigPaths)) pctx.secretConfigPaths.set(id, input.secretConfigPaths);
5545
5638
  const { isFirstRegistration, exportFingerprint, fingerprintChanged, inheritedLocation, inheritedDescendantIds, inheritFailed } = await pctx.metaStore.withMetaWriteLock(async () => {
5546
5639
  const existingRow = await pctx.metaStore.rows.get(id);
5547
5640
  const existingMeta = existingRow?.meta;
@@ -5688,6 +5781,7 @@ async function removeDevice(pctx, input) {
5688
5781
  stableId
5689
5782
  });
5690
5783
  });
5784
+ pctx.secretConfigPaths.delete(deviceId);
5691
5785
  await pctx.settings.clearDeviceStore(deviceId);
5692
5786
  await pctx.host.forgetMirrorDevice(deviceId);
5693
5787
  await pctx.settings.clearDeviceRuntimeState(deviceId);
@@ -5723,13 +5817,29 @@ async function removeDevice(pctx, input) {
5723
5817
  }
5724
5818
  async function persistConfig(pctx, input) {
5725
5819
  const { deviceId, data } = input;
5726
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) throw new Error(`[device-manager] persistConfig: unknown device id=${deviceId}`);
5727
- 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
+ });
5728
5833
  }
5729
5834
  async function loadConfig(pctx, input) {
5730
5835
  const { deviceId } = input;
5731
- if (!await pctx.metaStore.resolvePersistedById(deviceId)) return {};
5732
- 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
+ });
5733
5843
  }
5734
5844
  /**
5735
5845
  * Load the operator-organisational meta surface for one device
@@ -9600,6 +9710,8 @@ var DeviceManagerAddon = class extends BaseAddon {
9600
9710
  * `allocateDeviceId` never consults.
9601
9711
  */
9602
9712
  removalFence = createRemovalFence();
9713
+ /** Declared secret config paths per device, as last registered (D783). */
9714
+ secretConfigPaths = createSecretConfigPathRegistry();
9603
9715
  /** The runtime-state mirror, asserted present (constructed in onInitialize). */
9604
9716
  get stateMirror() {
9605
9717
  if (!this.stateMirrorImpl) throw new Error("DeviceManagerAddon: state mirror accessed before onInitialize");
@@ -9841,6 +9953,7 @@ var DeviceManagerAddon = class extends BaseAddon {
9841
9953
  bindingsDeps: this.bindingsDeps,
9842
9954
  migrationGuard: createMigrationGuard(),
9843
9955
  removalFence: this.removalFence,
9956
+ secretConfigPaths: this.secretConfigPaths,
9844
9957
  requireDeviceOps,
9845
9958
  stampIntegrationId: stampIntegrationId$1,
9846
9959
  get provider() {
@@ -62,6 +62,8 @@ export declare function toDeviceInfo(addonId: string, device: IDevice, metadata?
62
62
  primaryChildEntityId?: string | null | undefined;
63
63
  linkDeviceId?: number | null | undefined;
64
64
  integrationId?: string | undefined;
65
+ metadata: Record<string, unknown> | null;
66
+ secretConfigPaths?: string[];
65
67
  id: number;
66
68
  stableId: string;
67
69
  addonId: string;
@@ -76,7 +78,6 @@ export declare function toDeviceInfo(addonId: string, device: IDevice, metadata?
76
78
  features: DeviceFeature[];
77
79
  isCamera: boolean;
78
80
  config: Record<string, unknown>;
79
- metadata: Record<string, unknown> | null;
80
81
  };
81
82
  export declare function resolveDeviceById(registry: IDeviceRegistry, deviceId: number): {
82
83
  addonId: string;
@@ -6,6 +6,7 @@ import { FieldClaimsIndex } from './field-claims-index.js';
6
6
  import { OwnedCaps } from './field-ownership.js';
7
7
  import { MigrationGuard } from './migrate-guard.js';
8
8
  import { RemovalFence } from './removal-fence.js';
9
+ import { SecretConfigPathRegistry } from './secret-config-paths.js';
9
10
  import { SeedMode } from './device-state-mirror.js';
10
11
  import { MirrorWriteHold } from './mirror-row-writer.js';
11
12
  type IDeviceProviderCap = InferProvider<typeof deviceProviderCapability>;
@@ -85,6 +86,8 @@ export interface ProviderContext {
85
86
  * tears down, which is how a deleted camera came back as a config-less
86
87
  * shell (D376). */
87
88
  readonly removalFence: RemovalFence;
89
+ /** The secret config paths each device declared at `registerDevice` (D783). */
90
+ readonly secretConfigPaths: SecretConfigPathRegistry;
88
91
  /** Resolve the per-device `device-ops` native provider (throws when absent). */
89
92
  requireDeviceOps(deviceId: number): IDeviceOpsProvider;
90
93
  /** Stamp an integration id onto a device's meta row + emit DeviceMetaChanged. */
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The secret config paths each device DECLARES (D783) — `connection.password`,
3
+ * `localKey`, `rows[].token` — as its runner last reported them at
4
+ * `registerDevice`.
5
+ *
6
+ * In memory on purpose: a runner re-registers every device it owns whenever it
7
+ * (re)starts, and a hub-main restart restarts every runner, so the map refills
8
+ * on its own. Until a device has registered, its `DeviceInfo` carries no paths
9
+ * and the non-admin redaction falls back to its keyword backstop — never to
10
+ * "no redaction". Paths only; never a value.
11
+ */
12
+ export interface SecretConfigPathRegistry {
13
+ /** The paths last reported for `deviceId`, or `undefined` when none were. */
14
+ get(deviceId: number): readonly string[] | undefined;
15
+ /** Replace the paths for `deviceId` with the runner's latest report. */
16
+ set(deviceId: number, paths: readonly string[]): void;
17
+ /** Forget a removed device. */
18
+ delete(deviceId: number): void;
19
+ }
20
+ export declare function createSecretConfigPathRegistry(): SecretConfigPathRegistry;
21
+ /** `{ secretConfigPaths }` when any are known, `{}` otherwise — spread into a `DeviceInfo`. */
22
+ export declare function secretConfigPathsField(paths: readonly string[] | undefined): {
23
+ secretConfigPaths?: string[];
24
+ };
@@ -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-CNbnikIh.js");
6
+ const require_dist = require("../../dist-D_a9mUiM.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-ZdSg09GJ.mjs";
1
+ import { Zt as logDestinationCapability, lr as BaseAddon } from "../../dist-BWNoS-1S.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';