@camstack/system 1.0.2

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 (262) hide show
  1. package/dist/addon/addon-api-factory.d.ts +35 -0
  2. package/dist/addon-routes/addon-route-registry.d.ts +37 -0
  3. package/dist/addon-runner.js +599 -0
  4. package/dist/addon-runner.mjs +597 -0
  5. package/dist/auth/api-key-manager.d.ts +26 -0
  6. package/dist/auth/auth-manager.d.ts +109 -0
  7. package/dist/auth/parse-record.d.ts +18 -0
  8. package/dist/auth/scope-matcher.d.ts +7 -0
  9. package/dist/auth/scoped-token-manager.d.ts +40 -0
  10. package/dist/auth/totp-manager.d.ts +51 -0
  11. package/dist/auth/user-manager.d.ts +34 -0
  12. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +53 -0
  13. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +259 -0
  14. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +251 -0
  15. package/dist/builtins/addon-pages-aggregator/dedupe-pages.d.ts +6 -0
  16. package/dist/builtins/addon-pages-aggregator/index.d.ts +1 -0
  17. package/dist/builtins/addon-pages-aggregator/index.js +8 -0
  18. package/dist/builtins/addon-pages-aggregator/index.mjs +2 -0
  19. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +47 -0
  20. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +228 -0
  21. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +220 -0
  22. package/dist/builtins/addon-widgets-aggregator/index.d.ts +1 -0
  23. package/dist/builtins/addon-widgets-aggregator/index.js +8 -0
  24. package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -0
  25. package/dist/builtins/alerts/alerts.addon.d.ts +81 -0
  26. package/dist/builtins/alerts/alerts.addon.js +601 -0
  27. package/dist/builtins/alerts/alerts.addon.mjs +595 -0
  28. package/dist/builtins/alerts/index.d.ts +1 -0
  29. package/dist/builtins/alerts/index.js +4 -0
  30. package/dist/builtins/alerts/index.mjs +2 -0
  31. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +147 -0
  32. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2229 -0
  33. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2220 -0
  34. package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +23 -0
  35. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +72 -0
  36. package/dist/builtins/backup-orchestrator/download-helpers.d.ts +12 -0
  37. package/dist/builtins/backup-orchestrator/index.d.ts +2 -0
  38. package/dist/builtins/backup-orchestrator/index.js +8 -0
  39. package/dist/builtins/backup-orchestrator/index.mjs +2 -0
  40. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +77 -0
  41. package/dist/builtins/console-logging/console-destination.d.ts +13 -0
  42. package/dist/builtins/console-logging/console-logging.addon.d.ts +25 -0
  43. package/dist/builtins/console-logging/index.d.ts +3 -0
  44. package/dist/builtins/console-logging/index.js +104 -0
  45. package/dist/builtins/console-logging/index.mjs +95 -0
  46. package/dist/builtins/device-manager/device-config-contribution.d.ts +32 -0
  47. package/dist/builtins/device-manager/device-event-propagator.d.ts +26 -0
  48. package/dist/builtins/device-manager/device-link-overlay.d.ts +23 -0
  49. package/dist/builtins/device-manager/device-link-resolver.d.ts +15 -0
  50. package/dist/builtins/device-manager/device-manager.addon.d.ts +452 -0
  51. package/dist/builtins/device-manager/device-manager.addon.js +3299 -0
  52. package/dist/builtins/device-manager/device-manager.addon.mjs +3292 -0
  53. package/dist/builtins/device-manager/index.d.ts +2 -0
  54. package/dist/builtins/device-manager/index.js +8 -0
  55. package/dist/builtins/device-manager/index.mjs +2 -0
  56. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +44 -0
  57. package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +15 -0
  58. package/dist/builtins/hub-forwarder/index.d.ts +3 -0
  59. package/dist/builtins/hub-forwarder/index.js +154 -0
  60. package/dist/builtins/hub-forwarder/index.mjs +145 -0
  61. package/dist/builtins/local-auth/auth-schema.d.ts +26 -0
  62. package/dist/builtins/local-auth/index.d.ts +1 -0
  63. package/dist/builtins/local-auth/index.js +4 -0
  64. package/dist/builtins/local-auth/index.mjs +2 -0
  65. package/dist/builtins/local-auth/local-auth.addon.d.ts +18 -0
  66. package/dist/builtins/local-auth/local-auth.addon.js +8094 -0
  67. package/dist/builtins/local-auth/local-auth.addon.mjs +8063 -0
  68. package/dist/builtins/local-auth/oauth-grants.d.ts +45 -0
  69. package/dist/builtins/local-auth/oauth-session-manager.d.ts +50 -0
  70. package/dist/builtins/local-network/index.d.ts +2 -0
  71. package/dist/builtins/local-network/index.js +10 -0
  72. package/dist/builtins/local-network/index.mjs +2 -0
  73. package/dist/builtins/local-network/local-network.addon.d.ts +150 -0
  74. package/dist/builtins/local-network/local-network.addon.js +489 -0
  75. package/dist/builtins/local-network/local-network.addon.mjs +477 -0
  76. package/dist/builtins/native-metrics/index.d.ts +2 -0
  77. package/dist/builtins/native-metrics/native-metrics-provider.d.ts +48 -0
  78. package/dist/builtins/native-metrics/native-metrics.addon.d.ts +73 -0
  79. package/dist/builtins/native-metrics/native-metrics.addon.js +922 -0
  80. package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -0
  81. package/dist/builtins/platform-probe/hardware-decode-accel-probe.d.ts +37 -0
  82. package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts +13 -0
  83. package/dist/builtins/platform-probe/index.d.ts +22 -0
  84. package/dist/builtins/platform-probe/index.js +834 -0
  85. package/dist/builtins/platform-probe/index.mjs +822 -0
  86. package/dist/builtins/platform-probe/inference-config-resolver.d.ts +29 -0
  87. package/dist/builtins/platform-probe/intel-accelerators.d.ts +11 -0
  88. package/dist/builtins/platform-probe/platform-scorer.d.ts +30 -0
  89. package/dist/builtins/platform-probe/runtime-packages.d.ts +6 -0
  90. package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +96 -0
  91. package/dist/builtins/remote-access-orchestrator/index.d.ts +1 -0
  92. package/dist/builtins/remote-access-orchestrator/index.js +8 -0
  93. package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
  94. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +40 -0
  95. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +214 -0
  96. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +208 -0
  97. package/dist/builtins/shared/settle-sources.d.ts +22 -0
  98. package/dist/builtins/snapshot/index.d.ts +2 -0
  99. package/dist/builtins/snapshot/index.js +494 -0
  100. package/dist/builtins/snapshot/index.mjs +488 -0
  101. package/dist/builtins/snapshot/snapshot.addon.d.ts +120 -0
  102. package/dist/builtins/sqlite-storage/config-store.d.ts +8 -0
  103. package/dist/builtins/sqlite-storage/device-store.d.ts +23 -0
  104. package/dist/builtins/sqlite-storage/filesystem-browse-provider.d.ts +25 -0
  105. package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +83 -0
  106. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
  107. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +396 -0
  108. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +388 -0
  109. package/dist/builtins/sqlite-storage/index.d.ts +8 -0
  110. package/dist/builtins/sqlite-storage/index.js +62 -0
  111. package/dist/builtins/sqlite-storage/index.mjs +49 -0
  112. package/dist/builtins/sqlite-storage/integration-registry.d.ts +27 -0
  113. package/dist/builtins/sqlite-storage/path-guard.d.ts +4 -0
  114. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +102 -0
  115. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +14 -0
  116. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +644 -0
  117. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +636 -0
  118. package/dist/builtins/storage-orchestrator/index.d.ts +6 -0
  119. package/dist/builtins/storage-orchestrator/index.js +10 -0
  120. package/dist/builtins/storage-orchestrator/index.mjs +2 -0
  121. package/dist/builtins/storage-orchestrator/location-store.d.ts +49 -0
  122. package/dist/builtins/storage-orchestrator/provider-discovery.d.ts +10 -0
  123. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +103 -0
  124. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1138 -0
  125. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1128 -0
  126. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +236 -0
  127. package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +38 -0
  128. package/dist/builtins/system-backup/system-backup.service.d.ts +137 -0
  129. package/dist/builtins/system-config/index.d.ts +1 -0
  130. package/dist/builtins/system-config/index.js +8 -0
  131. package/dist/builtins/system-config/index.mjs +2 -0
  132. package/dist/builtins/system-config/system-config.addon.d.ts +10 -0
  133. package/dist/builtins/system-config/system-config.addon.js +232 -0
  134. package/dist/builtins/system-config/system-config.addon.mjs +226 -0
  135. package/dist/builtins/winston-logging/index.d.ts +3 -0
  136. package/dist/builtins/winston-logging/index.js +156 -0
  137. package/dist/builtins/winston-logging/index.mjs +144 -0
  138. package/dist/builtins/winston-logging/winston-destination.d.ts +21 -0
  139. package/dist/builtins/winston-logging/winston-logging.addon.d.ts +19 -0
  140. package/dist/chunk-CNf5ZN-e.mjs +37 -0
  141. package/dist/chunk-Cek0wNdY.js +64 -0
  142. package/dist/download/model-download-service.d.ts +41 -0
  143. package/dist/download/model-downloader.d.ts +31 -0
  144. package/dist/events/event-bus.d.ts +10 -0
  145. package/dist/events/system-event-bus.d.ts +14 -0
  146. package/dist/feature/feature-manager.d.ts +11 -0
  147. package/dist/formatter-B7qW8bPJ.mjs +162 -0
  148. package/dist/formatter-DqAKDlvN.js +167 -0
  149. package/dist/http/authenticated-file-server.d.ts +53 -0
  150. package/dist/http/data-plane-registry.d.ts +23 -0
  151. package/dist/http/file-data-plane.d.ts +10 -0
  152. package/dist/http/reverse-proxy.d.ts +15 -0
  153. package/dist/index.d.ts +82 -0
  154. package/dist/index.js +93485 -0
  155. package/dist/index.mjs +93179 -0
  156. package/dist/intel-accelerators-Gg0P5mnl.js +20 -0
  157. package/dist/intel-accelerators-hGgpZ0pX.mjs +19 -0
  158. package/dist/kernel/addon-class-resolver.d.ts +4 -0
  159. package/dist/kernel/addon-engine-manager.d.ts +22 -0
  160. package/dist/kernel/addon-health-monitor.d.ts +154 -0
  161. package/dist/kernel/addon-installer.d.ts +208 -0
  162. package/dist/kernel/addon-loader.d.ts +106 -0
  163. package/dist/kernel/addon-manifest.d.ts +77 -0
  164. package/dist/kernel/capability-handle.d.ts +46 -0
  165. package/dist/kernel/capability-registry.d.ts +412 -0
  166. package/dist/kernel/config-manager.d.ts +212 -0
  167. package/dist/kernel/config-schema.d.ts +93 -0
  168. package/dist/kernel/custom-action-registry.d.ts +23 -0
  169. package/dist/kernel/deps/addon-deps-manager.d.ts +19 -0
  170. package/dist/kernel/deps/manifest-native-deps.d.ts +25 -0
  171. package/dist/kernel/deps/manifest-python-deps.d.ts +20 -0
  172. package/dist/kernel/device-registry.d.ts +29 -0
  173. package/dist/kernel/fs-utils.d.ts +41 -0
  174. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +19 -0
  175. package/dist/kernel/hwaccel/hwaccel-service.d.ts +4 -0
  176. package/dist/kernel/index.d.ts +74 -0
  177. package/dist/kernel/infra-capabilities.d.ts +13 -0
  178. package/dist/kernel/moleculer/addon-context-factory.d.ts +91 -0
  179. package/dist/kernel/moleculer/addon-data-plane-facility.d.ts +19 -0
  180. package/dist/kernel/moleculer/addon-runner.d.ts +1 -0
  181. package/dist/kernel/moleculer/addon-service-factory.d.ts +50 -0
  182. package/dist/kernel/moleculer/broker-factory.d.ts +50 -0
  183. package/dist/kernel/moleculer/cap-usage-registry.d.ts +46 -0
  184. package/dist/kernel/moleculer/capabilities-access.d.ts +21 -0
  185. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +46 -0
  186. package/dist/kernel/moleculer/child-cap-dispatch.d.ts +20 -0
  187. package/dist/kernel/moleculer/cluster-secret.d.ts +15 -0
  188. package/dist/kernel/moleculer/core-cap-service.d.ts +50 -0
  189. package/dist/kernel/moleculer/crash-supervisor.d.ts +50 -0
  190. package/dist/kernel/moleculer/device-cap-proxy.d.ts +79 -0
  191. package/dist/kernel/moleculer/event-bus-core.d.ts +53 -0
  192. package/dist/kernel/moleculer/event-bus.d.ts +53 -0
  193. package/dist/kernel/moleculer/hub-log-forwarder.d.ts +36 -0
  194. package/dist/kernel/moleculer/hub-service.d.ts +35 -0
  195. package/dist/kernel/moleculer/node-registry.d.ts +126 -0
  196. package/dist/kernel/moleculer/process-context.d.ts +4 -0
  197. package/dist/kernel/moleculer/process-service.d.ts +72 -0
  198. package/dist/kernel/moleculer/provider-registry.d.ts +28 -0
  199. package/dist/kernel/moleculer/readiness-context.d.ts +62 -0
  200. package/dist/kernel/moleculer/readiness-service.d.ts +7 -0
  201. package/dist/kernel/moleculer/register-node-client.d.ts +35 -0
  202. package/dist/kernel/moleculer/remote-logger.d.ts +43 -0
  203. package/dist/kernel/moleculer/resilient-cap-call.d.ts +28 -0
  204. package/dist/kernel/moleculer/stream-probe-service.d.ts +9 -0
  205. package/dist/kernel/moleculer/trpc-links.d.ts +189 -0
  206. package/dist/kernel/moleculer/typed-array-serde.d.ts +25 -0
  207. package/dist/kernel/moleculer/worker-device-restore.d.ts +10 -0
  208. package/dist/kernel/provider-kind-drift.d.ts +12 -0
  209. package/dist/kernel/restart-coordinator.d.ts +90 -0
  210. package/dist/kernel/storage-location-registry.d.ts +40 -0
  211. package/dist/kernel/transport/cap-action-name.d.ts +100 -0
  212. package/dist/kernel/transport/cap-route-resolver.d.ts +148 -0
  213. package/dist/kernel/transport/cap-route.d.ts +148 -0
  214. package/dist/kernel/transport/child-cap-protocol.d.ts +136 -0
  215. package/dist/kernel/transport/create-local-transport.d.ts +7 -0
  216. package/dist/kernel/transport/frame-codec.d.ts +7 -0
  217. package/dist/kernel/transport/index.d.ts +27 -0
  218. package/dist/kernel/transport/local-child-client.d.ts +136 -0
  219. package/dist/kernel/transport/local-child-registry.d.ts +179 -0
  220. package/dist/kernel/transport/local-endpoint-path.d.ts +6 -0
  221. package/dist/kernel/transport/local-transport.d.ts +46 -0
  222. package/dist/kernel/transport/parent-unowned-call.d.ts +75 -0
  223. package/dist/kernel/transport/socket-channel.d.ts +27 -0
  224. package/dist/kernel/transport/uds-event-bridge.d.ts +36 -0
  225. package/dist/kernel/transport/uds-event-bus.d.ts +22 -0
  226. package/dist/kernel/transport/uds-local-transport.d.ts +18 -0
  227. package/dist/kernel/transport/uds-log-ingest.d.ts +28 -0
  228. package/dist/kernel/transport/uds-logger.d.ts +44 -0
  229. package/dist/kernel/utils/ring-buffer.d.ts +15 -0
  230. package/dist/kernel/workspace-detect.d.ts +9 -0
  231. package/dist/lifecycle/lifecycle-state-machine.d.ts +28 -0
  232. package/dist/logging/formatter.d.ts +30 -0
  233. package/dist/logging/log-manager.d.ts +54 -0
  234. package/dist/logging/log-ring-buffer.d.ts +47 -0
  235. package/dist/logging/partitioned-log-buffer.d.ts +35 -0
  236. package/dist/logging/scoped-logger.d.ts +17 -0
  237. package/dist/main-DNnMW7Z2.js +9983 -0
  238. package/dist/main-rtjOwPBR.mjs +9976 -0
  239. package/dist/manifest-python-deps-D1DbAQEv.js +6724 -0
  240. package/dist/manifest-python-deps-DZsKTbs1.mjs +6315 -0
  241. package/dist/network/network-quality.d.ts +11 -0
  242. package/dist/notification/notification-service.d.ts +37 -0
  243. package/dist/notification/toast-service.d.ts +22 -0
  244. package/dist/pipeline/engine-manager-resolver.d.ts +15 -0
  245. package/dist/pipeline/pipeline-runner.d.ts +8 -0
  246. package/dist/pipeline/pipeline-validator.d.ts +13 -0
  247. package/dist/process/resource-monitor.d.ts +11 -0
  248. package/dist/python/python-env-manager.d.ts +12 -0
  249. package/dist/repl/interfaces.d.ts +31 -0
  250. package/dist/repl/repl-engine.d.ts +8 -0
  251. package/dist/resource-monitor-ClDGFyf6.mjs +57 -0
  252. package/dist/resource-monitor-IIEanuJt.js +74 -0
  253. package/dist/settle-sources-Bhsy57y-.js +38 -0
  254. package/dist/settle-sources-CDtNC8ub.mjs +33 -0
  255. package/dist/storage/fs-storage-backend.d.ts +40 -0
  256. package/dist/storage/storage-location-manager.d.ts +23 -0
  257. package/dist/storage/storage-manager.d.ts +83 -0
  258. package/dist/tar-BgAEMRBR.js +5434 -0
  259. package/dist/tar-ByMOPNM0.mjs +5429 -0
  260. package/dist/tls/cert-manager.d.ts +26 -0
  261. package/dist/tls/index.d.ts +1 -0
  262. package/package.json +343 -0
