@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,595 @@
1
+ import { AlertSchema, BaseAddon, EventCategory, alertsCapability, createEvent, errMsg } from "@camstack/types";
2
+ //#region src/builtins/alerts/alerts.addon.ts
3
+ var CATEGORY_MAPPINGS = {
4
+ "addon.crashed": {
5
+ severity: "error",
6
+ titleTemplate: "Addon crashed"
7
+ },
8
+ "addon.error": {
9
+ severity: "error",
10
+ titleTemplate: "Addon error"
11
+ },
12
+ "process.crashed": {
13
+ severity: "error",
14
+ titleTemplate: "Process crashed"
15
+ },
16
+ "recording.error": {
17
+ severity: "error",
18
+ titleTemplate: "Recording error"
19
+ },
20
+ "recording.storage.critical": {
21
+ severity: "warning",
22
+ titleTemplate: "Storage critical"
23
+ },
24
+ "notification.failed": {
25
+ severity: "error",
26
+ titleTemplate: "Notification failed"
27
+ },
28
+ "agent.online": {
29
+ severity: "info",
30
+ titleTemplate: "Agent connected"
31
+ },
32
+ "agent.offline": {
33
+ severity: "warning",
34
+ titleTemplate: "Agent disconnected"
35
+ },
36
+ "system.boot": {
37
+ severity: "info",
38
+ titleTemplate: "System boot"
39
+ },
40
+ "system.restarting": {
41
+ severity: "warning",
42
+ titleTemplate: "System restarting"
43
+ },
44
+ "device.registered": {
45
+ severity: "info",
46
+ titleTemplate: "Device registered"
47
+ },
48
+ "device.unregistered": {
49
+ severity: "warning",
50
+ titleTemplate: "Device unregistered"
51
+ },
52
+ "addon.installed": {
53
+ severity: "info",
54
+ titleTemplate: "Addon installed"
55
+ },
56
+ "addon.updated": {
57
+ severity: "info",
58
+ titleTemplate: "Addon updated"
59
+ },
60
+ "addon.uninstalled": {
61
+ severity: "info",
62
+ titleTemplate: "Addon uninstalled"
63
+ },
64
+ "addon.load-failed": {
65
+ severity: "error",
66
+ titleTemplate: "Addon failed to load"
67
+ },
68
+ "addon.load-recovered": {
69
+ severity: "info",
70
+ titleTemplate: "Addon recovered"
71
+ },
72
+ "backup.completed": {
73
+ severity: "info",
74
+ titleTemplate: "Backup completed"
75
+ },
76
+ "backup.restored": {
77
+ severity: "info",
78
+ titleTemplate: "Backup restored"
79
+ },
80
+ "model.download.progress": {
81
+ severity: "info",
82
+ titleTemplate: "Model download"
83
+ }
84
+ };
85
+ var TRACKED_CATEGORIES = Object.keys(CATEGORY_MAPPINGS);
86
+ /**
87
+ * `[ALERT-CENTER-EVENTS]` — rate limiting. Events that fire thousands of
88
+ * times a minute (flaky cam reconnecting, chatty integration, …) would
89
+ * flood the alert feed and push genuinely important alerts off the
90
+ * visible page. We collapse bursts into a single throttled summary per
91
+ * `(category, source.id)` tuple: the first N events within the window
92
+ * still surface as individual alerts, but once the source crosses the
93
+ * threshold we stop emitting alerts for it and wait out the window.
94
+ *
95
+ * A standalone category-count map is cleared on every window rollover.
96
+ * Keep the threshold generous enough that legitimate bursts of ~a few
97
+ * per minute still get through, but strict enough that a reconnect loop
98
+ * firing every second gets muted.
99
+ */
100
+ var RATE_LIMIT_WINDOW_MS = 6e4;
101
+ var RATE_LIMIT_MAX_PER_SOURCE = 5;
102
+ /** Parse a raw settings record into a validated Alert. */
103
+ function parseAlert(record) {
104
+ return AlertSchema.parse({
105
+ id: record.id,
106
+ ...record.data
107
+ });
108
+ }
109
+ var DEFAULT_CONFIG = {
110
+ maxAlerts: 500,
111
+ retentionDays: 30
112
+ };
113
+ var ALERTS_COLLECTION = "alerts";
114
+ var EVENT_SOURCE = {
115
+ type: "addon",
116
+ id: "alert-center"
117
+ };
118
+ /**
119
+ * Alert Center addon — core builtin that persists alerts in a
120
+ * structured SQLite table and serves them to the admin UI.
121
+ *
122
+ * Registers as an `alerts` collection provider and subscribes to
123
+ * important EventBus categories to create/update alerts automatically.
124
+ */
125
+ var AlertCenterAddon = class extends BaseAddon {
126
+ unsubscribers = [];
127
+ constructor() {
128
+ super({ ...DEFAULT_CONFIG });
129
+ }
130
+ /**
131
+ * Per `(category, source.id)` counter used to rate-limit chatty
132
+ * events. Entries are pruned lazily when they age out of
133
+ * `RATE_LIMIT_WINDOW_MS`; see `shouldSuppressByRate()` below.
134
+ */
135
+ rateLimitCounters = /* @__PURE__ */ new Map();
136
+ async onInitialize() {
137
+ const alertsProvider = {
138
+ emit: (alert) => this.emitAlert(alert),
139
+ update: (input) => this.updateAlert(input.alertId, input.patch),
140
+ list: (filter) => this.listAlerts(filter),
141
+ getUnreadCount: () => this.getUnreadCount(),
142
+ markRead: (input) => this.markRead(input.alertId),
143
+ markAllRead: () => this.markAllRead(),
144
+ dismiss: (input) => this.dismiss(input.alertId)
145
+ };
146
+ const unsubs = [];
147
+ for (const category of TRACKED_CATEGORIES) {
148
+ const unsub = this.ctx.eventBus.subscribe({ category }, (event) => {
149
+ this.handleEvent(category, event);
150
+ });
151
+ unsubs.push(unsub);
152
+ }
153
+ this.unsubscribers = unsubs;
154
+ this.ctx.logger.info("Initialized", { meta: { trackedCategoriesCount: TRACKED_CATEGORIES.length } });
155
+ return [{
156
+ capability: alertsCapability,
157
+ provider: alertsProvider
158
+ }];
159
+ }
160
+ async onShutdown() {
161
+ for (const unsub of this.unsubscribers) unsub();
162
+ this.unsubscribers = [];
163
+ }
164
+ globalSettingsSchema() {
165
+ return this.schema({ sections: [{
166
+ id: "alerts",
167
+ title: "Alert Center",
168
+ description: "Configure alert storage and retention.",
169
+ columns: 1,
170
+ fields: [this.field({
171
+ type: "number",
172
+ key: "maxAlerts",
173
+ label: "Maximum stored alerts",
174
+ description: "Oldest read alerts are deleted when this limit is exceeded.",
175
+ min: 50,
176
+ max: 5e3,
177
+ step: 50,
178
+ default: 500
179
+ }), this.field({
180
+ type: "number",
181
+ key: "retentionDays",
182
+ label: "Alert retention (days)",
183
+ description: "Alerts older than this are automatically removed.",
184
+ min: 1,
185
+ max: 365,
186
+ step: 1,
187
+ default: 30
188
+ })]
189
+ }] });
190
+ }
191
+ async listAlerts(filter) {
192
+ const backend = this.ctx.api.settingsStore;
193
+ if (!backend) return [];
194
+ const whereClause = {};
195
+ if (filter?.unreadOnly) whereClause.read = false;
196
+ return (await backend.query.query({
197
+ collection: ALERTS_COLLECTION,
198
+ filter: {
199
+ where: Object.keys(whereClause).length > 0 ? whereClause : void 0,
200
+ orderBy: {
201
+ field: "updatedAt",
202
+ direction: "desc"
203
+ },
204
+ limit: filter?.limit ?? 100
205
+ }
206
+ })).map(parseAlert);
207
+ }
208
+ async getUnreadCount() {
209
+ const backend = this.ctx.api.settingsStore;
210
+ if (!backend) return 0;
211
+ return backend.count.query({
212
+ collection: ALERTS_COLLECTION,
213
+ filter: { where: { read: false } }
214
+ });
215
+ }
216
+ async markRead(alertId) {
217
+ await this.mergeUpdate(alertId, {
218
+ read: true,
219
+ updatedAt: Date.now()
220
+ });
221
+ }
222
+ async markAllRead() {
223
+ const backend = this.ctx.api.settingsStore;
224
+ if (!backend) return;
225
+ const unread = await backend.query.query({
226
+ collection: ALERTS_COLLECTION,
227
+ filter: { where: { read: false } }
228
+ });
229
+ const now = Date.now();
230
+ for (const record of unread) await this.mergeUpdate(record.id, {
231
+ read: true,
232
+ updatedAt: now
233
+ });
234
+ }
235
+ async dismiss(alertId) {
236
+ await this.mergeUpdate(alertId, {
237
+ status: "dismissed",
238
+ read: true,
239
+ updatedAt: Date.now()
240
+ });
241
+ }
242
+ async handleEvent(category, event) {
243
+ try {
244
+ if (category === "model.download.progress") {
245
+ await this.handleModelDownload(event);
246
+ return;
247
+ }
248
+ if (category === EventCategory.AddonLoadFailed) {
249
+ await this.handleAddonLoadFailed(event);
250
+ return;
251
+ }
252
+ if (category === EventCategory.AddonLoadRecovered) {
253
+ await this.handleAddonLoadRecovered(event);
254
+ return;
255
+ }
256
+ const mapping = CATEGORY_MAPPINGS[category];
257
+ if (!mapping) return;
258
+ if (this.shouldSuppressByRate(category, event)) return;
259
+ const message = this.buildMessage(category, event.data, event.source ? String(event.source.id) : void 0);
260
+ const alert = {
261
+ id: crypto.randomUUID(),
262
+ category,
263
+ severity: mapping.severity,
264
+ title: mapping.titleTemplate,
265
+ message,
266
+ status: "active",
267
+ read: false,
268
+ createdAt: Date.now(),
269
+ updatedAt: Date.now(),
270
+ source: event.source ? {
271
+ type: event.source.type,
272
+ id: String(event.source.id)
273
+ } : void 0,
274
+ metadata: event.data
275
+ };
276
+ await this.emitAlert(alert);
277
+ } catch (err) {
278
+ this.ctx.logger?.warn("Failed to handle event", { meta: {
279
+ category,
280
+ error: errMsg(err)
281
+ } });
282
+ }
283
+ }
284
+ async handleModelDownload(event) {
285
+ const data = event.data;
286
+ const modelId = data.modelId ?? "unknown";
287
+ const progress = data.progress ?? 0;
288
+ const stableId = `model-download:${modelId}`;
289
+ const backend = this.ctx.api.settingsStore;
290
+ if (!backend) return;
291
+ if ((await backend.query.query({
292
+ collection: ALERTS_COLLECTION,
293
+ filter: { where: { id: stableId } }
294
+ })).length > 0) {
295
+ const now = Date.now();
296
+ if (progress >= 100) {
297
+ await this.mergeUpdate(stableId, {
298
+ status: "completed",
299
+ progress: 100,
300
+ message: `Model "${modelId}" download completed`,
301
+ updatedAt: now
302
+ });
303
+ this.emitAlertUpdatedEvent(stableId, {
304
+ status: "completed",
305
+ progress: 100
306
+ });
307
+ } else if (progress < 0) {
308
+ await this.mergeUpdate(stableId, {
309
+ status: "failed",
310
+ message: `Model "${modelId}" download failed`,
311
+ updatedAt: now
312
+ });
313
+ this.emitAlertUpdatedEvent(stableId, { status: "failed" });
314
+ } else {
315
+ await this.mergeUpdate(stableId, {
316
+ progress,
317
+ message: `Downloading model "${modelId}" — ${String(Math.round(progress))}%`,
318
+ updatedAt: now
319
+ });
320
+ this.emitAlertUpdatedEvent(stableId, { progress });
321
+ }
322
+ } else {
323
+ const alert = {
324
+ id: stableId,
325
+ category: EventCategory.ModelDownloadProgress,
326
+ severity: "info",
327
+ title: "Model download",
328
+ message: `Downloading model "${modelId}" — ${String(Math.round(progress))}%`,
329
+ status: "in-progress",
330
+ progress,
331
+ read: false,
332
+ createdAt: Date.now(),
333
+ updatedAt: Date.now(),
334
+ source: event.source ? {
335
+ type: event.source.type,
336
+ id: String(event.source.id)
337
+ } : void 0,
338
+ metadata: { modelId }
339
+ };
340
+ await this.persistAlert(alert);
341
+ this.emitAlertCreatedEvent(alert);
342
+ }
343
+ }
344
+ /**
345
+ * `[ALERT-CENTER-EVENTS]` — rate limit a `(category, source.id)`
346
+ * tuple. Returns `true` when the caller should DROP this event
347
+ * without persisting an alert, and `false` when the alert should
348
+ * proceed normally.
349
+ *
350
+ * Heuristic: the first `RATE_LIMIT_MAX_PER_SOURCE` events within a
351
+ * `RATE_LIMIT_WINDOW_MS` window go through. Once the threshold is
352
+ * crossed, subsequent events are suppressed until the window rolls
353
+ * over. When the threshold is first crossed, the suppression is
354
+ * logged once so operators know why they're not seeing the follow-
355
+ * up alerts; after the window rolls over the next event is
356
+ * un-suppressed and starts a new window.
357
+ */
358
+ shouldSuppressByRate(category, event) {
359
+ const sourceId = event.source?.id ?? "unknown";
360
+ const key = `${category}::${sourceId}`;
361
+ const now = Date.now();
362
+ const entry = this.rateLimitCounters.get(key);
363
+ if (!entry || now - entry.firstAt > RATE_LIMIT_WINDOW_MS) {
364
+ this.rateLimitCounters.set(key, {
365
+ firstAt: now,
366
+ count: 1,
367
+ suppressedLogged: false
368
+ });
369
+ return false;
370
+ }
371
+ entry.count += 1;
372
+ if (entry.count <= RATE_LIMIT_MAX_PER_SOURCE) return false;
373
+ if (!entry.suppressedLogged) {
374
+ entry.suppressedLogged = true;
375
+ this.ctx.logger?.info("rate-limiting suppressing remainder of window", { meta: {
376
+ category,
377
+ sourceId,
378
+ maxPerSource: RATE_LIMIT_MAX_PER_SOURCE,
379
+ windowSeconds: RATE_LIMIT_WINDOW_MS / 1e3
380
+ } });
381
+ }
382
+ return true;
383
+ }
384
+ /**
385
+ * AddonLoadFailed — kernel's AddonHealthMonitor has post-grace
386
+ * failed an addon load/init. Upsert a stable-id alert keyed by
387
+ * `addon-load-failed:<packageName>` so the recovery path can
388
+ * dismiss it. Severity=error, persistent until dismissed or
389
+ * auto-resolved.
390
+ *
391
+ * The action `retry` carries the package name so the admin UI can
392
+ * dispatch `addons.retryLoad(packageName)` directly from the alert
393
+ * card without the operator opening the Addons page.
394
+ */
395
+ async handleAddonLoadFailed(event) {
396
+ const data = event.data;
397
+ const packageName = String(data["packageName"] ?? "");
398
+ if (!packageName) return;
399
+ const addonId = data["addonId"];
400
+ const errorObj = data["error"];
401
+ const retryCount = Number(data["retryCount"] ?? 0);
402
+ const nextRetryAt = data["nextRetryAt"];
403
+ const stableId = `addon-load-failed:${packageName}`;
404
+ const message = errorObj?.message ? `${addonId ? `${addonId} — ` : ""}${errorObj.message}` : `Addon ${addonId ?? packageName} failed to load`;
405
+ const alert = {
406
+ id: stableId,
407
+ category: EventCategory.AddonLoadFailed,
408
+ severity: "error",
409
+ title: `Addon failed: ${addonId ?? packageName}`,
410
+ message,
411
+ status: "active",
412
+ read: false,
413
+ createdAt: Date.now(),
414
+ updatedAt: Date.now(),
415
+ source: {
416
+ type: "addon",
417
+ id: packageName
418
+ },
419
+ metadata: {
420
+ packageName,
421
+ addonId,
422
+ retryCount,
423
+ nextRetryAt,
424
+ stack: errorObj?.stack
425
+ }
426
+ };
427
+ await this.emitAlert(alert);
428
+ }
429
+ /**
430
+ * AddonLoadRecovered — addon previously alerting is back to healthy.
431
+ * Dismiss the matching alert so the operator's badge count drops.
432
+ */
433
+ async handleAddonLoadRecovered(event) {
434
+ const data = event.data;
435
+ const packageName = String(data["packageName"] ?? "");
436
+ if (!packageName) return;
437
+ const stableId = `addon-load-failed:${packageName}`;
438
+ try {
439
+ await this.dismiss(stableId);
440
+ } catch (err) {
441
+ this.ctx.logger?.debug("AddonLoadRecovered: dismiss failed (likely already dismissed)", { meta: {
442
+ stableId,
443
+ error: errMsg(err)
444
+ } });
445
+ }
446
+ }
447
+ buildMessage(category, data, sourceId) {
448
+ const addonId = data.addonId ?? sourceId;
449
+ const deviceId = data.deviceId;
450
+ const error = data.error;
451
+ const processId = data.processId;
452
+ switch (category) {
453
+ case "addon.crashed": return `Addon "${addonId ?? "unknown"}" crashed${error ? `: ${error}` : ""}`;
454
+ case "addon.error": return `Addon "${addonId ?? "unknown"}" error${error ? `: ${error}` : ""}`;
455
+ case "addon.installed": return `Addon "${addonId ?? "unknown"}" installed`;
456
+ case "addon.updated": {
457
+ const from = data.fromVersion;
458
+ const to = data.toVersion;
459
+ return `Addon "${addonId ?? "unknown"}" updated${from && to ? ` from ${from} to ${to}` : ""}`;
460
+ }
461
+ case "addon.uninstalled": return `Addon "${addonId ?? "unknown"}" uninstalled`;
462
+ case "device.registered": return `Device "${data.name ?? deviceId ?? "unknown"}" registered`;
463
+ case "device.unregistered": return `Device "${deviceId ?? "unknown"}" unregistered`;
464
+ case "agent.online": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" connected`;
465
+ case "agent.offline": return `Agent "${data.agentId ?? data.nodeId ?? "unknown"}" disconnected${data.reason ? `: ${String(data.reason)}` : ""}`;
466
+ case "backup.completed": return `Backup completed${data.targetId ? ` (${String(data.targetId)})` : ""}`;
467
+ case "backup.restored": return `Backup restored${data.source ? ` from ${String(data.source)}` : ""}`;
468
+ case "notification.failed": return `Notification failed${error ? `: ${error}` : ""}`;
469
+ case "system.restarting": return `System restarting${data.reason ? ` — ${String(data.reason)}` : ""}`;
470
+ case "recording.error": return `Recording error on device "${deviceId ?? "unknown"}"${error ? `: ${error}` : ""}`;
471
+ case "recording.storage.critical": return `Storage critical for device "${deviceId ?? "unknown"}"`;
472
+ case "system.boot": return `System booted in "${data.mode ?? "unknown"}" mode`;
473
+ case "process.crashed": return `Process "${processId ?? "unknown"}" crashed`;
474
+ default: return `Event: ${category}`;
475
+ }
476
+ }
477
+ async emitAlert(alert) {
478
+ await this.persistAlert(alert);
479
+ this.emitAlertCreatedEvent(alert);
480
+ await this.enforceMaxAlerts();
481
+ await this.enforceRetention();
482
+ }
483
+ async updateAlert(alertId, patch) {
484
+ await this.mergeUpdate(alertId, {
485
+ ...patch,
486
+ updatedAt: Date.now()
487
+ });
488
+ this.emitAlertUpdatedEvent(alertId, patch);
489
+ }
490
+ /**
491
+ * Read-merge-write: SettingsBackend.update() replaces the entire `data` blob,
492
+ * so we must read the existing record, merge the patch, and write back.
493
+ */
494
+ async mergeUpdate(id, patch) {
495
+ const backend = this.ctx.api.settingsStore;
496
+ if (!backend) return;
497
+ const raw = await backend.get.query({
498
+ collection: ALERTS_COLLECTION,
499
+ key: id
500
+ });
501
+ if (raw === null || raw === void 0 || typeof raw !== "object") return;
502
+ const existing = Object.fromEntries(Object.entries(raw));
503
+ await backend.set.mutate({
504
+ collection: ALERTS_COLLECTION,
505
+ key: id,
506
+ value: {
507
+ ...existing,
508
+ ...patch
509
+ }
510
+ });
511
+ }
512
+ async persistAlert(alert) {
513
+ const backend = this.ctx.api.settingsStore;
514
+ if (!backend) return;
515
+ const data = {
516
+ id: alert.id,
517
+ category: alert.category,
518
+ severity: alert.severity,
519
+ title: alert.title,
520
+ message: alert.message,
521
+ status: alert.status,
522
+ read: alert.read,
523
+ createdAt: alert.createdAt,
524
+ updatedAt: alert.updatedAt,
525
+ ...alert.progress !== void 0 ? { progress: alert.progress } : {},
526
+ ...alert.source ? { source: alert.source } : {},
527
+ ...alert.metadata ? { metadata: alert.metadata } : {}
528
+ };
529
+ await backend.set.mutate({
530
+ collection: ALERTS_COLLECTION,
531
+ key: alert.id,
532
+ value: data
533
+ });
534
+ }
535
+ emitAlertCreatedEvent(alert) {
536
+ this.ctx.eventBus?.emit(createEvent("alert.created", EVENT_SOURCE, {
537
+ id: alert.id,
538
+ category: alert.category,
539
+ severity: alert.severity,
540
+ title: alert.title,
541
+ status: alert.status
542
+ }));
543
+ }
544
+ emitAlertUpdatedEvent(alertId, patch) {
545
+ const patchRecord = {};
546
+ for (const [key, value] of Object.entries(patch)) patchRecord[key] = value;
547
+ this.ctx.eventBus?.emit(createEvent("alert.updated", EVENT_SOURCE, {
548
+ alertId,
549
+ patch: patchRecord
550
+ }));
551
+ }
552
+ async enforceMaxAlerts() {
553
+ const backend = this.ctx.api.settingsStore;
554
+ if (!backend) return;
555
+ const total = await backend.count.query({ collection: ALERTS_COLLECTION });
556
+ if (total <= this.config.maxAlerts) return;
557
+ const excess = total - this.config.maxAlerts;
558
+ const oldest = await backend.query.query({
559
+ collection: ALERTS_COLLECTION,
560
+ filter: {
561
+ where: { read: true },
562
+ orderBy: {
563
+ field: "createdAt",
564
+ direction: "asc"
565
+ },
566
+ limit: excess
567
+ }
568
+ });
569
+ for (const record of oldest) await backend.delete.mutate({
570
+ collection: ALERTS_COLLECTION,
571
+ key: record.id
572
+ });
573
+ }
574
+ async enforceRetention() {
575
+ const backend = this.ctx.api.settingsStore;
576
+ if (!backend) return;
577
+ const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1e3;
578
+ const expired = await backend.query.query({
579
+ collection: ALERTS_COLLECTION,
580
+ filter: {
581
+ where: { read: true },
582
+ orderBy: {
583
+ field: "createdAt",
584
+ direction: "asc"
585
+ }
586
+ }
587
+ });
588
+ for (const record of expired) if (Number(record.data["createdAt"] ?? 0) < cutoff) await backend.delete.mutate({
589
+ collection: ALERTS_COLLECTION,
590
+ key: record.id
591
+ });
592
+ }
593
+ };
594
+ //#endregion
595
+ export { AlertCenterAddon, AlertCenterAddon as default };
@@ -0,0 +1 @@
1
+ export { AlertCenterAddon } from './alerts.addon.js';
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../chunk-Cek0wNdY.js");
3
+ const require_builtins_alerts_alerts_addon = require("./alerts.addon.js");
4
+ exports.AlertCenterAddon = require_builtins_alerts_alerts_addon.AlertCenterAddon;
@@ -0,0 +1,2 @@
1
+ import { AlertCenterAddon } from "./alerts.addon.mjs";
2
+ export { AlertCenterAddon };