@daniel.stefan/metalink 1.3.1

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 (333) hide show
  1. package/README.md +160 -0
  2. package/package.json +96 -0
  3. package/packages/cli/dist/bin/cli.d.ts +3 -0
  4. package/packages/cli/dist/bin/cli.d.ts.map +1 -0
  5. package/packages/cli/dist/bin/cli.js +4 -0
  6. package/packages/cli/dist/bin/cli.js.map +1 -0
  7. package/packages/cli/dist/commands/config/init.d.ts +9 -0
  8. package/packages/cli/dist/commands/config/init.d.ts.map +1 -0
  9. package/packages/cli/dist/commands/config/init.js +38 -0
  10. package/packages/cli/dist/commands/config/init.js.map +1 -0
  11. package/packages/cli/dist/commands/config/validate.d.ts +9 -0
  12. package/packages/cli/dist/commands/config/validate.d.ts.map +1 -0
  13. package/packages/cli/dist/commands/config/validate.js +34 -0
  14. package/packages/cli/dist/commands/config/validate.js.map +1 -0
  15. package/packages/cli/dist/commands/daemon/restart.d.ts +15 -0
  16. package/packages/cli/dist/commands/daemon/restart.d.ts.map +1 -0
  17. package/packages/cli/dist/commands/daemon/restart.js +184 -0
  18. package/packages/cli/dist/commands/daemon/restart.js.map +1 -0
  19. package/packages/cli/dist/commands/daemon/start.d.ts +7 -0
  20. package/packages/cli/dist/commands/daemon/start.d.ts.map +1 -0
  21. package/packages/cli/dist/commands/daemon/start.js +85 -0
  22. package/packages/cli/dist/commands/daemon/start.js.map +1 -0
  23. package/packages/cli/dist/commands/daemon/status.d.ts +7 -0
  24. package/packages/cli/dist/commands/daemon/status.d.ts.map +1 -0
  25. package/packages/cli/dist/commands/daemon/status.js +69 -0
  26. package/packages/cli/dist/commands/daemon/status.js.map +1 -0
  27. package/packages/cli/dist/commands/daemon/stop.d.ts +8 -0
  28. package/packages/cli/dist/commands/daemon/stop.d.ts.map +1 -0
  29. package/packages/cli/dist/commands/daemon/stop.js +77 -0
  30. package/packages/cli/dist/commands/daemon/stop.js.map +1 -0
  31. package/packages/cli/dist/commands/import/mcpm.d.ts +10 -0
  32. package/packages/cli/dist/commands/import/mcpm.d.ts.map +1 -0
  33. package/packages/cli/dist/commands/import/mcpm.js +58 -0
  34. package/packages/cli/dist/commands/import/mcpm.js.map +1 -0
  35. package/packages/cli/dist/commands/safety/add-risky-pattern.d.ts +16 -0
  36. package/packages/cli/dist/commands/safety/add-risky-pattern.d.ts.map +1 -0
  37. package/packages/cli/dist/commands/safety/add-risky-pattern.js +72 -0
  38. package/packages/cli/dist/commands/safety/add-risky-pattern.js.map +1 -0
  39. package/packages/cli/dist/commands/safety/add-risky.d.ts +12 -0
  40. package/packages/cli/dist/commands/safety/add-risky.d.ts.map +1 -0
  41. package/packages/cli/dist/commands/safety/add-risky.js +52 -0
  42. package/packages/cli/dist/commands/safety/add-risky.js.map +1 -0
  43. package/packages/cli/dist/commands/safety/add-safe-pattern.d.ts +16 -0
  44. package/packages/cli/dist/commands/safety/add-safe-pattern.d.ts.map +1 -0
  45. package/packages/cli/dist/commands/safety/add-safe-pattern.js +72 -0
  46. package/packages/cli/dist/commands/safety/add-safe-pattern.js.map +1 -0
  47. package/packages/cli/dist/commands/safety/add-safe.d.ts +12 -0
  48. package/packages/cli/dist/commands/safety/add-safe.d.ts.map +1 -0
  49. package/packages/cli/dist/commands/safety/add-safe.js +52 -0
  50. package/packages/cli/dist/commands/safety/add-safe.js.map +1 -0
  51. package/packages/cli/dist/commands/safety/check.d.ts +9 -0
  52. package/packages/cli/dist/commands/safety/check.d.ts.map +1 -0
  53. package/packages/cli/dist/commands/safety/check.js +36 -0
  54. package/packages/cli/dist/commands/safety/check.js.map +1 -0
  55. package/packages/cli/dist/commands/safety/export.d.ts +10 -0
  56. package/packages/cli/dist/commands/safety/export.d.ts.map +1 -0
  57. package/packages/cli/dist/commands/safety/export.js +48 -0
  58. package/packages/cli/dist/commands/safety/export.js.map +1 -0
  59. package/packages/cli/dist/commands/safety/import.d.ts +12 -0
  60. package/packages/cli/dist/commands/safety/import.d.ts.map +1 -0
  61. package/packages/cli/dist/commands/safety/import.js +78 -0
  62. package/packages/cli/dist/commands/safety/import.js.map +1 -0
  63. package/packages/cli/dist/commands/safety/index.d.ts +8 -0
  64. package/packages/cli/dist/commands/safety/index.d.ts.map +1 -0
  65. package/packages/cli/dist/commands/safety/index.js +46 -0
  66. package/packages/cli/dist/commands/safety/index.js.map +1 -0
  67. package/packages/cli/dist/commands/safety/list.d.ts +6 -0
  68. package/packages/cli/dist/commands/safety/list.d.ts.map +1 -0
  69. package/packages/cli/dist/commands/safety/list.js +77 -0
  70. package/packages/cli/dist/commands/safety/list.js.map +1 -0
  71. package/packages/cli/dist/commands/safety/remove.d.ts +9 -0
  72. package/packages/cli/dist/commands/safety/remove.d.ts.map +1 -0
  73. package/packages/cli/dist/commands/safety/remove.js +46 -0
  74. package/packages/cli/dist/commands/safety/remove.js.map +1 -0
  75. package/packages/cli/dist/commands/safety/reset.d.ts +9 -0
  76. package/packages/cli/dist/commands/safety/reset.d.ts.map +1 -0
  77. package/packages/cli/dist/commands/safety/reset.js +46 -0
  78. package/packages/cli/dist/commands/safety/reset.js.map +1 -0
  79. package/packages/cli/dist/commands/safety/validate.d.ts +9 -0
  80. package/packages/cli/dist/commands/safety/validate.d.ts.map +1 -0
  81. package/packages/cli/dist/commands/safety/validate.js +51 -0
  82. package/packages/cli/dist/commands/safety/validate.js.map +1 -0
  83. package/packages/cli/dist/commands/secret/get.d.ts +9 -0
  84. package/packages/cli/dist/commands/secret/get.d.ts.map +1 -0
  85. package/packages/cli/dist/commands/secret/get.js +26 -0
  86. package/packages/cli/dist/commands/secret/get.js.map +1 -0
  87. package/packages/cli/dist/commands/secret/set.d.ts +10 -0
  88. package/packages/cli/dist/commands/secret/set.d.ts.map +1 -0
  89. package/packages/cli/dist/commands/secret/set.js +22 -0
  90. package/packages/cli/dist/commands/secret/set.js.map +1 -0
  91. package/packages/cli/dist/commands/server/__tests__/server-management-e2e.test.d.ts +2 -0
  92. package/packages/cli/dist/commands/server/__tests__/server-management-e2e.test.d.ts.map +1 -0
  93. package/packages/cli/dist/commands/server/__tests__/server-management-e2e.test.js +234 -0
  94. package/packages/cli/dist/commands/server/__tests__/server-management-e2e.test.js.map +1 -0
  95. package/packages/cli/dist/commands/server/add.d.ts +14 -0
  96. package/packages/cli/dist/commands/server/add.d.ts.map +1 -0
  97. package/packages/cli/dist/commands/server/add.js +86 -0
  98. package/packages/cli/dist/commands/server/add.js.map +1 -0
  99. package/packages/cli/dist/commands/server/available.d.ts +10 -0
  100. package/packages/cli/dist/commands/server/available.d.ts.map +1 -0
  101. package/packages/cli/dist/commands/server/available.js +62 -0
  102. package/packages/cli/dist/commands/server/available.js.map +1 -0
  103. package/packages/cli/dist/commands/server/debug.d.ts +18 -0
  104. package/packages/cli/dist/commands/server/debug.d.ts.map +1 -0
  105. package/packages/cli/dist/commands/server/debug.js +165 -0
  106. package/packages/cli/dist/commands/server/debug.js.map +1 -0
  107. package/packages/cli/dist/commands/server/info.d.ts +13 -0
  108. package/packages/cli/dist/commands/server/info.d.ts.map +1 -0
  109. package/packages/cli/dist/commands/server/info.js +62 -0
  110. package/packages/cli/dist/commands/server/info.js.map +1 -0
  111. package/packages/cli/dist/commands/server/list.d.ts +10 -0
  112. package/packages/cli/dist/commands/server/list.d.ts.map +1 -0
  113. package/packages/cli/dist/commands/server/list.js +105 -0
  114. package/packages/cli/dist/commands/server/list.js.map +1 -0
  115. package/packages/cli/dist/commands/server/refresh-tools.d.ts +13 -0
  116. package/packages/cli/dist/commands/server/refresh-tools.d.ts.map +1 -0
  117. package/packages/cli/dist/commands/server/refresh-tools.js +46 -0
  118. package/packages/cli/dist/commands/server/refresh-tools.js.map +1 -0
  119. package/packages/cli/dist/commands/server/remove.d.ts +12 -0
  120. package/packages/cli/dist/commands/server/remove.d.ts.map +1 -0
  121. package/packages/cli/dist/commands/server/remove.js +39 -0
  122. package/packages/cli/dist/commands/server/remove.js.map +1 -0
  123. package/packages/cli/dist/commands/server/restart.d.ts +9 -0
  124. package/packages/cli/dist/commands/server/restart.d.ts.map +1 -0
  125. package/packages/cli/dist/commands/server/restart.js +30 -0
  126. package/packages/cli/dist/commands/server/restart.js.map +1 -0
  127. package/packages/cli/dist/commands/server/start.d.ts +9 -0
  128. package/packages/cli/dist/commands/server/start.d.ts.map +1 -0
  129. package/packages/cli/dist/commands/server/start.js +37 -0
  130. package/packages/cli/dist/commands/server/start.js.map +1 -0
  131. package/packages/cli/dist/commands/server/status.d.ts +9 -0
  132. package/packages/cli/dist/commands/server/status.d.ts.map +1 -0
  133. package/packages/cli/dist/commands/server/status.js +30 -0
  134. package/packages/cli/dist/commands/server/status.js.map +1 -0
  135. package/packages/cli/dist/commands/server/stop.d.ts +9 -0
  136. package/packages/cli/dist/commands/server/stop.d.ts.map +1 -0
  137. package/packages/cli/dist/commands/server/stop.js +31 -0
  138. package/packages/cli/dist/commands/server/stop.js.map +1 -0
  139. package/packages/cli/dist/commands/server/validate.d.ts +15 -0
  140. package/packages/cli/dist/commands/server/validate.d.ts.map +1 -0
  141. package/packages/cli/dist/commands/server/validate.js +87 -0
  142. package/packages/cli/dist/commands/server/validate.js.map +1 -0
  143. package/packages/cli/dist/commands/stdio.d.ts +36 -0
  144. package/packages/cli/dist/commands/stdio.d.ts.map +1 -0
  145. package/packages/cli/dist/commands/stdio.js +85 -0
  146. package/packages/cli/dist/commands/stdio.js.map +1 -0
  147. package/packages/cli/dist/commands/tool/execute-confirm.d.ts +12 -0
  148. package/packages/cli/dist/commands/tool/execute-confirm.d.ts.map +1 -0
  149. package/packages/cli/dist/commands/tool/execute-confirm.js +98 -0
  150. package/packages/cli/dist/commands/tool/execute-confirm.js.map +1 -0
  151. package/packages/cli/dist/commands/tool/execute.d.ts +12 -0
  152. package/packages/cli/dist/commands/tool/execute.d.ts.map +1 -0
  153. package/packages/cli/dist/commands/tool/execute.js +55 -0
  154. package/packages/cli/dist/commands/tool/execute.js.map +1 -0
  155. package/packages/cli/dist/commands/tool/list.d.ts +13 -0
  156. package/packages/cli/dist/commands/tool/list.d.ts.map +1 -0
  157. package/packages/cli/dist/commands/tool/list.js +91 -0
  158. package/packages/cli/dist/commands/tool/list.js.map +1 -0
  159. package/packages/cli/dist/commands/tool/search.d.ts +12 -0
  160. package/packages/cli/dist/commands/tool/search.d.ts.map +1 -0
  161. package/packages/cli/dist/commands/tool/search.js +87 -0
  162. package/packages/cli/dist/commands/tool/search.js.map +1 -0
  163. package/packages/cli/dist/index.d.ts +2 -0
  164. package/packages/cli/dist/index.d.ts.map +1 -0
  165. package/packages/cli/dist/index.js +9 -0
  166. package/packages/cli/dist/index.js.map +1 -0
  167. package/packages/cli/dist/utils/daemon-checker.d.ts +18 -0
  168. package/packages/cli/dist/utils/daemon-checker.d.ts.map +1 -0
  169. package/packages/cli/dist/utils/daemon-checker.js +69 -0
  170. package/packages/cli/dist/utils/daemon-checker.js.map +1 -0
  171. package/packages/cli/dist/utils/daemon-endpoint.d.ts +7 -0
  172. package/packages/cli/dist/utils/daemon-endpoint.d.ts.map +1 -0
  173. package/packages/cli/dist/utils/daemon-endpoint.js +13 -0
  174. package/packages/cli/dist/utils/daemon-endpoint.js.map +1 -0
  175. package/packages/cli/dist/utils/get-configured-port.d.ts +43 -0
  176. package/packages/cli/dist/utils/get-configured-port.d.ts.map +1 -0
  177. package/packages/cli/dist/utils/get-configured-port.js +141 -0
  178. package/packages/cli/dist/utils/get-configured-port.js.map +1 -0
  179. package/packages/cli/dist/utils/stdio-bridge.d.ts +48 -0
  180. package/packages/cli/dist/utils/stdio-bridge.d.ts.map +1 -0
  181. package/packages/cli/dist/utils/stdio-bridge.js +181 -0
  182. package/packages/cli/dist/utils/stdio-bridge.js.map +1 -0
  183. package/packages/cli/package.json +48 -0
  184. package/packages/core/dist/config/defaults.d.ts +36 -0
  185. package/packages/core/dist/config/defaults.d.ts.map +1 -0
  186. package/packages/core/dist/config/defaults.js +324 -0
  187. package/packages/core/dist/config/defaults.js.map +1 -0
  188. package/packages/core/dist/config/index.d.ts +9 -0
  189. package/packages/core/dist/config/index.d.ts.map +1 -0
  190. package/packages/core/dist/config/index.js +14 -0
  191. package/packages/core/dist/config/index.js.map +1 -0
  192. package/packages/core/dist/config/loader.d.ts +269 -0
  193. package/packages/core/dist/config/loader.d.ts.map +1 -0
  194. package/packages/core/dist/config/loader.js +777 -0
  195. package/packages/core/dist/config/loader.js.map +1 -0
  196. package/packages/core/dist/config/registry.d.ts +212 -0
  197. package/packages/core/dist/config/registry.d.ts.map +1 -0
  198. package/packages/core/dist/config/registry.js +754 -0
  199. package/packages/core/dist/config/registry.js.map +1 -0
  200. package/packages/core/dist/config/schema.d.ts +4352 -0
  201. package/packages/core/dist/config/schema.d.ts.map +1 -0
  202. package/packages/core/dist/config/schema.js +267 -0
  203. package/packages/core/dist/config/schema.js.map +1 -0
  204. package/packages/core/dist/daemon.d.ts +7 -0
  205. package/packages/core/dist/daemon.d.ts.map +1 -0
  206. package/packages/core/dist/daemon.js +116 -0
  207. package/packages/core/dist/daemon.js.map +1 -0
  208. package/packages/core/dist/http-client-retry.d.ts +67 -0
  209. package/packages/core/dist/http-client-retry.d.ts.map +1 -0
  210. package/packages/core/dist/http-client-retry.js +133 -0
  211. package/packages/core/dist/http-client-retry.js.map +1 -0
  212. package/packages/core/dist/http-client-updated.d.ts +147 -0
  213. package/packages/core/dist/http-client-updated.d.ts.map +1 -0
  214. package/packages/core/dist/http-client-updated.js +452 -0
  215. package/packages/core/dist/http-client-updated.js.map +1 -0
  216. package/packages/core/dist/http-client.d.ts +207 -0
  217. package/packages/core/dist/http-client.d.ts.map +1 -0
  218. package/packages/core/dist/http-client.js +704 -0
  219. package/packages/core/dist/http-client.js.map +1 -0
  220. package/packages/core/dist/index.d.ts +13 -0
  221. package/packages/core/dist/index.d.ts.map +1 -0
  222. package/packages/core/dist/index.js +23 -0
  223. package/packages/core/dist/index.js.map +1 -0
  224. package/packages/core/dist/logging/index.d.ts +46 -0
  225. package/packages/core/dist/logging/index.d.ts.map +1 -0
  226. package/packages/core/dist/logging/index.js +74 -0
  227. package/packages/core/dist/logging/index.js.map +1 -0
  228. package/packages/core/dist/metrics/index.d.ts +339 -0
  229. package/packages/core/dist/metrics/index.d.ts.map +1 -0
  230. package/packages/core/dist/metrics/index.js +792 -0
  231. package/packages/core/dist/metrics/index.js.map +1 -0
  232. package/packages/core/dist/plugins/index.d.ts +49 -0
  233. package/packages/core/dist/plugins/index.d.ts.map +1 -0
  234. package/packages/core/dist/plugins/index.js +82 -0
  235. package/packages/core/dist/plugins/index.js.map +1 -0
  236. package/packages/core/dist/secrets/index.d.ts +6 -0
  237. package/packages/core/dist/secrets/index.d.ts.map +1 -0
  238. package/packages/core/dist/secrets/index.js +5 -0
  239. package/packages/core/dist/secrets/index.js.map +1 -0
  240. package/packages/core/dist/secrets/keyring.d.ts +54 -0
  241. package/packages/core/dist/secrets/keyring.d.ts.map +1 -0
  242. package/packages/core/dist/secrets/keyring.js +141 -0
  243. package/packages/core/dist/secrets/keyring.js.map +1 -0
  244. package/packages/core/dist/server/batch-executor.d.ts +83 -0
  245. package/packages/core/dist/server/batch-executor.d.ts.map +1 -0
  246. package/packages/core/dist/server/batch-executor.js +291 -0
  247. package/packages/core/dist/server/batch-executor.js.map +1 -0
  248. package/packages/core/dist/server/circuit-breaker.d.ts +215 -0
  249. package/packages/core/dist/server/circuit-breaker.d.ts.map +1 -0
  250. package/packages/core/dist/server/circuit-breaker.js +330 -0
  251. package/packages/core/dist/server/circuit-breaker.js.map +1 -0
  252. package/packages/core/dist/server/client-detection.d.ts +40 -0
  253. package/packages/core/dist/server/client-detection.d.ts.map +1 -0
  254. package/packages/core/dist/server/client-detection.js +242 -0
  255. package/packages/core/dist/server/client-detection.js.map +1 -0
  256. package/packages/core/dist/server/client-profiles.d.ts +102 -0
  257. package/packages/core/dist/server/client-profiles.d.ts.map +1 -0
  258. package/packages/core/dist/server/client-profiles.js +254 -0
  259. package/packages/core/dist/server/client-profiles.js.map +1 -0
  260. package/packages/core/dist/server/http.d.ts +386 -0
  261. package/packages/core/dist/server/http.d.ts.map +1 -0
  262. package/packages/core/dist/server/http.js +4253 -0
  263. package/packages/core/dist/server/http.js.map +1 -0
  264. package/packages/core/dist/server/index.d.ts +7 -0
  265. package/packages/core/dist/server/index.d.ts.map +1 -0
  266. package/packages/core/dist/server/index.js +6 -0
  267. package/packages/core/dist/server/index.js.map +1 -0
  268. package/packages/core/dist/server/manager.d.ts +458 -0
  269. package/packages/core/dist/server/manager.d.ts.map +1 -0
  270. package/packages/core/dist/server/manager.js +3255 -0
  271. package/packages/core/dist/server/manager.js.map +1 -0
  272. package/packages/core/dist/server/managers/HttpConnectionManager.d.ts +69 -0
  273. package/packages/core/dist/server/managers/HttpConnectionManager.d.ts.map +1 -0
  274. package/packages/core/dist/server/managers/HttpConnectionManager.js +214 -0
  275. package/packages/core/dist/server/managers/HttpConnectionManager.js.map +1 -0
  276. package/packages/core/dist/server/managers/ProcessManager.d.ts +128 -0
  277. package/packages/core/dist/server/managers/ProcessManager.d.ts.map +1 -0
  278. package/packages/core/dist/server/managers/ProcessManager.js +443 -0
  279. package/packages/core/dist/server/managers/ProcessManager.js.map +1 -0
  280. package/packages/core/dist/server/managers/SchemaCacheManager.d.ts +152 -0
  281. package/packages/core/dist/server/managers/SchemaCacheManager.d.ts.map +1 -0
  282. package/packages/core/dist/server/managers/SchemaCacheManager.js +426 -0
  283. package/packages/core/dist/server/managers/SchemaCacheManager.js.map +1 -0
  284. package/packages/core/dist/server/managers/index.d.ts +9 -0
  285. package/packages/core/dist/server/managers/index.d.ts.map +1 -0
  286. package/packages/core/dist/server/managers/index.js +9 -0
  287. package/packages/core/dist/server/managers/index.js.map +1 -0
  288. package/packages/core/dist/server/metrics.d.ts +134 -0
  289. package/packages/core/dist/server/metrics.d.ts.map +1 -0
  290. package/packages/core/dist/server/metrics.js +273 -0
  291. package/packages/core/dist/server/metrics.js.map +1 -0
  292. package/packages/core/dist/server/prompts.d.ts +58 -0
  293. package/packages/core/dist/server/prompts.d.ts.map +1 -0
  294. package/packages/core/dist/server/prompts.js +405 -0
  295. package/packages/core/dist/server/prompts.js.map +1 -0
  296. package/packages/core/dist/server/protocol-versions.d.ts +49 -0
  297. package/packages/core/dist/server/protocol-versions.d.ts.map +1 -0
  298. package/packages/core/dist/server/protocol-versions.js +173 -0
  299. package/packages/core/dist/server/protocol-versions.js.map +1 -0
  300. package/packages/core/dist/server/resources.d.ts +64 -0
  301. package/packages/core/dist/server/resources.d.ts.map +1 -0
  302. package/packages/core/dist/server/resources.js +243 -0
  303. package/packages/core/dist/server/resources.js.map +1 -0
  304. package/packages/core/dist/server/schema-store.d.ts +84 -0
  305. package/packages/core/dist/server/schema-store.d.ts.map +1 -0
  306. package/packages/core/dist/server/schema-store.js +234 -0
  307. package/packages/core/dist/server/schema-store.js.map +1 -0
  308. package/packages/core/dist/server/schema-validator.d.ts +51 -0
  309. package/packages/core/dist/server/schema-validator.d.ts.map +1 -0
  310. package/packages/core/dist/server/schema-validator.js +208 -0
  311. package/packages/core/dist/server/schema-validator.js.map +1 -0
  312. package/packages/core/dist/server/token-calculator.d.ts +44 -0
  313. package/packages/core/dist/server/token-calculator.d.ts.map +1 -0
  314. package/packages/core/dist/server/token-calculator.js +53 -0
  315. package/packages/core/dist/server/token-calculator.js.map +1 -0
  316. package/packages/core/dist/server/types.d.ts +45 -0
  317. package/packages/core/dist/server/types.d.ts.map +1 -0
  318. package/packages/core/dist/server/types.js +5 -0
  319. package/packages/core/dist/server/types.js.map +1 -0
  320. package/packages/core/dist/utils/file-lock.d.ts +73 -0
  321. package/packages/core/dist/utils/file-lock.d.ts.map +1 -0
  322. package/packages/core/dist/utils/file-lock.js +235 -0
  323. package/packages/core/dist/utils/file-lock.js.map +1 -0
  324. package/packages/core/package.json +36 -0
  325. package/packages/dashboard/dist/assets/index-B7hvkCMu.css +1 -0
  326. package/packages/dashboard/dist/assets/index-yZhLPpzr.js +1 -0
  327. package/packages/dashboard/dist/index.html +14 -0
  328. package/packages/dashboard/package.json +24 -0
  329. package/packages/shared/dist/version.d.ts +2 -0
  330. package/packages/shared/dist/version.d.ts.map +1 -0
  331. package/packages/shared/dist/version.js +2 -0
  332. package/packages/shared/dist/version.js.map +1 -0
  333. package/packages/shared/package.json +18 -0