@@ -0,0 +1,452 @@
1
+ import { ProviderRegistration, BaseAddon, DeviceBindingEntry } from '@camstack/types';
2
+ /**
3
+ * Wire shape matching `z.infer<typeof SettingsSchemaWithValuesSchema>` —
4
+ * duplicated as a plain interface because importing the Zod schema across
5
+ * package boundaries confuses `tsc` when the types package pins a
6
+ * different `zod` minor than the core package. Keeping the shape local
7
+ * keeps the addon decoupled from the schema's internal type encoding.
8
+ */
9
+ interface ContributionShape {
10
+ tabs?: Array<{
11
+ id: string;
12
+ label: string;
13
+ icon: string;
14
+ order?: number;
15
+ }>;
16
+ sections: Array<{
17
+ id: string;
18
+ title: string;
19
+ description?: string;
20
+ style?: 'card' | 'accordion';
21
+ defaultCollapsed?: boolean;
22
+ columns?: 1 | 2 | 3 | 4;
23
+ tab?: string;
24
+ /** Where the section renders. Default 'settings' (Config tab); 'top-tab' hoists into the device-detail tab bar via DeviceDetail discovery. */
25
+ location?: 'settings' | 'top-tab';
26
+ order?: number;
27
+ fields: unknown[];
28
+ }>;
29
+ }
30
+ export declare function mergeAggregates(parts: readonly ContributionShape[]): ContributionShape;
31
+ export declare class DeviceManagerAddon extends BaseAddon {
32
+ constructor();
33
+ /** Shorthand for the kernel-injected capability registry. */
34
+ private get capabilityRegistry();
35
+ /**
36
+ * Parent-chain event propagator. Started in `onInitialize` once the
37
+ * hub's `deviceRegistry` is available; listens to every device-sourced
38
+ * event and re-emits a copy on each ancestor scope with `via[]`
39
+ * populated. Stopped in `onShutdown`.
40
+ */
41
+ private propagator;
42
+ /**
43
+ * Hub-side mirror of every device's cap-keyed runtime state.
44
+ * Populated whenever any caller writes via `deviceState.setCapSlice`
45
+ * (the canonical cross-layer write entrypoint) and on first load
46
+ * via `loadRuntimeState`. Cross-process consumers reach the mirror
47
+ * through the `deviceState` cap router; per-cap event subscribers
48
+ * (e.g. `battery.onStatusChanged`) get the same data via
49
+ * cap-specific events still emitted by the owning device.
50
+ *
51
+ * Key: deviceId. Value: per-cap slice map. Empty by default —
52
+ * slices show up as `setCapSlice` calls trickle in.
53
+ */
54
+ private readonly stateMirror;
55
+ /**
56
+ * Per-device disk-write debouncer for runtime-state. `setCapSlice`
57
+ * updates the in-memory mirror synchronously and emits the change
58
+ * event immediately, but the disk write is coalesced — frequent
59
+ * back-to-back writes (motion phase transitions, battery pushes,
60
+ * etc.) collapse to one `writeDeviceRuntimeState` per
61
+ * `RUNTIME_STATE_DEBOUNCE_MS` window. `flushRuntimeStateWrites`
62
+ * awaits any in-flight write + scheduled flush so shutdown is
63
+ * lossless.
64
+ */
65
+ private readonly runtimeStateDebounce;
66
+ private static readonly RUNTIME_STATE_DEBOUNCE_MS;
67
+ /**
68
+ * Cross-process native-provider cache: deviceId (numeric) → capName → { addonId, nodeId }.
69
+ * Kept in sync with `DeviceBindingsChanged` push events emitted by forked
70
+ * workers on `ctx.registerNativeCap` / device removal. Union'd into
71
+ * `getBindings` so hub-side consumers see every native cap regardless of
72
+ * which process owns the IDevice.
73
+ *
74
+ * No persistence — entries re-populate when the worker re-handshakes or
75
+ * re-emits its native-cap registrations after restart. Entries that were
76
+ * lost in the Moleculer transport handshake window are recovered lazily:
77
+ * `resolveNativeCapOwnerSync` and `getBindings` fall through to
78
+ * `ctx.kernel.listClusterNativeCaps()` (the handshake-fed
79
+ * `HubNodeRegistry`) when the push-based cache misses.
80
+ *
81
+ * The previous pull-based recovery (`syncWorkerNativeCaps`, driven by
82
+ * `$node.connected` + `addon.restarted`) has been removed in Task 13 —
83
+ * the D3 re-handshake after device restore is the reliable replacement.
84
+ */
85
+ private remoteNativeCaps;
86
+ /** Device ids that currently have at least one `deviceLinks` entry. O(1) gate
87
+ * consulted by `resolveLinkedStatus` so the cap-mount overlay is a no-op for
88
+ * the vast majority of devices that have no links. Rebuilt on restore. */
89
+ private readonly devicesWithLinks;
90
+ /** Whether a device currently has cross-device links. */
91
+ devicesWithLinksHas(deviceId: number): boolean;
92
+ /** `${targetDeviceId}:${targetCap}` → resolved links feeding that cap's slice. */
93
+ private linkTargets;
94
+ /** `${sourceDeviceId}:${sourceCap}` → targets to recompute when that source changes. */
95
+ private linkDependents;
96
+ /** Loop/churn guard: last overlaid slice emitted per `${deviceId}:${cap}`. */
97
+ private readonly lastEmittedOverlay;
98
+ /** Expected source `stableId`s (`${container}-${sourceKey}`) across all links,
99
+ * resolved or not — gates the `registerDevice` rebuild so only a registering
100
+ * device that IS a link source triggers a reindex (not every boot restore). */
101
+ private expectedSourceStableIds;
102
+ /** Test/diagnostic accessors. */
103
+ linkTargetKeys(): string[];
104
+ linkDependentsKeys(): string[];
105
+ /** Wait for a device-provider by addonId, returning null on timeout. */
106
+ private waitDeviceProvider;
107
+ /** Require a device-provider by addonId — throws if not found. */
108
+ private requireDeviceProvider;
109
+ /** Require a device-adoption provider by addonId — throws if not found. */
110
+ private requireDeviceAdoptionProvider;
111
+ private readBindingsStore;
112
+ private writeBindingsStore;
113
+ private resolveWrapperNodeId;
114
+ /**
115
+ * Reduce a provider node id to the routable form `DeviceProxy` can pin.
116
+ *
117
+ * Every addon runs in its own `addon-runner` with the composite node id
118
+ * `${parentNodeId}/${runnerId}` (see `addon-runner.ts`) — e.g.
119
+ * `hub/provider-reolink` or `dev-agent-0/provider-reolink`. That composite is
120
+ * an IDENTITY, not a routable target: the `CapRouteResolver` reaches a child
121
+ * only THROUGH its parent (the hub resolves a hub-local-uds child by
122
+ * cap+device; an agent forwards to its own child). `DeviceProxy` pins
123
+ * `entry.providerNodeId` on every cap call, so a binding entry must expose the
124
+ * parent node id — otherwise the explicit pin classifies as `remote-moleculer`
125
+ * to an unknown node → `no-provider`, which surfaces as
126
+ * "this camera doesn't expose …" for client-proxy-driven widget caps
127
+ * (motion-zones, privacy-mask). Wrappers already report the parent via
128
+ * `resolveWrapperNodeId`; this aligns natives with the same contract.
129
+ *
130
+ * A flat node id (a genuine standalone node with no `/`) is returned
131
+ * unchanged.
132
+ */
133
+ private toRoutableProviderNodeId;
134
+ /**
135
+ * Resolve a remote native cap entry for a given `(capName, deviceId)` by
136
+ * consulting the handshake-fed `HubNodeRegistry` via
137
+ * `ctx.kernel.listClusterNativeCaps()`. Called when the push-based
138
+ * `remoteNativeCaps` cache misses — covers the Moleculer transport
139
+ * handshake window where `DeviceBindingsChanged` events were lost but the
140
+ * D3 re-handshake (post device restore) has already populated the registry.
141
+ *
142
+ * Returns `null` when the entry is genuinely not present in the cluster
143
+ * view (cap not registered on any worker for that device).
144
+ */
145
+ private resolveRemoteNativeCapFromRegistry;
146
+ getBindings(input: {
147
+ deviceId: number;
148
+ }): Promise<{
149
+ deviceId: number;
150
+ entries: DeviceBindingEntry[];
151
+ }>;
152
+ /**
153
+ * Whole-fleet binding dump. Iterates every device known to the
154
+ * deviceRegistry and reuses the per-device `getBindings` resolver
155
+ * for each — same routing rules, single round-trip. Used by
156
+ * `SystemManager.init()` for warm-boot.
157
+ *
158
+ * Bindings change rarely (wrapper toggle, device add/remove) so
159
+ * clients invalidate via the existing
160
+ * `capability.binding-changed` event rather than re-fetching this
161
+ * payload periodically.
162
+ */
163
+ getAllBindings(): Promise<Array<{
164
+ deviceId: number;
165
+ entries: DeviceBindingEntry[];
166
+ }>>;
167
+ /**
168
+ * Resolve a numeric deviceId to a stableId via persisted meta.
169
+ * Used only by the device-identity section of the device-details
170
+ * aggregator (see `buildBaseDeviceSection`) to surface the stableId as
171
+ * a readonly display field. All runtime/registry lookups are keyed by
172
+ * numeric deviceId; this helper is display-only.
173
+ */
174
+ private lookupPersistedStableId;
175
+ getDeviceAggregate(deviceId: number, kind: 'settings' | 'live'): Promise<ContributionShape | null>;
176
+ /**
177
+ * System-scoped per-device contributions — the deliberate exception to
178
+ * binding-driven aggregation (D12).
179
+ *
180
+ * A `scope: 'system'` cap with `exposesDeviceSettings: true` holds per-device
181
+ * state but is NOT bound per-device: it is a system addon, not a BaseDevice,
182
+ * so it never calls `registerNativeCap` and never appears in
183
+ * `getBindings(deviceId)`. The binding-driven loop therefore skips it and its
184
+ * per-device panel never renders. Two such caps ship today:
185
+ * - `stream-broker` (singleton) — the RTSP-restream / pre-buffer settings
186
+ * tab, scoped to the cameras whose streams it serves.
187
+ * - `device-export` (collection) — the "Export" panel; a device can be
188
+ * exposed to MULTIPLE exporters at once (Alexa + HomeKit + HA-MQTT).
189
+ *
190
+ * D12 bans fanning a per-device call out to every same-named provider of a
191
+ * `scope: 'device'` cap, because vendor providers SHARE cap names
192
+ * (`stream-params`/`ptz` from reolink AND hikvision). System caps are NOT
193
+ * vendor-shared — a system cap name maps to one active provider (singleton)
194
+ * or one declared collection — so consulting the cap's own provider(s)
195
+ * directly is safe. Each provider gates internally by deviceId and returns
196
+ * null for devices it does not own.
197
+ *
198
+ * `seenCaps` skips any system cap that already contributed via a binding so
199
+ * its section is never duplicated.
200
+ */
201
+ private collectSystemDeviceContributions;
202
+ /**
203
+ * D14: framework-derived device-config contribution.
204
+ *
205
+ * `kind === 'live'` — device-config caps contribute nothing to the live
206
+ * aggregate (they hold editable config, not live observables).
207
+ *
208
+ * `ui.kind === 'widget'` — emits a single structural `type:'widget'`
209
+ * section; the widget self-persists via the cap's own mutations.
210
+ *
211
+ * `ui.kind === 'derived-form'` — calls `getOptions`/`getStatus` on the
212
+ * bound provider, runs the registered pure builder, and returns the
213
+ * derived form sections. Returns null when the camera exposes nothing
214
+ * configurable or the provider is not yet registered.
215
+ */
216
+ private deriveDeviceConfigContribution;
217
+ /**
218
+ * Build the device-manager's own contribution to the aggregator — the
219
+ * device identity (id, stableId, addonId, type, online) + the
220
+ * driver-specific config exposed by the device class via
221
+ * `zodEntriesToConfigUI`.
222
+ *
223
+ * Two paths, deliberately symmetric with `getSettingsSchema`:
224
+ *
225
+ * - Hub-local: device's IDevice instance lives in this process'
226
+ * DeviceRegistry, we read config + schema directly by reference.
227
+ * - Cross-process: device lives in a forked worker (RtspCamera on
228
+ * provider-rtsp, ONVIF on provider-onvif, …). We ask the worker's
229
+ * `device-ops.getSettingsSchema` native provider for a wire-
230
+ * serializable ConfigUISchema and merge it in under the same
231
+ * "Driver Config" section, so the UI sees the same shape regardless
232
+ * of where the IDevice physically runs.
233
+ *
234
+ * Returns `null` only when the device genuinely doesn't exist anywhere
235
+ * (no hub-local, no persisted ownership, no device-ops native). The
236
+ * aggregator falls back to contributor sections only in that case.
237
+ */
238
+ private buildBaseDeviceSection;
239
+ /**
240
+ * Lookup the native owner for `device-ops` on `deviceId` — the native-cap
241
+ * registry (hub-local and remote) is keyed by numeric id.
242
+ */
243
+ private resolveNativeDeviceOwner;
244
+ /**
245
+ * Aggregate `status` across every registered cap for a device.
246
+ *
247
+ * Walks the supplied cap list (or `CAP_NAMES_WITH_STATUS` when
248
+ * omitted), looks up a native provider per cap via the capability
249
+ * registry, calls `provider.getStatus({ deviceId })`, and validates
250
+ * the return against the cap's own `status.schema`. Validation
251
+ * failures log a warning and yield `null` for that cap so the
252
+ * overall aggregate stays usable — a single misbehaving provider
253
+ * must not blank out a device's entire status view.
254
+ *
255
+ * Returned shape is `Record<capName, unknown | null>`; the client-
256
+ * side hook tightens this to `CapStatusTypeMap` via the generated
257
+ * `cap-status-types.ts`.
258
+ */
259
+ private getDeviceStatusAggregate;
260
+ /**
261
+ * Return the driver-specific device-settings contribution. Hub-local
262
+ * devices call `getSettingsUISchema()` directly; forked-worker devices
263
+ * go through the `device-ops.getSettingsSchema` cap method on the
264
+ * numeric-id-keyed native registry.
265
+ *
266
+ * Returns a discriminated result so callers can distinguish three states:
267
+ * 'ok' – schema obtained successfully
268
+ * 'none' – driver genuinely has no settings schema
269
+ * 'unavailable' – worker was unreachable after retries (transient)
270
+ */
271
+ private resolveDriverConfigSchema;
272
+ updateDeviceField(input: {
273
+ deviceId: number;
274
+ writerCapName: string;
275
+ writerAddonId: string;
276
+ key: string;
277
+ value: unknown;
278
+ }): Promise<{
279
+ success: true;
280
+ }>;
281
+ /**
282
+ * Dispatch a device custom action. Hub-local devices run it directly;
283
+ * forked/remote devices route through the `device-ops` native cap
284
+ * (`runAction`) — the same hub-local-then-device-ops fan-out that
285
+ * `updateDeviceField` uses for `applySettingsPatch`.
286
+ */
287
+ private dispatchDeviceAction;
288
+ /**
289
+ * Resolve the `DeviceSettingsContribution` provider that owns a tagged
290
+ * field. The `writerAddonId` on a tagged field equals `entry.providerAddonId`
291
+ * from the binding that produced it — for `kind:'wrapped'` entries, that is
292
+ * the wrapper addon id (e.g. 'snapshot-addon'); for native-only entries,
293
+ * the system addon id.
294
+ *
295
+ * Resolution order (Bug-3 fix):
296
+ * 1. `getProviderByAddon(capName, writerAddonId)` — resolves the
297
+ * system-registered provider by the addon id from the tagged field.
298
+ * For wrapper bindings (snapshot, motion-detection, etc.) this directly
299
+ * returns the wrapper provider, bypassing the native-first resolution
300
+ * order of `getProviderForDevice` that caused "method not found".
301
+ * 2. `getSingleton(capName)` — fallback for stale/mismatched writerAddonIds.
302
+ * The active singleton handles the contribution even if the addonId
303
+ * stored in the field is out of date (e.g. after an addon rename).
304
+ *
305
+ * `getProviderForDevice` is intentionally NOT used here: it returns the
306
+ * per-device native first when present (e.g. Reolink/ONVIF), and the native
307
+ * does NOT implement contribution methods — the root cause of Bug-3.
308
+ */
309
+ private resolveContributionProvider;
310
+ /**
311
+ * Batched counterpart of `updateDeviceField`. Groups changes by
312
+ * `(writerCapName, writerAddonId)` so each contributor receives a
313
+ * single `applyDeviceSettingsPatch` with all of its updates merged —
314
+ * avoids N round-trips for simultaneous edits in the same save.
315
+ *
316
+ * Per-provider failures are captured in the `failures[]` output so the
317
+ * admin UI can highlight which sections didn't persist; a failure on
318
+ * one provider does NOT abort the others.
319
+ */
320
+ updateDeviceFieldsBatch(input: {
321
+ deviceId: number;
322
+ changes: ReadonlyArray<{
323
+ writerCapName: string;
324
+ writerAddonId: string;
325
+ key: string;
326
+ value: unknown;
327
+ }>;
328
+ }): Promise<{
329
+ success: true;
330
+ failures: {
331
+ writerCapName: string;
332
+ writerAddonId: string;
333
+ error: string;
334
+ }[];
335
+ }>;
336
+ /** Apply a single grouped patch to the appropriate provider. Mirrors
337
+ * `updateDeviceField` routing (special-case device-manager, else
338
+ * registry lookup). Used by `updateDeviceFieldsBatch`. */
339
+ private applyGroupPatch;
340
+ listWrappersForCap(input: {
341
+ capName: string;
342
+ }): Promise<string[]>;
343
+ listBindableCapsForDeviceType(input: {
344
+ deviceType: string;
345
+ }): Promise<Array<{
346
+ capName: string;
347
+ wrappers: string[];
348
+ }>>;
349
+ setWrapperActive(input: {
350
+ deviceId: number;
351
+ capName: string;
352
+ wrapperAddonId: string;
353
+ active: boolean;
354
+ }): Promise<void>;
355
+ protected onInitialize(): Promise<ProviderRegistration[] | void>;
356
+ /**
357
+ * Single-cap mirror update — diff against the current mirror,
358
+ * persist the new slice in-memory, emit `DeviceStateChanged` for
359
+ * this cap. No-op on identical writes (both same shape and same
360
+ * values). Called by `setCapSlice` provider.
361
+ */
362
+ private applySingleCapUpdate;
363
+ /**
364
+ * Debounced disk writer. Coalesces frequent writes (motion phase
365
+ * transitions, battery pushes) into one `writeDeviceRuntimeState`
366
+ * per `RUNTIME_STATE_DEBOUNCE_MS` window. Reads the per-device
367
+ * blob from the live mirror at flush time so the disk picture is
368
+ * always the latest state — no risk of writing a stale snapshot.
369
+ */
370
+ private scheduleRuntimeStateDiskWrite;
371
+ /**
372
+ * One-shot mirror seed used by `loadRuntimeState` at boot so the
373
+ * hub knows about every persisted slice without waiting for the
374
+ * first `setCapSlice` call. No events emitted — this is
375
+ * initial-state population, not a transition.
376
+ *
377
+ * Callers that must not carry a stale per-session probe across a
378
+ * restart pass the blob through `withResetSessionProbe` first (see
379
+ * `loadRuntimeState`).
380
+ */
381
+ private seedMirror;
382
+ /**
383
+ * The hub mirror's `feature-probe.lastProbedAt` is a PER-SESSION liveness
384
+ * signal — it means "this worker process completed a probe THIS session".
385
+ * Persisted runtime state carries the PRE-RESTART timestamp, which is stale
386
+ * after a hub or worker restart: the device has not re-probed yet. Seeding it
387
+ * verbatim makes `resolveDeviceProbed` report `probed:true` during the
388
+ * restart→reprobe window, which defeats the export carry-forward gate
389
+ * (`resolveExportFingerprint`, gated on `device.probed`) and posts a spurious
390
+ * partial `AddOrUpdateReport` to Alexa/HAP before the real probe lands.
391
+ *
392
+ * Reset `lastProbedAt` to 0 for the MIRROR seed only — `probed:false` carries
393
+ * the last-advertised fingerprint forward until the worker republishes a
394
+ * fresh probe (its post-probe `setCapSlice` raises `lastProbedAt` again, which
395
+ * also fires `DeviceReady`). The worker's returned `initialRuntimeState` blob
396
+ * is untouched, and every non-probe slice (e.g. `device-status`/online) is
397
+ * preserved.
398
+ */
399
+ private withResetSessionProbe;
400
+ /**
401
+ * Resolve a device's REAL `online` flag for the persisted/forked-worker
402
+ * list branch. Forked workers own the live `IDevice` in their own process,
403
+ * so the hub registry can't read `device.online` directly. The owning
404
+ * driver instead publishes its liveness through the auto-registered
405
+ * `device-status` runtime-state slice (`markOnline` → `setCapState`), which
406
+ * the canonical `deviceState.setCapSlice` write entrypoint mirrors into the
407
+ * hub-side `stateMirror`. We read that mirrored slice here so the list
408
+ * payload reflects the device's actual reachability instead of a constant.
409
+ *
410
+ * Fallback (`fallbackOnline`) preserves the legacy behaviour when no slice
411
+ * has been published yet: a persisted device with a live registry is
412
+ * assumed online (it was successfully registered by its owning process),
413
+ * and the null-registry "offline view" keeps reporting offline. We never
414
+ * regress a device to offline merely because its mirror is empty.
415
+ */
416
+ private resolveDeviceOnline;
417
+ /**
418
+ * Derive the `probed` flag for an offline-view (forked-worker, not
419
+ * live in the hub registry) device projection. Reads the mirrored
420
+ * `feature-probe` slice the owning worker publishes. Mirrors the
421
+ * `toDeviceInfo` rule: no mirrored slice → ready (`true`, no probe seen);
422
+ * slice present → ready iff `lastProbedAt` has advanced past 0. The
423
+ * mirror is populated when the worker's first `setCapSlice` RPC arrives
424
+ * (BaseDevice seeds `feature-probe` `lastProbedAt:0` at construction, but
425
+ * cross-process delivery is async); until then the no-entry path returns
426
+ * `true` — a brief transient window, same as `resolveDeviceOnline`.
427
+ */
428
+ private resolveDeviceProbed;
429
+ private snapshotForDevice;
430
+ /**
431
+ * Read-time overlay of a cap slice with its cross-device linked values.
432
+ * Returns a cloned raw mirror slice when the (device, cap) pair has no
433
+ * links. Sources are read from the same in-hub stateMirror — sync, no
434
+ * cross-process call. The disk writer must NOT use this method; it must
435
+ * persist raw provider truth via snapshotForDevice.
436
+ */
437
+ private overlayedSlice;
438
+ /**
439
+ * Like snapshotForDevice but applies the device-link overlay per cap.
440
+ * Used exclusively by the device-state READ methods (getSnapshot,
441
+ * getAllSnapshots) so callers see overlayed values. The debounced disk
442
+ * writer must continue to call snapshotForDevice (raw truth).
443
+ */
444
+ private snapshotForDeviceOverlayed;
445
+ private emitStateChanged;
446
+ /** Emit DeviceStateChanged for (deviceId, cap) using the OVERLAID slice,
447
+ * skipping when the overlay is unchanged since the last emit (loop/churn
448
+ * guard). Used for the written pair AND its dependent targets. */
449
+ private emitOverlayed;
450
+ protected onShutdown(): Promise<void>;
451
+ }
452
+ export default DeviceManagerAddon;