@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,21 @@
1
+ import { ServiceBroker } from 'moleculer';
2
+ import { BrokerRegistries } from './provider-registry.js';
3
+ /**
4
+ * Build `ctx.capabilities` for a worker context.
5
+ *
6
+ * Broker mode (hub / agent / in-process addons): merges the local registry
7
+ * (providers from THIS process) with cross-process discovery via the
8
+ * Moleculer service registry — remote providers are returned as Proxy
9
+ * objects that forward method calls back through `broker.call(...)`.
10
+ * Synchronous on the read side because Moleculer's service registry is a
11
+ * local in-memory mirror of cluster state (updated via gossip).
12
+ *
13
+ * UDS mode (broker-less forked child, Phase F1+F2): `broker` is `undefined`,
14
+ * so `ctx.capabilities` is LOCAL-ONLY — it sees only providers registered in
15
+ * THIS process. This matches the canonical contract (CLAUDE.md: "`ctx.capabilities`
16
+ * is the LOCAL CapabilityRegistry of the calling addon's group runner"). For
17
+ * cross-process access a UDS child uses `ctx.api`, which routes over UDS to
18
+ * the parent's `onUnownedCall`.
19
+ */
20
+ declare function buildCapabilitiesAccess(broker: ServiceBroker | undefined, localRegs: BrokerRegistries): import('@camstack/types').CapabilitiesAccess;
21
+ export { buildCapabilitiesAccess };
@@ -0,0 +1,46 @@
1
+ import { AddonCallInput } from '../transport/child-cap-protocol.js';
2
+ import { CustomActionRegistry } from '../custom-action-registry.js';
3
+ import { ICamstackAddon, AddonDataPlaneEndpoint } from '@camstack/types';
4
+ /**
5
+ * Serializable HTTP route descriptor sent from a forked child to the hub over
6
+ * UDS. The `handler` function on the live `IAddonHttpRoute` is intentionally
7
+ * OMITTED — MsgPack (the UDS frame codec) cannot encode a function, and the
8
+ * hub re-binds dispatch through the `addon-routes` cap's `invoke` method
9
+ * anyway. Mirrors the `addonRoutesCapability.getRoutes` output schema.
10
+ */
11
+ export interface SerializableRouteDescriptor {
12
+ readonly method: string;
13
+ readonly path: string;
14
+ readonly access?: string;
15
+ readonly description?: string;
16
+ }
17
+ /**
18
+ * Resolved `addon-routes` provider lookup — the live provider object the addon
19
+ * registered (`buildAddonRouteProvider(...)`). Returning `null`/`undefined`
20
+ * means the addon registered no routes.
21
+ */
22
+ export type RouteProviderLookup = (addonId: string) => object | null | undefined;
23
+ /** Injected lookups the addon-call dispatcher uses to resolve addon-level surfaces. */
24
+ export interface ChildAddonCallDispatchDeps {
25
+ /** Resolve the live `addon-routes` provider an addon registered, by addon id. */
26
+ getRouteProvider: RouteProviderLookup;
27
+ /** The runner-wide custom-action registry (populated during the init loop). */
28
+ customActions: CustomActionRegistry;
29
+ /** Resolve the loaded addon instance by id — used for the `settings` surface. */
30
+ getAddonInstance: (addonId: string) => ICamstackAddon | null;
31
+ /** Resolve an addon's live HTTP data-plane endpoints (published by its
32
+ * `ctx.dataPlane` facility). Empty when the addon serves no data-plane. */
33
+ getDataPlanes: (addonId: string) => readonly AddonDataPlaneEndpoint[];
34
+ }
35
+ /**
36
+ * Creates the addon-level dispatcher the addon-runner wires to
37
+ * `LocalChildClient.onAddonCall`. Routes a {@link AddonCallInput} to one of the
38
+ * exhaustive {@link AddonCallTarget} surfaces (routes / custom / settings) —
39
+ * everything the per-addon Moleculer broker used to carry before the UDS
40
+ * migration removed it. The `target` switch is exhaustive (`never` check): a
41
+ * new surface added to the protocol union that isn't dispatched here is a
42
+ * COMPILE ERROR — the guard that makes a "missed link" impossible.
43
+ *
44
+ * Pure module — no Moleculer, no broker, no addon-runner dependency.
45
+ */
46
+ export declare function createChildAddonCallDispatch(deps: ChildAddonCallDispatchDeps): (call: AddonCallInput) => Promise<unknown>;
@@ -0,0 +1,20 @@
1
+ import { CapCallInput } from '../transport/child-cap-protocol.js';
2
+ /**
3
+ * Injected lookups that the dispatcher uses to resolve cap providers. A provider
4
+ * is an opaque object whose methods are resolved structurally (via {@link isCapMethod})
5
+ * at the UDS dispatch boundary. Returning `null`/`undefined` signals "no provider
6
+ * registered".
7
+ */
8
+ export interface ChildCapDispatchDeps {
9
+ /** Resolve a singleton/system-scoped provider by cap name. */
10
+ getSingletonProvider(capName: string): object | null | undefined;
11
+ /** Resolve a device-scoped provider by cap name and device id. */
12
+ getDeviceProvider(capName: string, deviceId: number): object | null | undefined;
13
+ }
14
+ /**
15
+ * Creates a unified dispatcher that routes a {@link CapCallInput} to either a
16
+ * device-scoped or singleton provider, then invokes the requested method.
17
+ *
18
+ * Pure module — no Moleculer, no broker, no addon-runner dependency.
19
+ */
20
+ export declare function createChildCapDispatch(deps: ChildCapDispatchDeps): (call: CapCallInput) => Promise<unknown>;
@@ -0,0 +1,15 @@
1
+ /** Moleculer error `type` marking a registration rejected for a bad cluster secret. */
2
+ export declare const CLUSTER_SECRET_MISMATCH_TYPE = "CLUSTER_SECRET_MISMATCH";
3
+ /** Process exit code a runner uses when its registration is rejected for a bad secret. */
4
+ export declare const CLUSTER_SECRET_REJECTED_EXIT_CODE = 78;
5
+ /** SHA-256 hex digest of a cluster secret. Never transmit or log the raw secret. */
6
+ export declare function hashClusterSecret(secret: string): string;
7
+ /**
8
+ * True if a registration carrying `presentedHash` is allowed against a
9
+ * receiver whose own secret hashes to `expectedHash`.
10
+ * - `expectedHash` undefined → the gate is OFF; everything is allowed.
11
+ * - otherwise `presentedHash` must be present and equal (constant-time).
12
+ */
13
+ export declare function clusterSecretMatches(expectedHash: string | undefined, presentedHash: string | undefined): boolean;
14
+ /** Recognises a cluster-secret rejection, including after a Moleculer RPC round-trip. */
15
+ export declare function isClusterSecretMismatchError(err: unknown): boolean;
@@ -0,0 +1,50 @@
1
+ import { ServiceSchema } from 'moleculer';
2
+ /**
3
+ * Default Moleculer service name for the hub core-capability bridge.
4
+ *
5
+ * `$`-prefixed so it never collides with an addon id (addon services
6
+ * take their name from `declaration.id`). It is still a regular,
7
+ * discoverable service — `findServiceCandidates` in `trpc-links.ts`
8
+ * scans every entry returned by `registry.getServiceList()`.
9
+ */
10
+ export declare const CORE_CAP_SERVICE_NAME = "$core-caps";
11
+ /**
12
+ * A single hub core-capability procedure, ready to expose as a
13
+ * Moleculer action.
14
+ *
15
+ * `actionName` must be the kebab-cased `<capName>.<method>` pair the
16
+ * worker-side `brokerTransportLink` resolves: it parses `op.path`,
17
+ * kebab-cases the namespace and looks for a service action ending in
18
+ * `.<capName>.<method>` (see `findServiceCandidates`). Mounting the
19
+ * action as `system.info` makes Moleculer register it as
20
+ * `$core-caps.system.info`, which matches that suffix lookup.
21
+ */
22
+ export interface CoreCapAction {
23
+ /** Kebab-cased `<capName>.<method>` — e.g. `system.info`, `addon-settings-raw.getGlobal`. */
24
+ readonly actionName: string;
25
+ /** Invoke the underlying tRPC procedure with a trusted mesh context. */
26
+ readonly invoke: (input: unknown) => Promise<unknown> | unknown;
27
+ }
28
+ export interface CoreCapServiceOptions {
29
+ /** Moleculer service name. Defaults to {@link CORE_CAP_SERVICE_NAME}. */
30
+ readonly serviceName?: string;
31
+ readonly actions: readonly CoreCapAction[];
32
+ }
33
+ /**
34
+ * Wrap the hub's core (non-addon) tRPC procedures as a single Moleculer
35
+ * service so forked addons and remote agents can reach them through
36
+ * `ctx.api.<coreCap>.<method>`.
37
+ *
38
+ * Core routers (`system`, `addons`, `capabilities`, `nodes`, …) are
39
+ * mounted only as the hub's tRPC routers — no addon registers a
40
+ * provider for them, so `addon-service-factory` never gives them a
41
+ * Moleculer service. Without this bridge a forked addon's
42
+ * `ctx.api.<coreCap>` falls through `localProviderLink` into
43
+ * `brokerTransportLink`, whose load-balanced discovery wait has no
44
+ * deadline, and hangs forever.
45
+ *
46
+ * Mirrors `createAddonService`: each action deserializes typed arrays
47
+ * and normalizes Moleculer's `{}` (empty params) back to `undefined`
48
+ * so void-input procedures don't receive a spurious empty object.
49
+ */
50
+ export declare function createCoreCapService(options: CoreCapServiceOptions): ServiceSchema;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Per-runner crash circuit-breaker.
3
+ *
4
+ * Replaces the old infinite-respawn loop in `process-service.ts`'s
5
+ * `spawnRunner` exit handler. A runner that exits unexpectedly is
6
+ * respawned with exponential backoff while the crash count inside a
7
+ * sliding time window stays under `maxCrashes`. Once the window fills
8
+ * up the breaker trips: respawning STOPS and the caller marks the
9
+ * addon `failed`.
10
+ *
11
+ * State is per-runner (keyed on `runnerId`) and crash timestamps older
12
+ * than `windowMs` age out — a runner that crashed once an hour ago and
13
+ * then crashes again starts a fresh streak.
14
+ */
15
+ /** Tunables for `CrashSupervisor`. */
16
+ export interface CrashSupervisorOptions {
17
+ /** CRASH_WINDOW_MS — crashes older than this age out of the count. */
18
+ readonly windowMs: number;
19
+ /** Crashes within the window before the breaker trips to `failed`. */
20
+ readonly maxCrashes: number;
21
+ /** Backoff cap — the exponential backoff never exceeds this. */
22
+ readonly maxBackoffMs: number;
23
+ }
24
+ /**
25
+ * Outcome of recording a crash. Discriminated on `action`:
26
+ * - `respawn` — under the threshold, schedule another spawn after `backoffMs`.
27
+ * - `failed` — breaker tripped, do NOT respawn; mark the addon `failed`.
28
+ */
29
+ export type CrashDecision = {
30
+ readonly action: 'respawn';
31
+ readonly backoffMs: number;
32
+ readonly crashesInWindow: number;
33
+ } | {
34
+ readonly action: 'failed';
35
+ readonly crashesInWindow: number;
36
+ };
37
+ /** Per-runner crash circuit-breaker. Replaces the old infinite-respawn loop. */
38
+ export declare class CrashSupervisor {
39
+ private readonly opts;
40
+ /** runnerId → crash timestamps (ms epoch), pruned to the active window. */
41
+ private readonly crashes;
42
+ constructor(opts: CrashSupervisorOptions);
43
+ /**
44
+ * Record a crash for `runnerId` and decide what to do. `now` is
45
+ * injectable for deterministic tests; production calls omit it.
46
+ */
47
+ recordCrash(runnerId: string, now?: number): CrashDecision;
48
+ /** Clear crash history after a clean run / manual restart. */
49
+ reset(runnerId: string): void;
50
+ }
@@ -0,0 +1,79 @@
1
+ import { deviceOpsCapability, AddonApi, CapabilityDefinition, DeviceManagerApi, IDevice, IEventBus, IKernelStreamProbe, IScopedLogger, InferProvider } from '@camstack/types';
2
+ import { ServiceBroker } from 'moleculer';
3
+ import { DeviceRegistry } from '../device-registry.js';
4
+ import { CapabilityRegistry } from '../capability-registry.js';
5
+ import { LocalChildRegistry } from '../transport/local-child-registry.js';
6
+ export { NATIVE_PROVIDER_SERVICE_INFIX } from '../transport/cap-action-name.js';
7
+ export interface WorkerDeviceManagerOptions {
8
+ readonly api: AddonApi;
9
+ readonly addonId: string;
10
+ readonly nodeId: string;
11
+ readonly logger: IScopedLogger;
12
+ readonly eventBus: IEventBus;
13
+ readonly registry: DeviceRegistry;
14
+ readonly capabilityRegistry?: CapabilityRegistry;
15
+ readonly broker?: ServiceBroker;
16
+ /**
17
+ * UDS-only forked child (Phase F1+F2): no `capabilityRegistry`, no
18
+ * `broker`. `registerNativeCap` populates the per-process `workerNativeCaps`
19
+ * map (read by the UDS dispatch in `addon-runner`) but mounts NO Moleculer
20
+ * `<addon>.native-provider.*` service — the child has no broker.
21
+ */
22
+ readonly udsMode?: boolean;
23
+ readonly streamProbe?: IKernelStreamProbe;
24
+ }
25
+ /** Subscribe to worker native-cap set changes. Pass null to clear. */
26
+ export declare function setWorkerNativeCapsChangeListener(listener: (() => void) | null): void;
27
+ /**
28
+ * Mount the Moleculer service exposing `<addonId>.native-provider.<capName>`
29
+ * with per-method actions that dispatch to `workerNativeCaps`. Called
30
+ * lazily on first `registerNativeCap` AND proactively at worker boot for
31
+ * always-on caps (e.g. `device-ops`) so the INFO packet sent at TCP
32
+ * connect already advertises the service.
33
+ */
34
+ export declare function mountNativeCapService<TCap extends CapabilityDefinition>(broker: ServiceBroker, addonId: string, cap: TCap): void;
35
+ export declare function getWorkerNativeCap(capName: string, deviceId: number): unknown | null;
36
+ export declare function clearWorkerNativeCapsForDevice(deviceId: number): void;
37
+ export declare function getWorkerNativeCapNames(): readonly string[];
38
+ /**
39
+ * Snapshot of every device-scoped native cap this worker hosts, with the
40
+ * device ids and registering addonId for each. Used by the D3 registration
41
+ * handshake (`process-runner`/`group-runner` → `$hub.registerNode`'s
42
+ * `nativeCaps` field) so the hub's `HubNodeRegistry` learns device-scoped
43
+ * native caps (including addonId) without the pull-based discovery sweep.
44
+ *
45
+ * Groups by `(capName, addonId)` because different addons in the same group
46
+ * may register the same cap for different devices — each such pair becomes
47
+ * its own entry so the hub can build the correct Moleculer proxy target.
48
+ */
49
+ export declare function getWorkerNativeCapSnapshot(): ReadonlyArray<{
50
+ readonly capName: string;
51
+ readonly addonId: string;
52
+ readonly deviceIds: readonly number[];
53
+ }>;
54
+ export declare function getWorkerNativeCapsForDevice(deviceId: number): readonly string[];
55
+ /**
56
+ * Read-only accessor for UDS dispatch — returns the provider registered for a
57
+ * given (capName, deviceId) pair, or `undefined` when none is registered.
58
+ * Returns the provider as an opaque `object`; `createChildCapDispatch` resolves
59
+ * its methods structurally via a type guard, so no cast is needed.
60
+ */
61
+ export declare function getWorkerNativeCapProvider(capName: string, deviceId: number): object | undefined;
62
+ /**
63
+ * Hub-side proxy factory. Returns an object whose method access dispatches
64
+ * via `broker.call('<addonId>.native-provider.<capName>.<method>', input)`.
65
+ * Calls are wrapped in exponential-backoff retry to absorb the race between
66
+ * worker `broker.createService` and the hub's Moleculer registry INFO packet.
67
+ */
68
+ export declare function buildNativeCapProxy(broker: ServiceBroker, addonId: string, capName: string, deviceId: number): Record<string, (input: unknown) => Promise<unknown>>;
69
+ /**
70
+ * Hub-side proxy for a device-scoped native cap whose owning runner is a
71
+ * HUB-LOCAL forked child reachable over UDS. Mirrors {@link buildNativeCapProxy}
72
+ * but dispatches via `LocalChildRegistry.callCapOnChild` (UDS) instead of
73
+ * `broker.call` — the child no longer hosts a Moleculer service after the UDS
74
+ * cutover, so a broker call fails "is not found". The `deviceId` is merged into
75
+ * the method args (provider convention) and carried as the routing field.
76
+ */
77
+ export declare function buildUdsNativeCapProxy(registry: LocalChildRegistry, childId: string, capName: string, deviceId: number): Record<string, (input: unknown) => Promise<unknown>>;
78
+ export declare function buildDeviceOpsProvider(device: IDevice): InferProvider<typeof deviceOpsCapability>;
79
+ export declare function createBrokerDeviceManagerApi(opts: WorkerDeviceManagerOptions): DeviceManagerApi;
@@ -0,0 +1,53 @@
1
+ import { SystemEvent, EventFilter } from '@camstack/types';
2
+ export interface SubscriberEntry {
3
+ /** Original filter — kept whole so non-category dimensions are honoured per-event. */
4
+ readonly filter: EventFilter | string | undefined;
5
+ /** Pre-computed category pattern for the cheap pre-filter. */
6
+ readonly categoryPattern: string;
7
+ readonly handler: (event: SystemEvent) => void;
8
+ }
9
+ export interface SharedBusState {
10
+ /**
11
+ * Subscribers indexed by category pattern. Each entry also carries its full
12
+ * filter so the subsequent `matchesEventFilter` call can reject events that
13
+ * match the category but not the scope (deviceId, addonId, …).
14
+ */
15
+ readonly handlers: Map<string, Set<SubscriberEntry>>;
16
+ /**
17
+ * In-memory recent-events buffer. The deny-list below filters out
18
+ * high-frequency categories so the buffer only accumulates audit-grade
19
+ * lifecycle events.
20
+ *
21
+ * Cleared on server restart (intentional — events are volatile by design).
22
+ */
23
+ readonly recent: SystemEvent[];
24
+ }
25
+ export declare function createSharedBusState(): SharedBusState;
26
+ export declare function matchesPattern(pattern: string, category: string): boolean;
27
+ export declare function extractCategoryPattern(filter: EventFilter | string): string;
28
+ /**
29
+ * Match an event against the full `EventFilter`. The Map-keyed subscribe path
30
+ * only handles the category pattern (deciding which handler set to fan out to);
31
+ * this function applies the remaining scope dimensions (`agentId`, `addonId`,
32
+ * `deviceId`, `source`, `since`) so per-device / per-addon subscribers don't
33
+ * receive sibling events.
34
+ */
35
+ export declare function matchesEventFilter(event: SystemEvent, filter: EventFilter | string | undefined): boolean;
36
+ /**
37
+ * Categories filtered out of the `recent[]` ring buffer.
38
+ *
39
+ * High-frequency, low-value-for-the-operator categories — periodic metrics
40
+ * snapshots, per-frame inference traces, raw motion-mask dumps, model-download
41
+ * progress, etc. They still fan out to live subscribers (UI charts that
42
+ * explicitly listen for them), but do NOT enter the recent-events ring so
43
+ * meaningful events (motion / phase transitions / device lifecycle / addon
44
+ * lifecycle / recording / detection.event) survive in the last-N window without
45
+ * being displaced by per-frame noise.
46
+ */
47
+ export declare const RING_BUFFER_DENY_PATTERNS: readonly string[];
48
+ export declare function isHighFrequencyCategory(category: string): boolean;
49
+ /**
50
+ * Deliver `event` to all matching local subscribers and — unless it is
51
+ * high-frequency — append it to the `recent[]` ring.
52
+ */
53
+ export declare function deliverShared(state: SharedBusState, event: SystemEvent): void;
@@ -0,0 +1,53 @@
1
+ import { ServiceBroker } from 'moleculer';
2
+ import { IEventBus } from '@camstack/types';
3
+ /**
4
+ * Narrow interface for the Moleculer ServiceBroker surface used in this file.
5
+ * moleculer's index.d.ts chains through eventemitter2 whose package.json has
6
+ * no `types` field; typescript-eslint's no-unsafe-* rules flag every
7
+ * broker.X access. Cast once per function: `const bkr = broker as unknown as BrokerLike`.
8
+ */
9
+ export interface BrokerLike {
10
+ readonly nodeID: string;
11
+ call<T = unknown>(action: string, params?: unknown, opts?: unknown): Promise<T>;
12
+ createService(schema: unknown): void;
13
+ waitForServices(service: unknown, timeout?: number): Promise<unknown>;
14
+ broadcast(event: string, data: unknown): void;
15
+ localBus: {
16
+ on(event: string, handler: (data: unknown) => void): void;
17
+ };
18
+ logger: {
19
+ warn?: (msg: string) => void;
20
+ };
21
+ }
22
+ /**
23
+ * Topic prefix for clustered EventBus broadcasts. The `camstack.evt.`
24
+ * namespace keeps our events disjoint from Moleculer internal events
25
+ * (`$node.*`, `$services.*`) — the `$event-bus` service's
26
+ * `camstack.evt.**` wildcard handler therefore never sees them.
27
+ */
28
+ export declare const EVENT_TOPIC_PREFIX = "camstack.evt.";
29
+ /** Build the Moleculer broadcast topic for an event category. */
30
+ export declare function clusterEventTopic(category: string): string;
31
+ /**
32
+ * Register the `$event-bus` service on a broker. MUST be called BEFORE
33
+ * `broker.start()` — Moleculer announces a service's event
34
+ * subscriptions to remote nodes only during the discovery handshake;
35
+ * a post-start `createService` propagates via the ~10s heartbeat and
36
+ * makes cross-node delivery unreliable in the meantime.
37
+ *
38
+ * The service's single wildcard handler (`camstack.evt.**`) is the
39
+ * inbound bridge: every `broker.broadcast('camstack.evt.<cat>', event)`
40
+ * from any node lands here. Self-origin echoes are dropped (the
41
+ * emitting node already delivered synchronously in `emit`).
42
+ *
43
+ * Idempotent. Internal service (`$`-prefixed) — hidden from the
44
+ * capability graph.
45
+ *
46
+ * Callers:
47
+ * - hub backend (`MoleculerService.onModuleInit`), before `broker.start()`
48
+ * - agent bootstrap, before `broker.start()`
49
+ * - forkable process / group runner, before `broker.start()`
50
+ */
51
+ export declare function registerEventBusService(broker: ServiceBroker): void;
52
+ export declare function getBrokerEventBus(broker: ServiceBroker): IEventBus;
53
+ export declare function createBrokerEventBus(broker: ServiceBroker, addonId: string): IEventBus;
@@ -0,0 +1,36 @@
1
+ import { LogTags } from '@camstack/types';
2
+ import { ServiceBroker } from 'moleculer';
3
+ interface LogEntry {
4
+ timestamp: Date;
5
+ level: string;
6
+ scope?: string;
7
+ message: string;
8
+ meta?: Record<string, unknown>;
9
+ tags?: LogTags;
10
+ }
11
+ /**
12
+ * Hub Log Forwarder — forwards log entries to the hub via $hub.log.
13
+ *
14
+ * Listens for Moleculer node discovery events. When the hub node
15
+ * connects, forwarding activates. When it disconnects, forwarding
16
+ * pauses and resumes on reconnect. No timeouts — fully event-driven.
17
+ *
18
+ * NOTE on `console.*` below: this class IS the log transport. Its own
19
+ * lifecycle messages (connected / disconnected / call-failed) must NOT
20
+ * be routed through a hub-forwarding logger — that would recurse (the
21
+ * log transport logging about itself through itself). The reference
22
+ * `HubForwarderDestination` in `@camstack/system` solves the same problem
23
+ * with an injected `statusLogger` that is wired to a non-forwarding
24
+ * destination. `HubLogForwarder` has no such injection point and is
25
+ * currently unused in the tree (exported only), so its status writes
26
+ * stay on raw `console.*` as a deliberate, documented residual.
27
+ */
28
+ declare class HubLogForwarder {
29
+ private readonly broker;
30
+ private connected;
31
+ constructor(broker: ServiceBroker);
32
+ initialize(): Promise<void>;
33
+ write(entry: LogEntry): void;
34
+ shutdown(): Promise<void>;
35
+ }
36
+ export { HubLogForwarder };
@@ -0,0 +1,35 @@
1
+ import { ServiceSchema } from 'moleculer';
2
+ import { LogTags } from '@camstack/types';
3
+ import { RegisterNodeParams } from './node-registry.js';
4
+ interface HubServiceDeps {
5
+ readonly getAddonConfig: (addonId: string) => unknown;
6
+ readonly getSettings: (scope: string, key?: string) => unknown;
7
+ readonly getRecentEvents: (category?: string, limit?: number) => readonly unknown[];
8
+ readonly onLog: (entry: {
9
+ level: string;
10
+ message: string;
11
+ addonId: string;
12
+ nodeId: string;
13
+ scope?: string;
14
+ tags?: LogTags;
15
+ meta?: Record<string, unknown>;
16
+ }) => void;
17
+ readonly onSetLogLevel?: (level: string) => void;
18
+ /**
19
+ * D3 registration handshake. A node calls `$hub.registerNode` once it
20
+ * has finished mounting EVERY service; the payload is its complete cap
21
+ * manifest. Idempotent — replaces the node's prior manifest entirely.
22
+ */
23
+ readonly onRegisterNode?: (params: RegisterNodeParams) => void;
24
+ /** Explicit deregistration (graceful shutdown). `$node.disconnected` covers crashes. */
25
+ readonly onUnregisterNode?: (nodeId: string) => void;
26
+ /**
27
+ * SHA-256 hash of the hub's own `CAMSTACK_CLUSTER_SECRET`, or `undefined`
28
+ * when no secret is configured. When set, `$hub.registerNode` rejects any
29
+ * node not presenting a matching `clusterSecretHash`. (Cluster-secret gate.)
30
+ */
31
+ readonly expectedClusterSecretHash?: string;
32
+ }
33
+ declare function createHubService(deps: HubServiceDeps): ServiceSchema;
34
+ export { createHubService };
35
+ export type { HubServiceDeps };
@@ -0,0 +1,126 @@
1
+ /**
2
+ * HubNodeRegistry — the single authority for which capabilities each
3
+ * cluster node provides. Holds the union of node manifests delivered by
4
+ * the D3 `$hub.registerNode` handshake; a node is dropped on
5
+ * `$node.disconnected`. Pure data — no Moleculer, no timers, no scan.
6
+ */
7
+ /**
8
+ * A capability call function — routes a method call to a remote cap provider
9
+ * via Moleculer. Moved here from `capability-bridge.ts` when that file was
10
+ * deleted as part of the D3 clean-up (Task 11).
11
+ */
12
+ type CallFn = (method: string, params: unknown, targetNodeId?: string) => Promise<unknown>;
13
+ /** One addon's contribution within a node's registration manifest. */
14
+ interface RegisteredAddonManifest {
15
+ readonly addonId: string;
16
+ readonly capabilities: readonly string[];
17
+ }
18
+ /**
19
+ * One device-scoped native cap a node hosts, with the device ids that
20
+ * registered it and the addonId of the registering addon. Device-scoped
21
+ * native caps (`ctx.registerNativeCap` from a `BaseDevice` subclass) are
22
+ * registered per device AFTER the node's system caps, once background device
23
+ * restore completes — so the node re-handshakes carrying these once they are
24
+ * known (D3 idempotent replace).
25
+ *
26
+ * `addonId` is required for the hub to build the correct Moleculer proxy
27
+ * target (`<addonId>.native-provider.<capName>.<method>`). It replaces the
28
+ * pull-based `syncWorkerNativeCaps` discovery sweep (Task 13).
29
+ */
30
+ interface RegisteredNativeCap {
31
+ readonly capName: string;
32
+ readonly addonId: string;
33
+ readonly deviceIds: readonly number[];
34
+ }
35
+ /** Payload of the `$hub.registerNode` RPC — a node's COMPLETE manifest. */
36
+ interface RegisterNodeParams {
37
+ readonly nodeId: string;
38
+ readonly addons: readonly RegisteredAddonManifest[];
39
+ /**
40
+ * Device-scoped native caps the node hosts. Optional — absent (or empty)
41
+ * on the FIRST handshake, populated by the re-handshake the node fires
42
+ * after `runWorkerDeviceRestoreWithRetry` completes. Each entry includes
43
+ * the registering `addonId` so the hub can build the correct Moleculer
44
+ * proxy target without the pull-based discovery sweep (Task 13).
45
+ */
46
+ readonly nativeCaps?: readonly RegisteredNativeCap[];
47
+ /**
48
+ * SHA-256 hash of the node's `CAMSTACK_CLUSTER_SECRET`. Optional — absent
49
+ * when the node has no secret configured. Verified by the `registerNode`
50
+ * receiver; never carries the raw secret. (Cluster-secret registration gate.)
51
+ */
52
+ readonly clusterSecretHash?: string;
53
+ }
54
+ /** Ack returned by `$hub.registerNode` — presence of `ok` is the signal. */
55
+ interface RegisterNodeResult {
56
+ readonly ok: true;
57
+ }
58
+ /** Flattened registry view: one row per (node, addon, capability). */
59
+ interface NodeCapEntry {
60
+ readonly nodeId: string;
61
+ readonly addonId: string;
62
+ readonly capName: string;
63
+ }
64
+ /** Flattened native-cap view: one row per (node, native cap, device). */
65
+ interface NodeNativeCapEntry {
66
+ readonly nodeId: string;
67
+ readonly addonId: string;
68
+ readonly capName: string;
69
+ readonly deviceId: number;
70
+ }
71
+ declare class HubNodeRegistry {
72
+ /** nodeId → its complete addon manifest (last `registerNode` wins). */
73
+ private readonly nodes;
74
+ /** nodeId → its device-scoped native caps (last `registerNode` wins). */
75
+ private readonly nativeCaps;
76
+ /**
77
+ * deviceId → flat native-cap entries for THAT device, across all nodes.
78
+ * Maintained incrementally on every `registerNode`/`removeNode` so a
79
+ * per-device lookup is O(caps-for-device) instead of flattening the whole
80
+ * cluster (`listNativeCapEntries()`) and filtering — the latter makes the
81
+ * per-device `getBindings`, run for every device in `getAllBindings`, an
82
+ * O(D²·C) boot-time hot spot. Insertion order mirrors `listNativeCapEntries`
83
+ * (node-registration order) so consumers that take the first match are
84
+ * unaffected.
85
+ */
86
+ private readonly nativeCapsByDevice;
87
+ /**
88
+ * Drop every `nativeCapsByDevice` entry contributed by `nodeId`, reading the
89
+ * node's CURRENT (about-to-be-replaced) native caps to know which device
90
+ * rows it touched. Must run BEFORE `nativeCaps` is overwritten/deleted.
91
+ */
92
+ private dropNodeFromDeviceIndex;
93
+ /**
94
+ * Replace the node's ENTIRE manifest atomically — addons AND native
95
+ * caps. Idempotent: a reconnect, hot-update, or post-device-restore
96
+ * re-handshake simply overwrites. Partial state is impossible because
97
+ * the node sends its complete picture every time.
98
+ */
99
+ registerNode(params: RegisterNodeParams): void;
100
+ /** Drop a node entirely — caps AND native caps — on `$node.disconnected`. */
101
+ removeNode(nodeId: string): void;
102
+ /** The node's manifest, or undefined when the node never registered. */
103
+ getNodeManifest(nodeId: string): readonly RegisteredAddonManifest[] | undefined;
104
+ /**
105
+ * The node's device-scoped native caps. `[]` when the node registered
106
+ * without any (or has not yet re-handshaked post-device-restore);
107
+ * `undefined` when the node never registered at all.
108
+ */
109
+ getNodeNativeCaps(nodeId: string): readonly RegisteredNativeCap[] | undefined;
110
+ /** Flat (nodeId, addonId, capName) view of the whole cluster. */
111
+ listEntries(): readonly NodeCapEntry[];
112
+ /** Flat (nodeId, addonId, capName, deviceId) native-cap view of the whole cluster. */
113
+ listNativeCapEntries(): readonly NodeNativeCapEntry[];
114
+ /**
115
+ * Native-cap entries for ONE device, across all nodes — O(caps-for-device).
116
+ * Equivalent to `listNativeCapEntries().filter(e => e.deviceId === deviceId)`
117
+ * but served from the incrementally-maintained `nativeCapsByDevice` index, so
118
+ * per-device resolution (and `getAllBindings`, which runs it per device)
119
+ * doesn't flatten the whole cluster each call.
120
+ */
121
+ listNativeCapEntriesForDevice(deviceId: number): readonly NodeNativeCapEntry[];
122
+ /** Every node id currently registered. */
123
+ listNodeIds(): readonly string[];
124
+ }
125
+ export { HubNodeRegistry };
126
+ export type { CallFn, RegisteredAddonManifest, RegisteredNativeCap, RegisterNodeParams, RegisterNodeResult, NodeCapEntry, NodeNativeCapEntry, };
@@ -0,0 +1,4 @@
1
+ import { ServiceBroker } from 'moleculer';
2
+ import { IAddonProcessManager } from '@camstack/types';
3
+ declare function createScopedProcessManager(broker: ServiceBroker, addonId: string): IAddonProcessManager;
4
+ export { createScopedProcessManager };