@@ -0,0 +1,792 @@
1
+ /**
2
+ * Metrics Collection and Reporting
3
+ * Tracks server performance and API usage
4
+ */
5
+ import fs from 'fs';
6
+ import { promises as fsPromises } from 'fs';
7
+ import path from 'path';
8
+ /**
9
+ * Metrics Collector
10
+ */
11
+ export class MetricsCollector {
12
+ constructor() {
13
+ this.metrics = new Map();
14
+ this.serverMetrics = new Map();
15
+ this.toolMetrics = new Map(); // Key: "serverName-toolName"
16
+ this.errorRecords = []; // Keep last 1000 errors
17
+ this.toolCallCounts = new Map(); // Track total calls per tool
18
+ this.toolErrorCounts = new Map(); // Track error counts per tool
19
+ this.apiMetrics = {
20
+ requests: 0,
21
+ responses: 0,
22
+ errors: 0,
23
+ avgResponseTime: 0,
24
+ lastRequest: 0,
25
+ };
26
+ }
27
+ /**
28
+ * Increment counter metric
29
+ */
30
+ incrementCounter(name, unit = '') {
31
+ if (!this.metrics.has(name)) {
32
+ this.metrics.set(name, {
33
+ name,
34
+ type: 'counter',
35
+ unit,
36
+ value: 0,
37
+ history: [],
38
+ });
39
+ }
40
+ const metric = this.metrics.get(name);
41
+ metric.value++;
42
+ metric.history.push({
43
+ timestamp: Date.now(),
44
+ value: metric.value,
45
+ });
46
+ // Keep only last 1000 data points
47
+ if (metric.history.length > 1000) {
48
+ metric.history = metric.history.slice(-1000);
49
+ }
50
+ }
51
+ /**
52
+ * Set gauge metric
53
+ */
54
+ setGauge(name, value, unit = '') {
55
+ if (!this.metrics.has(name)) {
56
+ this.metrics.set(name, {
57
+ name,
58
+ type: 'gauge',
59
+ unit,
60
+ value,
61
+ history: [],
62
+ });
63
+ }
64
+ const metric = this.metrics.get(name);
65
+ metric.value = value;
66
+ metric.history.push({
67
+ timestamp: Date.now(),
68
+ value,
69
+ });
70
+ // Keep only last 1000 data points
71
+ if (metric.history.length > 1000) {
72
+ metric.history = metric.history.slice(-1000);
73
+ }
74
+ }
75
+ /**
76
+ * Record server startup
77
+ */
78
+ recordServerStart(serverName) {
79
+ this.serverMetrics.set(serverName, {
80
+ serverName,
81
+ startTime: Date.now(),
82
+ uptime: 0,
83
+ restarts: (this.serverMetrics.get(serverName)?.restarts || 0) + 1,
84
+ errors: 0,
85
+ tools: { total: 0, executed: 0, failed: 0 },
86
+ });
87
+ }
88
+ /**
89
+ * Record server error
90
+ */
91
+ recordServerError(serverName, error, errorType) {
92
+ const metrics = this.serverMetrics.get(serverName);
93
+ if (metrics) {
94
+ metrics.errors++;
95
+ metrics.lastError = error;
96
+ }
97
+ // If errorType provided, also record detailed error for analytics
98
+ if (errorType) {
99
+ this.recordToolError(error, undefined, serverName);
100
+ }
101
+ }
102
+ /**
103
+ * Record API request
104
+ */
105
+ recordApiRequest() {
106
+ this.apiMetrics.requests++;
107
+ this.apiMetrics.lastRequest = Date.now();
108
+ }
109
+ /**
110
+ * Record API response
111
+ */
112
+ recordApiResponse(responseTime) {
113
+ this.apiMetrics.responses++;
114
+ // Calculate running average
115
+ const totalTime = this.apiMetrics.avgResponseTime * (this.apiMetrics.responses - 1) + responseTime;
116
+ this.apiMetrics.avgResponseTime = totalTime / this.apiMetrics.responses;
117
+ }
118
+ /**
119
+ * Record API error
120
+ */
121
+ recordApiError() {
122
+ this.apiMetrics.errors++;
123
+ }
124
+ /**
125
+ * Record tool execution (success)
126
+ * @param serverName - Server name (e.g., "memory", "time")
127
+ * @param toolName - Tool name (e.g., "create_entities", "get_current_time")
128
+ * @param latency - Execution time in milliseconds
129
+ */
130
+ recordToolExecution(serverName, toolName, latency) {
131
+ const key = `${serverName}-${toolName}`;
132
+ if (!this.toolMetrics.has(key)) {
133
+ this.toolMetrics.set(key, {
134
+ toolName,
135
+ serverName,
136
+ calls: 0,
137
+ successes: 0,
138
+ failures: 0,
139
+ totalLatency: 0,
140
+ minLatency: Infinity,
141
+ maxLatency: 0,
142
+ avgLatency: 0,
143
+ latencyHistory: [],
144
+ lastCall: 0,
145
+ });
146
+ }
147
+ const metrics = this.toolMetrics.get(key);
148
+ metrics.calls++;
149
+ metrics.successes++;
150
+ metrics.totalLatency += latency;
151
+ metrics.minLatency = Math.min(metrics.minLatency, latency);
152
+ metrics.maxLatency = Math.max(metrics.maxLatency, latency);
153
+ metrics.avgLatency = metrics.totalLatency / metrics.successes;
154
+ metrics.lastCall = Date.now();
155
+ // Keep last 1000 latencies for percentile calculation
156
+ metrics.latencyHistory.push(latency);
157
+ if (metrics.latencyHistory.length > 1000) {
158
+ metrics.latencyHistory = metrics.latencyHistory.slice(-1000);
159
+ }
160
+ }
161
+ /**
162
+ * Record tool execution failure
163
+ * @param serverName - Server name
164
+ * @param toolName - Tool name
165
+ * @param error - Error message
166
+ */
167
+ recordToolFailure(serverName, toolName, error) {
168
+ const key = `${serverName}-${toolName}`;
169
+ if (!this.toolMetrics.has(key)) {
170
+ this.toolMetrics.set(key, {
171
+ toolName,
172
+ serverName,
173
+ calls: 0,
174
+ successes: 0,
175
+ failures: 0,
176
+ totalLatency: 0,
177
+ minLatency: Infinity,
178
+ maxLatency: 0,
179
+ avgLatency: 0,
180
+ latencyHistory: [],
181
+ lastCall: 0,
182
+ });
183
+ }
184
+ const metrics = this.toolMetrics.get(key);
185
+ metrics.calls++;
186
+ metrics.failures++;
187
+ metrics.lastCall = Date.now();
188
+ metrics.lastError = error;
189
+ }
190
+ /**
191
+ * Calculate percentile from sorted array
192
+ * @param sortedArray - Sorted array of numbers
193
+ * @param percentile - Percentile to calculate (0-100)
194
+ */
195
+ calculatePercentile(sortedArray, percentile) {
196
+ if (sortedArray.length === 0)
197
+ return 0;
198
+ const index = (percentile / 100) * (sortedArray.length - 1);
199
+ const lower = Math.floor(index);
200
+ const upper = Math.ceil(index);
201
+ const weight = index % 1;
202
+ if (lower === upper) {
203
+ return sortedArray[lower];
204
+ }
205
+ return sortedArray[lower] * (1 - weight) + sortedArray[upper] * weight;
206
+ }
207
+ /**
208
+ * Get all tool metrics with percentiles
209
+ */
210
+ getAllToolMetrics() {
211
+ return Array.from(this.toolMetrics.values()).map((metrics) => {
212
+ const sortedLatencies = [...metrics.latencyHistory].sort((a, b) => a - b);
213
+ return {
214
+ toolName: metrics.toolName,
215
+ serverName: metrics.serverName,
216
+ calls: metrics.calls,
217
+ successRate: metrics.calls > 0 ? (metrics.successes / metrics.calls) * 100 : 0,
218
+ failureRate: metrics.calls > 0 ? (metrics.failures / metrics.calls) * 100 : 0,
219
+ latency: {
220
+ min: metrics.minLatency === Infinity ? 0 : metrics.minLatency,
221
+ max: metrics.maxLatency,
222
+ avg: metrics.avgLatency,
223
+ p50: this.calculatePercentile(sortedLatencies, 50),
224
+ p95: this.calculatePercentile(sortedLatencies, 95),
225
+ p99: this.calculatePercentile(sortedLatencies, 99),
226
+ },
227
+ lastCall: metrics.lastCall,
228
+ lastError: metrics.lastError,
229
+ };
230
+ });
231
+ }
232
+ /**
233
+ * Get tool metrics for a specific tool
234
+ * @param serverName - Server name
235
+ * @param toolName - Tool name
236
+ */
237
+ getToolMetrics(serverName, toolName) {
238
+ const key = `${serverName}-${toolName}`;
239
+ const metrics = this.toolMetrics.get(key);
240
+ if (!metrics) {
241
+ return undefined;
242
+ }
243
+ const sortedLatencies = [...metrics.latencyHistory].sort((a, b) => a - b);
244
+ return {
245
+ toolName: metrics.toolName,
246
+ serverName: metrics.serverName,
247
+ calls: metrics.calls,
248
+ successRate: metrics.calls > 0 ? (metrics.successes / metrics.calls) * 100 : 0,
249
+ failureRate: metrics.calls > 0 ? (metrics.failures / metrics.calls) * 100 : 0,
250
+ latency: {
251
+ min: metrics.minLatency === Infinity ? 0 : metrics.minLatency,
252
+ max: metrics.maxLatency,
253
+ avg: metrics.avgLatency,
254
+ p50: this.calculatePercentile(sortedLatencies, 50),
255
+ p95: this.calculatePercentile(sortedLatencies, 95),
256
+ p99: this.calculatePercentile(sortedLatencies, 99),
257
+ },
258
+ lastCall: metrics.lastCall,
259
+ lastError: metrics.lastError,
260
+ };
261
+ }
262
+ /**
263
+ * Get top N slowest tools by P95 latency
264
+ * @param limit - Number of tools to return (default: 10)
265
+ */
266
+ getSlowestTools(limit = 10) {
267
+ const allMetrics = this.getAllToolMetrics();
268
+ return allMetrics
269
+ .sort((a, b) => b.latency.p95 - a.latency.p95)
270
+ .slice(0, limit);
271
+ }
272
+ /**
273
+ * Get tools with high error rates
274
+ * @param threshold - Error rate threshold percentage (default: 5%)
275
+ */
276
+ getHighErrorRateTools(threshold = 5) {
277
+ const allMetrics = this.getAllToolMetrics();
278
+ return allMetrics
279
+ .filter((m) => m.failureRate >= threshold && m.calls >= 5) // At least 5 calls to be meaningful
280
+ .sort((a, b) => b.failureRate - a.failureRate);
281
+ }
282
+ /**
283
+ * Classify error type from error message
284
+ * Public method to allow external error classification
285
+ */
286
+ classifyErrorType(error) {
287
+ const message = typeof error === 'string' ? error : error.message;
288
+ const lowerMessage = message.toLowerCase();
289
+ if (lowerMessage.includes('invalid') || lowerMessage.includes('validation') || lowerMessage.includes('required')) {
290
+ return 'validation';
291
+ }
292
+ if (lowerMessage.includes('timeout') || lowerMessage.includes('timed out')) {
293
+ return 'timeout';
294
+ }
295
+ if (lowerMessage.includes('econnrefused') || lowerMessage.includes('connection') || lowerMessage.includes('enotfound')) {
296
+ return 'connection';
297
+ }
298
+ if (lowerMessage.includes('rate limit')) {
299
+ return 'rate_limit';
300
+ }
301
+ if (lowerMessage.includes('permission') || lowerMessage.includes('unauthorized') || lowerMessage.includes('forbidden')) {
302
+ return 'permission';
303
+ }
304
+ if (lowerMessage.includes('not found') || lowerMessage.includes('does not exist')) {
305
+ return 'not_found';
306
+ }
307
+ if (lowerMessage.includes('internal') || lowerMessage.includes('crash')) {
308
+ return 'internal';
309
+ }
310
+ return 'unknown';
311
+ }
312
+ /**
313
+ * Record tool call (success or failure)
314
+ */
315
+ recordToolCall(toolName, serverName) {
316
+ const key = serverName ? `${serverName}-${toolName}` : toolName;
317
+ this.toolCallCounts.set(key, (this.toolCallCounts.get(key) || 0) + 1);
318
+ }
319
+ /**
320
+ * Record tool error with detailed tracking
321
+ */
322
+ recordToolError(error, toolName, serverName) {
323
+ const errorType = this.classifyErrorType(error);
324
+ const errorMessage = typeof error === 'string' ? error : error.message;
325
+ const stack = typeof error === 'string' ? undefined : error.stack;
326
+ const errorRecord = {
327
+ timestamp: Date.now(),
328
+ errorType,
329
+ message: errorMessage,
330
+ toolName,
331
+ serverName,
332
+ stack,
333
+ };
334
+ // Add to error records (keep last 1000)
335
+ this.errorRecords.push(errorRecord);
336
+ if (this.errorRecords.length > 1000) {
337
+ this.errorRecords = this.errorRecords.slice(-1000);
338
+ }
339
+ // Track error counts per tool
340
+ if (toolName) {
341
+ const key = serverName ? `${serverName}-${toolName}` : toolName;
342
+ this.toolErrorCounts.set(key, (this.toolErrorCounts.get(key) || 0) + 1);
343
+ }
344
+ }
345
+ /**
346
+ * Get error analytics for a specific tool
347
+ */
348
+ getToolErrorMetrics(toolName, serverName) {
349
+ const key = serverName ? `${serverName}-${toolName}` : toolName;
350
+ const totalCalls = this.toolCallCounts.get(key) || 0;
351
+ const totalErrors = this.toolErrorCounts.get(key) || 0;
352
+ if (totalCalls === 0) {
353
+ return null;
354
+ }
355
+ // Get errors for this tool
356
+ const toolErrors = this.errorRecords.filter((e) => e.toolName === toolName && (!serverName || e.serverName === serverName));
357
+ // Count errors by type
358
+ const errorsByType = {
359
+ validation: 0,
360
+ timeout: 0,
361
+ connection: 0,
362
+ internal: 0,
363
+ rate_limit: 0,
364
+ permission: 0,
365
+ not_found: 0,
366
+ unknown: 0,
367
+ };
368
+ for (const error of toolErrors) {
369
+ errorsByType[error.errorType]++;
370
+ }
371
+ // Calculate error patterns
372
+ const errorPatterns = Object.entries(errorsByType)
373
+ .filter(([_, count]) => count > 0)
374
+ .map(([type, count]) => ({
375
+ type: type,
376
+ count,
377
+ percentage: totalErrors > 0 ? (count / totalErrors) * 100 : 0,
378
+ }))
379
+ .sort((a, b) => b.count - a.count);
380
+ return {
381
+ toolName,
382
+ serverName: serverName || 'unknown',
383
+ totalCalls,
384
+ totalErrors,
385
+ errorRate: totalCalls > 0 ? (totalErrors / totalCalls) * 100 : 0,
386
+ errorsByType,
387
+ recentErrors: toolErrors.slice(-10), // Last 10 errors
388
+ lastError: toolErrors[toolErrors.length - 1],
389
+ errorPatterns,
390
+ };
391
+ }
392
+ /**
393
+ * Get aggregated error analytics across all tools
394
+ */
395
+ getErrorAnalytics() {
396
+ const totalCalls = Array.from(this.toolCallCounts.values()).reduce((sum, count) => sum + count, 0);
397
+ const totalErrors = this.errorRecords.length;
398
+ // Count errors by type
399
+ const errorsByType = {
400
+ validation: 0,
401
+ timeout: 0,
402
+ connection: 0,
403
+ internal: 0,
404
+ rate_limit: 0,
405
+ permission: 0,
406
+ not_found: 0,
407
+ unknown: 0,
408
+ };
409
+ const errorsByServer = {};
410
+ const errorsByTool = {};
411
+ for (const error of this.errorRecords) {
412
+ errorsByType[error.errorType]++;
413
+ if (error.serverName) {
414
+ errorsByServer[error.serverName] = (errorsByServer[error.serverName] || 0) + 1;
415
+ }
416
+ if (error.toolName) {
417
+ const key = error.serverName ? `${error.serverName}-${error.toolName}` : error.toolName;
418
+ errorsByTool[key] = (errorsByTool[key] || 0) + 1;
419
+ }
420
+ }
421
+ // Calculate top failing tools
422
+ const topFailingTools = [];
423
+ for (const [key, errorCount] of this.toolErrorCounts.entries()) {
424
+ const totalCalls = this.toolCallCounts.get(key) || 0;
425
+ if (totalCalls > 0) {
426
+ const [serverName, ...toolParts] = key.split('-');
427
+ const toolName = toolParts.join('-');
428
+ topFailingTools.push({
429
+ toolName,
430
+ serverName,
431
+ errorCount,
432
+ errorRate: (errorCount / totalCalls) * 100,
433
+ });
434
+ }
435
+ }
436
+ // Sort by error count descending
437
+ topFailingTools.sort((a, b) => b.errorCount - a.errorCount);
438
+ return {
439
+ totalErrors,
440
+ totalCalls,
441
+ errorRate: totalCalls > 0 ? (totalErrors / totalCalls) * 100 : 0,
442
+ errorsByType,
443
+ errorsByServer,
444
+ errorsByTool,
445
+ recentErrors: this.errorRecords.slice(-50), // Last 50 errors
446
+ topFailingTools: topFailingTools.slice(0, 10), // Top 10 failing tools
447
+ };
448
+ }
449
+ /**
450
+ * Get all metrics
451
+ */
452
+ getMetrics() {
453
+ return Array.from(this.metrics.values());
454
+ }
455
+ /**
456
+ * Get metric by name
457
+ */
458
+ getMetric(name) {
459
+ return this.metrics.get(name);
460
+ }
461
+ /**
462
+ * Get server metrics
463
+ */
464
+ getServerMetrics(serverName) {
465
+ const metrics = this.serverMetrics.get(serverName);
466
+ if (metrics) {
467
+ metrics.uptime = Date.now() - metrics.startTime;
468
+ }
469
+ return metrics;
470
+ }
471
+ /**
472
+ * Get API metrics
473
+ */
474
+ getApiMetrics() {
475
+ return { ...this.apiMetrics };
476
+ }
477
+ /**
478
+ * Get all server metrics
479
+ */
480
+ getAllServerMetrics() {
481
+ return Array.from(this.serverMetrics.values()).map((metrics) => ({
482
+ ...metrics,
483
+ uptime: Date.now() - metrics.startTime,
484
+ }));
485
+ }
486
+ /**
487
+ * Restore metrics from persisted data
488
+ * Used during daemon startup to restore metrics from disk
489
+ */
490
+ restoreMetrics(data) {
491
+ // Restore custom metrics
492
+ for (const metric of data.metrics) {
493
+ this.metrics.set(metric.name, {
494
+ ...metric,
495
+ history: metric.history.slice(-1000), // Keep last 1000 points
496
+ });
497
+ }
498
+ // Restore server metrics
499
+ for (const serverMetric of data.serverMetrics) {
500
+ this.serverMetrics.set(serverMetric.serverName, {
501
+ ...serverMetric,
502
+ // Preserve restarts count and errors, reset runtime values
503
+ startTime: Date.now(), // Reset start time to now
504
+ uptime: 0, // Will be recalculated
505
+ });
506
+ }
507
+ // Restore tool metrics (optional for backward compatibility)
508
+ if (data.toolMetrics && Array.isArray(data.toolMetrics)) {
509
+ for (const toolMetric of data.toolMetrics) {
510
+ const key = `${toolMetric.serverName}-${toolMetric.toolName}`;
511
+ this.toolMetrics.set(key, {
512
+ ...toolMetric,
513
+ latencyHistory: toolMetric.latencyHistory.slice(-1000), // Keep last 1000 points
514
+ });
515
+ }
516
+ }
517
+ // Restore API metrics
518
+ this.apiMetrics = {
519
+ ...data.apiMetrics,
520
+ lastRequest: Date.now(), // Update to current time
521
+ };
522
+ const toolCount = data.toolMetrics ? data.toolMetrics.length : 0;
523
+ console.log(`[MetricsCollector] Restored metrics: ${data.metrics.length} custom, ` +
524
+ `${data.serverMetrics.length} servers, ${toolCount} tools, API metrics loaded`);
525
+ }
526
+ /**
527
+ * Export metrics as Prometheus format
528
+ */
529
+ exportPrometheus() {
530
+ let output = '';
531
+ // Custom metrics
532
+ for (const metric of this.metrics.values()) {
533
+ output += `# TYPE ${metric.name} ${metric.type}\n`;
534
+ output += `# UNIT ${metric.name} ${metric.unit}\n`;
535
+ output += `${metric.name}{} ${metric.value}\n`;
536
+ }
537
+ // API metrics
538
+ output += `# TYPE api_requests counter\n`;
539
+ output += `api_requests{} ${this.apiMetrics.requests}\n`;
540
+ output += `api_responses{} ${this.apiMetrics.responses}\n`;
541
+ output += `api_errors{} ${this.apiMetrics.errors}\n`;
542
+ output += `api_response_time_ms{} ${this.apiMetrics.avgResponseTime.toFixed(2)}\n`;
543
+ // Server metrics
544
+ for (const metrics of this.serverMetrics.values()) {
545
+ output += `# TYPE server_uptime gauge\n`;
546
+ output += `server_uptime{server="${metrics.serverName}"} ${metrics.uptime}\n`;
547
+ output += `server_restarts{server="${metrics.serverName}"} ${metrics.restarts}\n`;
548
+ output += `server_errors{server="${metrics.serverName}"} ${metrics.errors}\n`;
549
+ }
550
+ // Tool metrics
551
+ const toolMetrics = this.getAllToolMetrics();
552
+ if (toolMetrics.length > 0) {
553
+ output += `# TYPE tool_calls counter\n`;
554
+ output += `# TYPE tool_success_rate gauge\n`;
555
+ output += `# TYPE tool_latency_ms gauge\n`;
556
+ for (const tool of toolMetrics) {
557
+ const labels = `{server="${tool.serverName}",tool="${tool.toolName}"}`;
558
+ output += `tool_calls${labels} ${tool.calls}\n`;
559
+ output += `tool_success_rate${labels} ${tool.successRate.toFixed(2)}\n`;
560
+ output += `tool_latency_ms${labels} ${tool.latency.avg.toFixed(2)}\n`;
561
+ output += `tool_latency_p50_ms${labels} ${tool.latency.p50.toFixed(2)}\n`;
562
+ output += `tool_latency_p95_ms${labels} ${tool.latency.p95.toFixed(2)}\n`;
563
+ output += `tool_latency_p99_ms${labels} ${tool.latency.p99.toFixed(2)}\n`;
564
+ }
565
+ }
566
+ // Error analytics by type
567
+ const errorAnalytics = this.getErrorAnalytics();
568
+ if (errorAnalytics.totalErrors > 0) {
569
+ output += `# TYPE error_total counter\n`;
570
+ output += `error_total{} ${errorAnalytics.totalErrors}\n`;
571
+ output += `# TYPE error_rate gauge\n`;
572
+ output += `error_rate{} ${errorAnalytics.errorRate.toFixed(2)}\n`;
573
+ // Errors by type
574
+ output += `# TYPE errors_by_type counter\n`;
575
+ for (const [errorType, count] of Object.entries(errorAnalytics.errorsByType)) {
576
+ if (count > 0) {
577
+ output += `errors_by_type{type="${errorType}"} ${count}\n`;
578
+ }
579
+ }
580
+ // Errors by server
581
+ if (Object.keys(errorAnalytics.errorsByServer).length > 0) {
582
+ output += `# TYPE errors_by_server counter\n`;
583
+ for (const [serverName, count] of Object.entries(errorAnalytics.errorsByServer)) {
584
+ output += `errors_by_server{server="${serverName}"} ${count}\n`;
585
+ }
586
+ }
587
+ }
588
+ return output;
589
+ }
590
+ }
591
+ // Global metrics instance
592
+ export const globalMetrics = new MetricsCollector();
593
+ /**
594
+ * MetricsPersistence - Disk persistence for metrics data
595
+ *
596
+ * Saves metrics to disk periodically to enable:
597
+ * - Metrics retention across daemon restarts
598
+ * - Historical analysis
599
+ * - Long-term trending
600
+ */
601
+ export class MetricsPersistence {
602
+ constructor(baseDir) {
603
+ this.intervalHandle = null;
604
+ // Expand ~ to home directory if needed
605
+ this.persistenceDir = baseDir.replace(/^~/, process.env.HOME || '~');
606
+ }
607
+ /**
608
+ * Get the path to the metrics file
609
+ */
610
+ getMetricsPath() {
611
+ // Create directory if it doesn't exist
612
+ if (!fs.existsSync(this.persistenceDir)) {
613
+ fs.mkdirSync(this.persistenceDir, { recursive: true });
614
+ }
615
+ return path.join(this.persistenceDir, 'metrics.json');
616
+ }
617
+ /**
618
+ * Load metrics from disk
619
+ */
620
+ async load() {
621
+ try {
622
+ const content = await fsPromises.readFile(this.getMetricsPath(), 'utf8');
623
+ const data = JSON.parse(content);
624
+ console.log(`[MetricsPersistence] Loaded metrics from ${this.getMetricsPath()}`);
625
+ return data;
626
+ }
627
+ catch (error) {
628
+ const errCode = error.code;
629
+ if (errCode === 'ENOENT') {
630
+ // File doesn't exist yet - this is normal on first run
631
+ return null;
632
+ }
633
+ throw error;
634
+ }
635
+ }
636
+ /**
637
+ * Save metrics to disk
638
+ */
639
+ async save(data) {
640
+ try {
641
+ const content = JSON.stringify(data, null, 2);
642
+ await fsPromises.writeFile(this.getMetricsPath(), content, 'utf8');
643
+ console.log(`[MetricsPersistence] Saved metrics to ${this.getMetricsPath()} ` +
644
+ `(${data.metrics.length} metrics, ${data.serverMetrics.length} servers)`);
645
+ }
646
+ catch (error) {
647
+ console.error('[MetricsPersistence] Failed to save metrics:', error);
648
+ throw error;
649
+ }
650
+ }
651
+ /**
652
+ * Start periodic writes
653
+ * @param getData - Function to get current metrics data
654
+ * @param intervalMs - Write interval in milliseconds
655
+ */
656
+ startPeriodicWrites(getData, intervalMs) {
657
+ if (this.intervalHandle) {
658
+ clearInterval(this.intervalHandle);
659
+ }
660
+ this.intervalHandle = setInterval(async () => {
661
+ try {
662
+ const data = getData();
663
+ await this.save(data);
664
+ }
665
+ catch (error) {
666
+ console.error('[MetricsPersistence] Periodic write failed:', error);
667
+ }
668
+ }, intervalMs);
669
+ }
670
+ /**
671
+ * Stop periodic writes
672
+ */
673
+ stopPeriodicWrites() {
674
+ if (this.intervalHandle) {
675
+ clearInterval(this.intervalHandle);
676
+ this.intervalHandle = null;
677
+ }
678
+ }
679
+ }
680
+ /**
681
+ * MetricsAggregator - Time-series aggregation for metrics
682
+ *
683
+ * Provides aggregation functions for:
684
+ * - Hourly rollups
685
+ * - Daily rollups
686
+ * - Weekly rollups
687
+ * - Custom time windows
688
+ */
689
+ export class MetricsAggregator {
690
+ /**
691
+ * Aggregate metrics by hour
692
+ * @param metrics - Array of metrics to aggregate
693
+ * @param hours - Number of hours to aggregate (default: 24)
694
+ */
695
+ aggregateHourly(metrics, hours = 24) {
696
+ const now = Date.now();
697
+ const hourMs = 60 * 60 * 1000;
698
+ const result = {};
699
+ for (const metric of metrics) {
700
+ const hourlyValues = new Array(hours).fill(0);
701
+ // Process history points
702
+ for (const point of metric.history) {
703
+ const hoursAgo = Math.floor((now - point.timestamp) / hourMs);
704
+ if (hoursAgo >= 0 && hoursAgo < hours) {
705
+ const index = hours - 1 - hoursAgo; // Reverse so newest is last
706
+ if (metric.type === 'counter') {
707
+ hourlyValues[index] = Math.max(hourlyValues[index], point.value);
708
+ }
709
+ else if (metric.type === 'gauge') {
710
+ hourlyValues[index] = point.value; // Latest value wins
711
+ }
712
+ }
713
+ }
714
+ result[metric.name] = hourlyValues;
715
+ }
716
+ return result;
717
+ }
718
+ /**
719
+ * Aggregate metrics by day
720
+ * @param metrics - Array of metrics to aggregate
721
+ * @param days - Number of days to aggregate (default: 7)
722
+ */
723
+ aggregateDaily(metrics, days = 7) {
724
+ const now = Date.now();
725
+ const dayMs = 24 * 60 * 60 * 1000;
726
+ const result = {};
727
+ for (const metric of metrics) {
728
+ const dailyValues = new Array(days).fill(0);
729
+ // Process history points
730
+ for (const point of metric.history) {
731
+ const daysAgo = Math.floor((now - point.timestamp) / dayMs);
732
+ if (daysAgo >= 0 && daysAgo < days) {
733
+ const index = days - 1 - daysAgo; // Reverse so newest is last
734
+ if (metric.type === 'counter') {
735
+ dailyValues[index] = Math.max(dailyValues[index], point.value);
736
+ }
737
+ else if (metric.type === 'gauge') {
738
+ dailyValues[index] = point.value; // Latest value wins
739
+ }
740
+ }
741
+ }
742
+ result[metric.name] = dailyValues;
743
+ }
744
+ return result;
745
+ }
746
+ /**
747
+ * Aggregate metrics by week
748
+ * @param metrics - Array of metrics to aggregate
749
+ * @param weeks - Number of weeks to aggregate (default: 4)
750
+ */
751
+ aggregateWeekly(metrics, weeks = 4) {
752
+ const now = Date.now();
753
+ const weekMs = 7 * 24 * 60 * 60 * 1000;
754
+ const result = {};
755
+ for (const metric of metrics) {
756
+ const weeklyValues = new Array(weeks).fill(0);
757
+ // Process history points
758
+ for (const point of metric.history) {
759
+ const weeksAgo = Math.floor((now - point.timestamp) / weekMs);
760
+ if (weeksAgo >= 0 && weeksAgo < weeks) {
761
+ const index = weeks - 1 - weeksAgo; // Reverse so newest is last
762
+ if (metric.type === 'counter') {
763
+ weeklyValues[index] = Math.max(weeklyValues[index], point.value);
764
+ }
765
+ else if (metric.type === 'gauge') {
766
+ weeklyValues[index] = point.value; // Latest value wins
767
+ }
768
+ }
769
+ }
770
+ result[metric.name] = weeklyValues;
771
+ }
772
+ return result;
773
+ }
774
+ /**
775
+ * Calculate statistics for a metric over a time window
776
+ */
777
+ calculateStats(metric, windowMs) {
778
+ const now = Date.now();
779
+ const cutoff = now - windowMs;
780
+ const relevantPoints = metric.history.filter((p) => p.timestamp >= cutoff);
781
+ if (relevantPoints.length === 0) {
782
+ return { min: 0, max: 0, avg: 0, count: 0 };
783
+ }
784
+ const values = relevantPoints.map((p) => p.value);
785
+ const min = Math.min(...values);
786
+ const max = Math.max(...values);
787
+ const sum = values.reduce((a, b) => a + b, 0);
788
+ const avg = sum / values.length;
789
+ return { min, max, avg, count: relevantPoints.length };
790
+ }
791
+ }
792
+ //# sourceMappingURL=index.js.map