@jagilber-org/index-server 1.19.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 (360) hide show
  1. package/CHANGELOG.md +1218 -0
  2. package/CODE_OF_CONDUCT.md +49 -0
  3. package/CONTRIBUTING.md +75 -0
  4. package/LICENSE +21 -0
  5. package/README.md +523 -0
  6. package/SECURITY.md +50 -0
  7. package/dist/config/configUtils.d.ts +11 -0
  8. package/dist/config/configUtils.js +87 -0
  9. package/dist/config/dashboardConfig.d.ts +45 -0
  10. package/dist/config/dashboardConfig.js +63 -0
  11. package/dist/config/defaultValues.d.ts +61 -0
  12. package/dist/config/defaultValues.js +70 -0
  13. package/dist/config/dirConstants.d.ts +17 -0
  14. package/dist/config/dirConstants.js +28 -0
  15. package/dist/config/featureConfig.d.ts +61 -0
  16. package/dist/config/featureConfig.js +121 -0
  17. package/dist/config/runtimeConfig.d.ts +145 -0
  18. package/dist/config/runtimeConfig.js +334 -0
  19. package/dist/config/serverConfig.d.ts +90 -0
  20. package/dist/config/serverConfig.js +164 -0
  21. package/dist/dashboard/analytics/AnalyticsEngine.d.ts +142 -0
  22. package/dist/dashboard/analytics/AnalyticsEngine.js +373 -0
  23. package/dist/dashboard/analytics/BusinessIntelligence.d.ts +187 -0
  24. package/dist/dashboard/analytics/BusinessIntelligence.js +594 -0
  25. package/dist/dashboard/client/admin.html +2150 -0
  26. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/chunk-SP2CHFBE.mjs +1 -0
  27. package/dist/dashboard/client/chunks/mermaid-layout-elk.esm.min/render-T6MDALS3.mjs +27 -0
  28. package/dist/dashboard/client/css/admin.css +1466 -0
  29. package/dist/dashboard/client/js/admin.boot.js +359 -0
  30. package/dist/dashboard/client/js/admin.config.js +196 -0
  31. package/dist/dashboard/client/js/admin.embeddings.js +425 -0
  32. package/dist/dashboard/client/js/admin.graph.js +583 -0
  33. package/dist/dashboard/client/js/admin.instances.js +120 -0
  34. package/dist/dashboard/client/js/admin.instructions.js +552 -0
  35. package/dist/dashboard/client/js/admin.logs.js +113 -0
  36. package/dist/dashboard/client/js/admin.maintenance.js +354 -0
  37. package/dist/dashboard/client/js/admin.messaging.js +635 -0
  38. package/dist/dashboard/client/js/admin.monitor.js +181 -0
  39. package/dist/dashboard/client/js/admin.overview.js +221 -0
  40. package/dist/dashboard/client/js/admin.performance.js +61 -0
  41. package/dist/dashboard/client/js/admin.sessions.js +293 -0
  42. package/dist/dashboard/client/js/admin.sqlite.js +366 -0
  43. package/dist/dashboard/client/js/admin.utils.js +49 -0
  44. package/dist/dashboard/client/js/chart.umd.js +14 -0
  45. package/dist/dashboard/client/js/elk.bundled.js +6696 -0
  46. package/dist/dashboard/client/js/marked.umd.js +74 -0
  47. package/dist/dashboard/client/js/mermaid.min.js +3022 -0
  48. package/dist/dashboard/client/mermaid-layout-elk.esm.min.mjs +1 -0
  49. package/dist/dashboard/export/DataExporter.d.ts +169 -0
  50. package/dist/dashboard/export/DataExporter.js +737 -0
  51. package/dist/dashboard/export/exporters/csvExporter.d.ts +11 -0
  52. package/dist/dashboard/export/exporters/csvExporter.js +46 -0
  53. package/dist/dashboard/export/exporters/exportTypes.d.ts +89 -0
  54. package/dist/dashboard/export/exporters/exportTypes.js +5 -0
  55. package/dist/dashboard/export/exporters/jsonExporter.d.ts +7 -0
  56. package/dist/dashboard/export/exporters/jsonExporter.js +22 -0
  57. package/dist/dashboard/export/exporters/xmlExporter.d.ts +17 -0
  58. package/dist/dashboard/export/exporters/xmlExporter.js +175 -0
  59. package/dist/dashboard/integration/APIIntegration.d.ts +41 -0
  60. package/dist/dashboard/integration/APIIntegration.js +95 -0
  61. package/dist/dashboard/security/SecurityMonitor.d.ts +167 -0
  62. package/dist/dashboard/security/SecurityMonitor.js +559 -0
  63. package/dist/dashboard/server/AdminPanel.d.ts +183 -0
  64. package/dist/dashboard/server/AdminPanel.js +792 -0
  65. package/dist/dashboard/server/AdminPanelConfig.d.ts +42 -0
  66. package/dist/dashboard/server/AdminPanelConfig.js +80 -0
  67. package/dist/dashboard/server/AdminPanelState.d.ts +47 -0
  68. package/dist/dashboard/server/AdminPanelState.js +214 -0
  69. package/dist/dashboard/server/ApiRoutes.d.ts +17 -0
  70. package/dist/dashboard/server/ApiRoutes.js +149 -0
  71. package/dist/dashboard/server/DashboardServer.d.ts +49 -0
  72. package/dist/dashboard/server/DashboardServer.js +159 -0
  73. package/dist/dashboard/server/FileMetricsStorage.d.ts +49 -0
  74. package/dist/dashboard/server/FileMetricsStorage.js +195 -0
  75. package/dist/dashboard/server/HttpTransport.d.ts +23 -0
  76. package/dist/dashboard/server/HttpTransport.js +116 -0
  77. package/dist/dashboard/server/InstanceManager.d.ts +53 -0
  78. package/dist/dashboard/server/InstanceManager.js +284 -0
  79. package/dist/dashboard/server/KnowledgeStore.d.ts +35 -0
  80. package/dist/dashboard/server/KnowledgeStore.js +105 -0
  81. package/dist/dashboard/server/LeaderElection.d.ts +81 -0
  82. package/dist/dashboard/server/LeaderElection.js +268 -0
  83. package/dist/dashboard/server/MetricsCollector.d.ts +200 -0
  84. package/dist/dashboard/server/MetricsCollector.js +803 -0
  85. package/dist/dashboard/server/SessionPersistenceManager.d.ts +88 -0
  86. package/dist/dashboard/server/SessionPersistenceManager.js +457 -0
  87. package/dist/dashboard/server/ThinClient.d.ts +64 -0
  88. package/dist/dashboard/server/ThinClient.js +237 -0
  89. package/dist/dashboard/server/WebSocketManager.d.ts +161 -0
  90. package/dist/dashboard/server/WebSocketManager.js +463 -0
  91. package/dist/dashboard/server/httpLifecycle.d.ts +17 -0
  92. package/dist/dashboard/server/httpLifecycle.js +35 -0
  93. package/dist/dashboard/server/legacyDashboardHtml.d.ts +9 -0
  94. package/dist/dashboard/server/legacyDashboardHtml.js +618 -0
  95. package/dist/dashboard/server/legacyDashboardStyles.d.ts +5 -0
  96. package/dist/dashboard/server/legacyDashboardStyles.js +490 -0
  97. package/dist/dashboard/server/metricsAggregation.d.ts +252 -0
  98. package/dist/dashboard/server/metricsAggregation.js +206 -0
  99. package/dist/dashboard/server/metricsSerializer.d.ts +25 -0
  100. package/dist/dashboard/server/metricsSerializer.js +195 -0
  101. package/dist/dashboard/server/routes/admin.routes.d.ts +16 -0
  102. package/dist/dashboard/server/routes/admin.routes.js +596 -0
  103. package/dist/dashboard/server/routes/alerts.routes.d.ts +7 -0
  104. package/dist/dashboard/server/routes/alerts.routes.js +93 -0
  105. package/dist/dashboard/server/routes/api.feedback.routes.d.ts +73 -0
  106. package/dist/dashboard/server/routes/api.feedback.routes.js +171 -0
  107. package/dist/dashboard/server/routes/api.instructions.routes.d.ts +101 -0
  108. package/dist/dashboard/server/routes/api.instructions.routes.js +213 -0
  109. package/dist/dashboard/server/routes/api.usage.routes.d.ts +57 -0
  110. package/dist/dashboard/server/routes/api.usage.routes.js +374 -0
  111. package/dist/dashboard/server/routes/embeddings.routes.d.ts +6 -0
  112. package/dist/dashboard/server/routes/embeddings.routes.js +246 -0
  113. package/dist/dashboard/server/routes/graph.routes.d.ts +6 -0
  114. package/dist/dashboard/server/routes/graph.routes.js +280 -0
  115. package/dist/dashboard/server/routes/index.d.ts +38 -0
  116. package/dist/dashboard/server/routes/index.js +194 -0
  117. package/dist/dashboard/server/routes/instances.routes.d.ts +6 -0
  118. package/dist/dashboard/server/routes/instances.routes.js +35 -0
  119. package/dist/dashboard/server/routes/instructions.routes.d.ts +8 -0
  120. package/dist/dashboard/server/routes/instructions.routes.js +336 -0
  121. package/dist/dashboard/server/routes/knowledge.routes.d.ts +6 -0
  122. package/dist/dashboard/server/routes/knowledge.routes.js +82 -0
  123. package/dist/dashboard/server/routes/logs.routes.d.ts +6 -0
  124. package/dist/dashboard/server/routes/logs.routes.js +164 -0
  125. package/dist/dashboard/server/routes/messaging.routes.d.ts +16 -0
  126. package/dist/dashboard/server/routes/messaging.routes.js +293 -0
  127. package/dist/dashboard/server/routes/metrics.routes.d.ts +10 -0
  128. package/dist/dashboard/server/routes/metrics.routes.js +346 -0
  129. package/dist/dashboard/server/routes/scripts.routes.d.ts +9 -0
  130. package/dist/dashboard/server/routes/scripts.routes.js +84 -0
  131. package/dist/dashboard/server/routes/sqlite.routes.d.ts +9 -0
  132. package/dist/dashboard/server/routes/sqlite.routes.js +569 -0
  133. package/dist/dashboard/server/routes/status.routes.d.ts +7 -0
  134. package/dist/dashboard/server/routes/status.routes.js +183 -0
  135. package/dist/dashboard/server/routes/synthetic.routes.d.ts +7 -0
  136. package/dist/dashboard/server/routes/synthetic.routes.js +195 -0
  137. package/dist/dashboard/server/routes/tools.routes.d.ts +6 -0
  138. package/dist/dashboard/server/routes/tools.routes.js +46 -0
  139. package/dist/dashboard/server/routes/usage.routes.d.ts +6 -0
  140. package/dist/dashboard/server/routes/usage.routes.js +25 -0
  141. package/dist/dashboard/server/wsInit.d.ts +16 -0
  142. package/dist/dashboard/server/wsInit.js +35 -0
  143. package/dist/externalClientLib.d.ts +1 -0
  144. package/dist/externalClientLib.js +2 -0
  145. package/dist/minimal/index.d.ts +1 -0
  146. package/dist/minimal/index.js +140 -0
  147. package/dist/models/SessionPersistence.d.ts +115 -0
  148. package/dist/models/SessionPersistence.js +66 -0
  149. package/dist/models/instruction.d.ts +45 -0
  150. package/dist/models/instruction.js +2 -0
  151. package/dist/perf/benchmark.d.ts +1 -0
  152. package/dist/perf/benchmark.js +50 -0
  153. package/dist/portableClientWrapper.d.ts +1 -0
  154. package/dist/portableClientWrapper.js +2 -0
  155. package/dist/schemas/index.d.ts +128 -0
  156. package/dist/schemas/index.js +371 -0
  157. package/dist/scripts/runPerformanceBaseline.d.ts +1 -0
  158. package/dist/scripts/runPerformanceBaseline.js +17 -0
  159. package/dist/server/handshakeManager.d.ts +25 -0
  160. package/dist/server/handshakeManager.js +472 -0
  161. package/dist/server/index-server.d.ts +56 -0
  162. package/dist/server/index-server.js +822 -0
  163. package/dist/server/registry.d.ts +44 -0
  164. package/dist/server/registry.js +236 -0
  165. package/dist/server/sdkServer.d.ts +8 -0
  166. package/dist/server/sdkServer.js +299 -0
  167. package/dist/server/shutdownGuard.d.ts +41 -0
  168. package/dist/server/shutdownGuard.js +52 -0
  169. package/dist/server/thin-client.d.ts +22 -0
  170. package/dist/server/thin-client.js +111 -0
  171. package/dist/server/transport.d.ts +41 -0
  172. package/dist/server/transport.js +312 -0
  173. package/dist/server/transportFactory.d.ts +21 -0
  174. package/dist/server/transportFactory.js +429 -0
  175. package/dist/services/atomicFs.d.ts +22 -0
  176. package/dist/services/atomicFs.js +103 -0
  177. package/dist/services/auditLog.d.ts +38 -0
  178. package/dist/services/auditLog.js +142 -0
  179. package/dist/services/autoBackup.d.ts +14 -0
  180. package/dist/services/autoBackup.js +171 -0
  181. package/dist/services/autoSplit.d.ts +32 -0
  182. package/dist/services/autoSplit.js +113 -0
  183. package/dist/services/backupZip.d.ts +25 -0
  184. package/dist/services/backupZip.js +110 -0
  185. package/dist/services/bootstrapGating.d.ts +123 -0
  186. package/dist/services/bootstrapGating.js +221 -0
  187. package/dist/services/canonical.d.ts +23 -0
  188. package/dist/services/canonical.js +65 -0
  189. package/dist/services/categoryRules.d.ts +7 -0
  190. package/dist/services/categoryRules.js +37 -0
  191. package/dist/services/classificationService.d.ts +42 -0
  192. package/dist/services/classificationService.js +168 -0
  193. package/dist/services/embeddingService.d.ts +62 -0
  194. package/dist/services/embeddingService.js +259 -0
  195. package/dist/services/errors.d.ts +22 -0
  196. package/dist/services/errors.js +31 -0
  197. package/dist/services/featureFlags.d.ts +25 -0
  198. package/dist/services/featureFlags.js +89 -0
  199. package/dist/services/features.d.ts +13 -0
  200. package/dist/services/features.js +35 -0
  201. package/dist/services/handlers/instructions.add.d.ts +1 -0
  202. package/dist/services/handlers/instructions.add.js +496 -0
  203. package/dist/services/handlers/instructions.groom.d.ts +1 -0
  204. package/dist/services/handlers/instructions.groom.js +523 -0
  205. package/dist/services/handlers/instructions.import.d.ts +1 -0
  206. package/dist/services/handlers/instructions.import.js +173 -0
  207. package/dist/services/handlers/instructions.patch.d.ts +1 -0
  208. package/dist/services/handlers/instructions.patch.js +167 -0
  209. package/dist/services/handlers/instructions.query.d.ts +163 -0
  210. package/dist/services/handlers/instructions.query.js +522 -0
  211. package/dist/services/handlers/instructions.reload.d.ts +1 -0
  212. package/dist/services/handlers/instructions.reload.js +13 -0
  213. package/dist/services/handlers/instructions.remove.d.ts +1 -0
  214. package/dist/services/handlers/instructions.remove.js +118 -0
  215. package/dist/services/handlers/instructions.shared.d.ts +31 -0
  216. package/dist/services/handlers/instructions.shared.js +124 -0
  217. package/dist/services/handlers.activation.d.ts +1 -0
  218. package/dist/services/handlers.activation.js +203 -0
  219. package/dist/services/handlers.bootstrap.d.ts +1 -0
  220. package/dist/services/handlers.bootstrap.js +38 -0
  221. package/dist/services/handlers.dashboardConfig.d.ts +34 -0
  222. package/dist/services/handlers.dashboardConfig.js +108 -0
  223. package/dist/services/handlers.diagnostics.d.ts +1 -0
  224. package/dist/services/handlers.diagnostics.js +64 -0
  225. package/dist/services/handlers.feedback.d.ts +15 -0
  226. package/dist/services/handlers.feedback.js +378 -0
  227. package/dist/services/handlers.gates.d.ts +1 -0
  228. package/dist/services/handlers.gates.js +46 -0
  229. package/dist/services/handlers.graph.d.ts +53 -0
  230. package/dist/services/handlers.graph.js +231 -0
  231. package/dist/services/handlers.help.d.ts +1 -0
  232. package/dist/services/handlers.help.js +119 -0
  233. package/dist/services/handlers.instructionSchema.d.ts +1 -0
  234. package/dist/services/handlers.instructionSchema.js +227 -0
  235. package/dist/services/handlers.instructions.d.ts +8 -0
  236. package/dist/services/handlers.instructions.js +14 -0
  237. package/dist/services/handlers.instructionsDiagnostics.d.ts +1 -0
  238. package/dist/services/handlers.instructionsDiagnostics.js +14 -0
  239. package/dist/services/handlers.integrity.d.ts +1 -0
  240. package/dist/services/handlers.integrity.js +35 -0
  241. package/dist/services/handlers.manifest.d.ts +1 -0
  242. package/dist/services/handlers.manifest.js +24 -0
  243. package/dist/services/handlers.messaging.d.ts +12 -0
  244. package/dist/services/handlers.messaging.js +203 -0
  245. package/dist/services/handlers.metrics.d.ts +1 -0
  246. package/dist/services/handlers.metrics.js +43 -0
  247. package/dist/services/handlers.promote.d.ts +1 -0
  248. package/dist/services/handlers.promote.js +306 -0
  249. package/dist/services/handlers.prompt.d.ts +1 -0
  250. package/dist/services/handlers.prompt.js +7 -0
  251. package/dist/services/handlers.search.d.ts +69 -0
  252. package/dist/services/handlers.search.js +645 -0
  253. package/dist/services/handlers.testPrimitive.d.ts +1 -0
  254. package/dist/services/handlers.testPrimitive.js +5 -0
  255. package/dist/services/handlers.trace.d.ts +1 -0
  256. package/dist/services/handlers.trace.js +31 -0
  257. package/dist/services/handlers.usage.d.ts +1 -0
  258. package/dist/services/handlers.usage.js +11 -0
  259. package/dist/services/hotScore.d.ts +137 -0
  260. package/dist/services/hotScore.js +244 -0
  261. package/dist/services/indexContext.d.ts +117 -0
  262. package/dist/services/indexContext.js +968 -0
  263. package/dist/services/indexLoader.d.ts +44 -0
  264. package/dist/services/indexLoader.js +921 -0
  265. package/dist/services/indexRepository.d.ts +32 -0
  266. package/dist/services/indexRepository.js +71 -0
  267. package/dist/services/indexingService.d.ts +1 -0
  268. package/dist/services/indexingService.js +2 -0
  269. package/dist/services/instructions.dispatcher.d.ts +1 -0
  270. package/dist/services/instructions.dispatcher.js +231 -0
  271. package/dist/services/logPrefix.d.ts +1 -0
  272. package/dist/services/logPrefix.js +30 -0
  273. package/dist/services/logger.d.ts +52 -0
  274. package/dist/services/logger.js +268 -0
  275. package/dist/services/manifestManager.d.ts +82 -0
  276. package/dist/services/manifestManager.js +200 -0
  277. package/dist/services/messaging/agentMailbox.d.ts +60 -0
  278. package/dist/services/messaging/agentMailbox.js +353 -0
  279. package/dist/services/messaging/messagingPersistence.d.ts +20 -0
  280. package/dist/services/messaging/messagingPersistence.js +111 -0
  281. package/dist/services/messaging/messagingTypes.d.ts +150 -0
  282. package/dist/services/messaging/messagingTypes.js +66 -0
  283. package/dist/services/ownershipService.d.ts +1 -0
  284. package/dist/services/ownershipService.js +38 -0
  285. package/dist/services/performanceBaseline.d.ts +19 -0
  286. package/dist/services/performanceBaseline.js +210 -0
  287. package/dist/services/preflight.d.ts +12 -0
  288. package/dist/services/preflight.js +79 -0
  289. package/dist/services/promptReviewService.d.ts +44 -0
  290. package/dist/services/promptReviewService.js +101 -0
  291. package/dist/services/responseEnvelope.d.ts +6 -0
  292. package/dist/services/responseEnvelope.js +25 -0
  293. package/dist/services/seedBootstrap.d.ts +34 -0
  294. package/dist/services/seedBootstrap.js +427 -0
  295. package/dist/services/storage/factory.d.ts +17 -0
  296. package/dist/services/storage/factory.js +35 -0
  297. package/dist/services/storage/hashUtils.d.ts +11 -0
  298. package/dist/services/storage/hashUtils.js +35 -0
  299. package/dist/services/storage/index.d.ts +12 -0
  300. package/dist/services/storage/index.js +18 -0
  301. package/dist/services/storage/jsonFileStore.d.ts +32 -0
  302. package/dist/services/storage/jsonFileStore.js +241 -0
  303. package/dist/services/storage/migrationEngine.d.ts +35 -0
  304. package/dist/services/storage/migrationEngine.js +93 -0
  305. package/dist/services/storage/sqliteMessageStore.d.ts +53 -0
  306. package/dist/services/storage/sqliteMessageStore.js +146 -0
  307. package/dist/services/storage/sqliteSchema.d.ts +12 -0
  308. package/dist/services/storage/sqliteSchema.js +122 -0
  309. package/dist/services/storage/sqliteStore.d.ts +41 -0
  310. package/dist/services/storage/sqliteStore.js +339 -0
  311. package/dist/services/storage/sqliteUsageStore.d.ts +35 -0
  312. package/dist/services/storage/sqliteUsageStore.js +94 -0
  313. package/dist/services/storage/types.d.ts +171 -0
  314. package/dist/services/storage/types.js +12 -0
  315. package/dist/services/toolHandlers.d.ts +23 -0
  316. package/dist/services/toolHandlers.js +50 -0
  317. package/dist/services/toolRegistry.d.ts +20 -0
  318. package/dist/services/toolRegistry.js +490 -0
  319. package/dist/services/toolRegistry.zod.d.ts +10 -0
  320. package/dist/services/toolRegistry.zod.js +323 -0
  321. package/dist/services/tracing.d.ts +26 -0
  322. package/dist/services/tracing.js +260 -0
  323. package/dist/services/usageBuckets.d.ts +161 -0
  324. package/dist/services/usageBuckets.js +364 -0
  325. package/dist/services/validationService.d.ts +38 -0
  326. package/dist/services/validationService.js +125 -0
  327. package/dist/utils/BufferRing.d.ts +203 -0
  328. package/dist/utils/BufferRing.js +551 -0
  329. package/dist/utils/BufferRingExamples.d.ts +55 -0
  330. package/dist/utils/BufferRingExamples.js +188 -0
  331. package/dist/utils/envUtils.d.ts +42 -0
  332. package/dist/utils/envUtils.js +80 -0
  333. package/dist/utils/memoryMonitor.d.ts +83 -0
  334. package/dist/utils/memoryMonitor.js +275 -0
  335. package/dist/versioning/schemaVersion.d.ts +6 -0
  336. package/dist/versioning/schemaVersion.js +93 -0
  337. package/package.json +134 -0
  338. package/schemas/README.md +13 -0
  339. package/schemas/feedback-entry.schema.json +27 -0
  340. package/schemas/graph-export-v2.schema.json +60 -0
  341. package/schemas/index-server.code-schema.json +38477 -0
  342. package/schemas/instruction.schema.json +262 -0
  343. package/schemas/json-schema/SessionPersistence-persisted-admin-session.schema.json +54 -0
  344. package/schemas/json-schema/SessionPersistence-persisted-session-history-entry.schema.json +51 -0
  345. package/schemas/json-schema/SessionPersistence-persisted-web-socket-connection.schema.json +54 -0
  346. package/schemas/json-schema/SessionPersistence-session-persistence-config.schema.json +110 -0
  347. package/schemas/json-schema/SessionPersistence-session-persistence-data.schema.json +229 -0
  348. package/schemas/json-schema/SessionPersistence-session-persistence-manifest.schema.json +109 -0
  349. package/schemas/json-schema/SessionPersistence-session-persistence-metadata.schema.json +55 -0
  350. package/schemas/json-schema/instruction-audience-scope.schema.json +14 -0
  351. package/schemas/json-schema/instruction-content-type.schema.json +17 -0
  352. package/schemas/json-schema/instruction-instruction-entry.schema.json +206 -0
  353. package/schemas/json-schema/instruction-requirement-level.schema.json +16 -0
  354. package/schemas/manifest.json +78 -0
  355. package/schemas/manifest.schema.json +33 -0
  356. package/schemas/usage-batch.schema.json +16 -0
  357. package/schemas/usage-buckets.schema.json +30 -0
  358. package/schemas/usage-event.schema.json +17 -0
  359. package/scripts/copy-dashboard-assets.mjs +170 -0
  360. package/scripts/setup-hooks.cjs +28 -0
@@ -0,0 +1,181 @@
1
+ /* eslint-disable */
2
+ // Lightweight monitoring module extracted from admin.html
3
+ (function(){
4
+ // Toggle synthetic traces wrapper visibility
5
+ function toggleSyntheticTraceVisibility(){
6
+ const wrap = document.getElementById('synthetic-traces-wrapper');
7
+ const chk = document.getElementById('synthetic-trace-toggle');
8
+ if(!wrap||!chk) return;
9
+ wrap.style.display = chk.checked ? 'block':'none';
10
+ }
11
+
12
+ // Run synthetic activity (keeps a faster monitoring poll while running)
13
+ async function runSyntheticActivity() {
14
+ const iter = parseInt(document.getElementById('synthetic-iterations').value, 10) || 10;
15
+ const conc = parseInt(document.getElementById('synthetic-concurrency').value, 10) || 2;
16
+ const wantTrace = document.getElementById('synthetic-trace-toggle')?.checked !== false; // default true
17
+ const btn = document.getElementById('synthetic-run-btn');
18
+ const output = document.getElementById('synthetic-output');
19
+ if(btn) { btn.disabled = true; btn.textContent = 'Running…'; }
20
+ if(output) output.textContent = 'Executing synthetic activity...';
21
+ const tracesBody = document.getElementById('synthetic-traces-body');
22
+ if(tracesBody) tracesBody.innerHTML = '';
23
+ // Accelerate monitoring poll during run
24
+ let previousInterval = window.monitoringInterval;
25
+ if (window.monitoringInterval) { clearInterval(window.monitoringInterval); window.monitoringInterval=null; }
26
+ window.monitoringInterval = setInterval(()=>{
27
+ if (document.getElementById('monitoring-section')?.classList.contains('hidden')) return;
28
+ loadMonitoringData();
29
+ updateActiveSyntheticRequests();
30
+ }, 1000); // fast poll while running
31
+ let statusTimer = setInterval(updateActiveSyntheticRequests, 1000);
32
+ try {
33
+ const url = '/api/admin/synthetic/activity?debug=1'+(wantTrace?'&trace=1&stream=1':'');
34
+ const res = await fetch(url, { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ iterations: iter, concurrency: conc }) });
35
+ const rawText = await res.text();
36
+ let data = null; try { data = JSON.parse(rawText); } catch { /* ignore */ }
37
+ if (!res.ok || !data) {
38
+ throw new Error(data && (data.error || data.message) ? (data.error || data.message) : `HTTP ${res.status} (non-JSON)`);
39
+ }
40
+ if (!data.success) {
41
+ throw new Error(data.error || data.message || 'Unknown failure');
42
+ }
43
+ const metaLine = `Executed ${data.executed}/${data.iterationsRequested} (errors:${data.errors}) in ${data.durationMs}ms @c=${data.concurrency} tools:${data.availableCount}`;
44
+ if(output) output.textContent = metaLine + (data.available ? `\nSample: ${data.available.slice(0,5).join(', ')}` : '');
45
+ const lastMeta = document.getElementById('synthetic-last-meta');
46
+ if (lastMeta) lastMeta.textContent = `Last run: ${new Date().toLocaleTimeString()} ${metaLine}`;
47
+ if (wantTrace && tracesBody) {
48
+ if (Array.isArray(data.traces) && data.traces.length) {
49
+ const rows = data.traces.map((t,i)=>{
50
+ const clr = t.success ? '#0a0' : '#a00';
51
+ const err = t.error ? String(t.error).slice(0,80) : '';
52
+ const skipped = t.skipped ? ' (skipped)' : '';
53
+ return `<tr>
54
+ <td style="padding:2px 4px; border-bottom:1px solid #eee;">${i+1}</td>
55
+ <td style="padding:2px 4px; border-bottom:1px solid #eee; font-family:monospace;">${t.method}${skipped}</td>
56
+ <td style="padding:2px 4px; border-bottom:1px solid #eee; color:${clr};">${t.success?'✓':'✗'}</td>
57
+ <td style="padding:2px 4px; border-bottom:1px solid #eee;">${t.durationMs}ms</td>
58
+ <td style="padding:2px 4px; border-bottom:1px solid #eee; color:${t.error?'#b55':'#666'};">${err}</td>
59
+ </tr>`;
60
+ }).join('');
61
+ tracesBody.innerHTML = rows;
62
+ } else {
63
+ const reason = data.traceReason || 'no traces captured';
64
+ tracesBody.innerHTML = `<tr><td colspan="5" style="padding:4px; font-style:italic;">${reason}</td></tr>`;
65
+ }
66
+ document.getElementById('synthetic-traces-wrapper').style.display = 'block';
67
+ }
68
+ // Refresh overview + monitoring for updated metrics
69
+ loadOverviewData();
70
+ loadMonitoringData();
71
+ } catch (err) {
72
+ const emsg = (err && err.message) || 'unknown error';
73
+ if(output) output.textContent = `Synthetic activity failed: ${emsg}`;
74
+ if (/No safe tools/i.test(emsg)) {
75
+ if(output) output.textContent += '\nHint: Ensure server started after tool handlers registered (import order)';
76
+ }
77
+ } finally {
78
+ if(btn) { btn.disabled = false; btn.textContent = 'Run Synthetic Activity'; }
79
+ // Restore slower poll cadence
80
+ if (window.monitoringInterval) { clearInterval(window.monitoringInterval); window.monitoringInterval=null; }
81
+ if (statusTimer) { clearInterval(statusTimer); statusTimer=null; }
82
+ if (!previousInterval) { // restart default if monitoring tab visible
83
+ ensureMonitoringPoll();
84
+ }
85
+ // One last status refresh to clear active counter
86
+ updateActiveSyntheticRequests();
87
+ }
88
+ }
89
+
90
+ // Fetch active synthetic request count and inject into monitoring panel if present
91
+ async function updateActiveSyntheticRequests(){
92
+ try {
93
+ const res = await fetch('/api/admin/synthetic/status');
94
+ const data = await res.json();
95
+ if (!data.success) return;
96
+ const active = data.activeRequests || 0;
97
+ // Find monitoring panel metric list and append/update a synthetic active row
98
+ const container = document.getElementById('monitoring-data');
99
+ if (container && container.innerHTML.includes('Throughput')) {
100
+ const id = 'active-synth-requests-row';
101
+ let el = document.getElementById(id);
102
+ if (!el) {
103
+ const div = document.createElement('div');
104
+ div.className='stat-row';
105
+ div.id = id;
106
+ div.innerHTML = '<span class="stat-label">Active Synthetic Requests</span><span class="stat-value">0</span>';
107
+ container.insertBefore(div, container.firstChild.nextSibling); // after first row
108
+ el = div;
109
+ }
110
+ const valSpan = el.querySelector('.stat-value');
111
+ if (valSpan) valSpan.textContent = String(active);
112
+ }
113
+ } catch { /* ignore */ }
114
+ }
115
+
116
+ // Monitoring data fetch
117
+ async function loadMonitoringData() {
118
+ try {
119
+ const [perfRes, sysRes, alertsRes] = await Promise.all([
120
+ fetch('/api/performance/detailed').catch(e=>e),
121
+ fetch('/api/system/health').catch(e=>e),
122
+ fetch('/api/alerts/active').catch(e=>e)
123
+ ]);
124
+ const [perfData, sysData, alertsData] = await Promise.all([
125
+ perfRes?.json ? perfRes.json().catch(()=>({})) : {},
126
+ sysRes?.json ? sysRes.json().catch(()=>({})) : {},
127
+ alertsRes?.json ? alertsRes.json().catch(()=>({})) : {}
128
+ ]);
129
+ const perf = perfData.data || {};
130
+ const sys = sysData.data || {};
131
+ const alerts = (alertsData.data || []).slice(0,5);
132
+ const html = `
133
+ <div class="metrics-list">
134
+ <div class="metrics-row"><span class="label">Throughput (rpm)</span><span class="value">${perf.requestThroughput ?? '—'}</span></div>
135
+ <div class="metrics-row"><span class="label">Avg Response</span><span class="value">${perf.averageResponseTime?.toFixed ? perf.averageResponseTime.toFixed(1)+'ms':'—'}</span></div>
136
+ <div class="metrics-row"><span class="label">P95</span><span class="value">${perf.p95ResponseTime ?? '—'}ms</span></div>
137
+ <div class="metrics-row"><span class="label">Error Rate</span><span class="value">${perf.errorRate?.toFixed ? perf.errorRate.toFixed(2)+'%':'—'}</span></div>
138
+ <div class="metrics-row"><span class="label">Active Connections</span><span class="value">${perf.concurrentConnections ?? '—'}</span></div>
139
+ <div class="metrics-row"><span class="label">System Health</span><span class="value">${sys.status || '—'}</span></div>
140
+ </div>
141
+ <div style="margin-top:12px; font-size:12px;">
142
+ <div class="metrics-section-title">Active Alerts (${alerts.length})</div>
143
+ <ul style="margin:4px 0 0 18px;">${alerts.map(a=>`<li>${a.type} (${a.severity}) - ${a.message}</li>`).join('') || '<li style="opacity:.7;">No active alerts</li>'}</ul>
144
+ </div>`;
145
+ const el = document.getElementById('monitoring-data');
146
+ if (el) el.innerHTML = html;
147
+ // Update nav badge if sessions already loaded
148
+ if (typeof updateSessionsNavBadge === 'function') updateSessionsNavBadge();
149
+ } catch (e) {
150
+ const el = document.getElementById('monitoring-data');
151
+ if (el) el.innerHTML = '<div class="error">Failed to load monitoring data</div>';
152
+ }
153
+ }
154
+
155
+ // Periodic refresh when Monitoring tab visible
156
+ window.monitoringInterval = window.monitoringInterval || null;
157
+ function ensureMonitoringPoll(){
158
+ if (document.getElementById('monitoring-section')?.classList.contains('hidden')) return;
159
+ if (window.monitoringInterval) return; // already
160
+ window.monitoringInterval = setInterval(()=>{
161
+ if (document.getElementById('monitoring-section')?.classList.contains('hidden')) { clearInterval(window.monitoringInterval); window.monitoringInterval=null; return; }
162
+ loadMonitoringData();
163
+ }, 5000);
164
+ }
165
+
166
+ // Expose functions to global scope for compatibility with admin.html
167
+ window.toggleSyntheticTraceVisibility = toggleSyntheticTraceVisibility;
168
+ window.runSyntheticActivity = runSyntheticActivity;
169
+ window.updateActiveSyntheticRequests = updateActiveSyntheticRequests;
170
+ window.loadMonitoringData = loadMonitoringData;
171
+ window.ensureMonitoringPoll = ensureMonitoringPoll;
172
+
173
+ // Wire synthetic run button if present (some refactors removed inline onclick)
174
+ document.addEventListener('DOMContentLoaded', function(){
175
+ const btn = document.getElementById('synthetic-run-btn');
176
+ if(btn && !btn.__wired){
177
+ btn.addEventListener('click', function(ev){ ev.preventDefault(); runSyntheticActivity(); });
178
+ Object.defineProperty(btn,'__wired',{value:true});
179
+ }
180
+ });
181
+ })();
@@ -0,0 +1,221 @@
1
+ /* eslint-disable */
2
+ // Extracted overview functions from admin.html
3
+ (function(){
4
+ // rely on global helpers: formatUptime, formatBytes, showError
5
+ window.statsAvailable = false;
6
+
7
+ async function loadOverviewData(){
8
+ try {
9
+ const [statsRes, maintenanceRes, healthRes] = await Promise.allSettled([
10
+ fetch('/api/admin/stats'),
11
+ fetch('/api/admin/maintenance'),
12
+ fetch('/api/system/health')
13
+ ]);
14
+ const statsData = statsRes.status==='fulfilled' ? await statsRes.value.json().catch(()=> ({})) : {};
15
+ const maintenanceData = maintenanceRes.status==='fulfilled' ? await maintenanceRes.value.json().catch(()=> ({})) : {};
16
+ const healthData = healthRes.status==='fulfilled' ? await healthRes.value.json().catch(()=> ({})) : {};
17
+ if(statsData?.success && statsData.stats){
18
+ window.statsAvailable = true; displaySystemStats(statsData.stats);
19
+ } else {
20
+ window.statsAvailable = false; const statsEl = document.getElementById('system-stats'); if(statsEl) statsEl.innerHTML = '<div class="error-message">Stats unavailable</div>';
21
+ }
22
+ if(maintenanceData?.success && maintenanceData.maintenance && typeof displayMaintenanceInfo==='function'){
23
+ try { displayMaintenanceInfo(maintenanceData.maintenance); } catch(e){ console.warn('displayMaintenanceInfo failed:', e); }
24
+ }
25
+ if(healthData && (healthData.success || ['ok','healthy','degraded'].includes(healthData.status))){
26
+ displaySystemHealth(healthData.systemHealth || healthData.maintenance?.systemHealth || healthData);
27
+ }
28
+ } catch(err){
29
+ console.error('Error loading overview data:', err);
30
+ showError('Failed to load overview data');
31
+ }
32
+ }
33
+
34
+ function displaySystemStats(stats) {
35
+ try { window.lastSystemStats = stats; } catch(e) { /* ignore */ }
36
+ const html = `
37
+ <div class="stat-row">
38
+ <span class="stat-label">Uptime</span>
39
+ <span class="stat-value">${formatUptime(stats.uptime)}</span>
40
+ </div>
41
+ <div class="stat-row">
42
+ <span class="stat-label">Active Connections (WS)</span>
43
+ <span class="stat-value">${stats.activeConnections}</span>
44
+ </div>
45
+ <div class="stat-row">
46
+ <span class="stat-label">Admin Sessions</span>
47
+ <span class="stat-value">${stats.adminActiveSessions ?? '0'}</span>
48
+ </div>
49
+ <div class="stat-row">
50
+ <span class="stat-label">Total Requests</span>
51
+ <span class="stat-value">${stats.totalRequests.toLocaleString()}</span>
52
+ </div>
53
+ <div class="stat-row">
54
+ <span class="stat-label">Error Rate</span>
55
+ <span class="stat-value">${stats.errorRate.toFixed(2)}%</span>
56
+ </div>
57
+ <div class="stat-row">
58
+ <span class="stat-label">Avg Response Time</span>
59
+ <span class="stat-value">${stats.avgResponseTime.toFixed(1)}ms</span>
60
+ </div>
61
+ <hr style="opacity:.15;margin:6px 0;"/>
62
+ <div class="stat-row">
63
+ <span class="stat-label" style="opacity:.8">index Accepted</span>
64
+ <span class="stat-value">${stats.indexStats?.acceptedInstructions ?? stats.indexStats?.totalInstructions ?? '—'}</span>
65
+ </div>
66
+ <div class="stat-row" title="Physical *.json files discovered (raw). May exceed accepted due to validation skips">
67
+ <span class="stat-label" style="opacity:.8">index Files</span>
68
+ <span class="stat-value">${stats.indexStats?.rawFileCount ?? '—'}</span>
69
+ </div>
70
+ <div class="stat-row" title="Rejected/skipped after validation/normalization">
71
+ <span class="stat-label" style="opacity:.8">index Skipped</span>
72
+ <span class="stat-value">${stats.indexStats?.skippedInstructions ?? '—'}</span>
73
+ </div>
74
+ <div class="stat-row">
75
+ <span class="stat-label" style="opacity:.8">index Version</span>
76
+ <span class="stat-value">${stats.indexStats?.version ?? '—'}</span>
77
+ </div>
78
+ <div class="stat-row">
79
+ <span class="stat-label" style="opacity:.8">Schema Version</span>
80
+ <span class="stat-value">${stats.indexStats?.schemaVersion ?? 'unknown'}</span>
81
+ </div>
82
+ <div class="stat-row">
83
+ <span class="stat-label" style="opacity:.8">Last Updated</span>
84
+ <span class="stat-value">${stats.indexStats?.lastUpdated ? new Date(stats.indexStats.lastUpdated).toLocaleString() : 'N/A'}</span>
85
+ </div>
86
+ `;
87
+ const el = document.getElementById('system-stats'); if(el) el.innerHTML = html;
88
+
89
+ const perfParts = [];
90
+ perfParts.push(`
91
+ <div class="stat-row">
92
+ <span class="stat-label">Total Connections</span>
93
+ <span class="stat-value">${stats.totalConnections.toLocaleString()}</span>
94
+ </div>
95
+ <div class="stat-row">
96
+ <span class="stat-label">Error Rate</span>
97
+ <span class="stat-value">${stats.errorRate.toFixed(2)}%</span>
98
+ </div>
99
+ <div class="stat-row">
100
+ <span class="stat-label">Response Time</span>
101
+ <span class="stat-value">${stats.avgResponseTime.toFixed(1)}ms</span>
102
+ </div>`);
103
+ try {
104
+ if(window.__resourceTrendCache){
105
+ const t = window.__resourceTrendCache;
106
+ perfParts.push(`
107
+ <div class="stat-row">
108
+ <span class="stat-label">Window</span>
109
+ <span class="stat-value">${t.windowSec}s (${t.sampleCount} samples)</span>
110
+ </div>
111
+ <div class="stat-row">
112
+ <span class="stat-label">Memory Usage</span>
113
+ <span class="stat-value">${formatBytes(stats.memoryUsage.heapUsed)} / ${formatBytes(stats.memoryUsage.heapLimit || stats.memoryUsage.heapTotal)}</span>
114
+ </div>`);
115
+ }
116
+ } catch(e) { /* ignore */ }
117
+ const perfEl = document.getElementById('performance-stats'); if(perfEl) perfEl.innerHTML = perfParts.join('');
118
+
119
+ displayToolMetrics(stats);
120
+ }
121
+
122
+ function displayToolMetrics(stats) {
123
+ const toolMetricsEl = document.getElementById('tool-metrics');
124
+ if (!toolMetricsEl || !stats.toolMetrics) {
125
+ if (toolMetricsEl) toolMetricsEl.innerHTML = '<div class="error-message">Tool metrics unavailable</div>';
126
+ return;
127
+ }
128
+ const tools = Object.entries(stats.toolMetrics);
129
+ tools.sort(([,a], [,b]) => b.callCount - a.callCount);
130
+
131
+ let html = '<div class="tool-metrics-grid">';
132
+ tools.forEach(([toolName, metrics]) => {
133
+ const avgResponseTime = metrics.callCount > 0 ? (metrics.totalResponseTime / metrics.callCount).toFixed(1) : '0.0';
134
+ const successRate = metrics.callCount > 0 ? ((metrics.successCount / metrics.callCount) * 100).toFixed(1) : '100.0';
135
+ html += `
136
+ <div class="tool-metric-card">
137
+ <div class="tool-name">${toolName}</div>
138
+ <div class="tool-stats">
139
+ <div class="stat-row">
140
+ <span class="stat-label">Total Calls</span>
141
+ <span class="stat-value">${metrics.callCount.toLocaleString()}</span>
142
+ </div>
143
+ <div class="stat-row">
144
+ <span class="stat-label">Success Rate</span>
145
+ <span class="stat-value ${parseFloat(successRate) < 95 ? 'warning' : ''}">${successRate}%</span>
146
+ </div>
147
+ <div class="stat-row">
148
+ <span class="stat-label">Avg Response</span>
149
+ <span class="stat-value">${avgResponseTime}ms</span>
150
+ </div>
151
+ </div>
152
+ </div>`;
153
+ });
154
+ html += '</div>';
155
+ toolMetricsEl.innerHTML = html;
156
+ }
157
+
158
+ // expose for other scripts and inline handlers
159
+ window.loadOverviewData = loadOverviewData;
160
+ window.displaySystemStats = displaySystemStats;
161
+ window.displayToolMetrics = displayToolMetrics;
162
+
163
+ // Usage Signals panel
164
+ async function loadUsageSignals() {
165
+ const panel = document.getElementById('usage-signals-panel');
166
+ if (!panel) return;
167
+ try {
168
+ const res = await fetch('/api/usage/snapshot');
169
+ if (!res.ok) throw new Error('http ' + res.status);
170
+ const data = await res.json();
171
+ const snap = data.snapshot || {};
172
+ const entries = Object.entries(snap).filter(function(e) { return e[1] && (e[1].lastSignal || e[1].usageCount); });
173
+ if (!entries.length) { panel.innerHTML = '<div style="opacity:.6;">No usage signals recorded yet.</div>'; return; }
174
+
175
+ // Summary counts
176
+ var signalCounts = {};
177
+ var totalUsage = 0;
178
+ var withSignal = 0;
179
+ entries.forEach(function(e) {
180
+ var rec = e[1];
181
+ totalUsage += rec.usageCount || 0;
182
+ if (rec.lastSignal) { withSignal++; signalCounts[rec.lastSignal] = (signalCounts[rec.lastSignal] || 0) + 1; }
183
+ });
184
+
185
+ var colors = { 'outdated': '#f2495c', 'not-relevant': '#ff9830', 'helpful': '#73bf69', 'applied': '#5794f2' };
186
+ var summaryHtml = '<div class="stat-row"><span class="stat-label">Instructions with Usage</span><span class="stat-value">' + entries.length + '</span></div>';
187
+ summaryHtml += '<div class="stat-row"><span class="stat-label">Total Usage Count</span><span class="stat-value">' + totalUsage + '</span></div>';
188
+ summaryHtml += '<div class="stat-row"><span class="stat-label">Instructions with Signals</span><span class="stat-value">' + withSignal + '</span></div>';
189
+ summaryHtml += '<hr style="opacity:.15;margin:6px 0;"/>';
190
+ Object.keys(signalCounts).sort().forEach(function(sig) {
191
+ var c = colors[sig] || '#888';
192
+ summaryHtml += '<div class="stat-row"><span class="stat-label"><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:' + c + ';margin-right:6px;"></span>' + sig + '</span><span class="stat-value">' + signalCounts[sig] + '</span></div>';
193
+ });
194
+
195
+ // Top 10 most signaled
196
+ var signaled = entries.filter(function(e) { return e[1].lastSignal; }).sort(function(a, b) { return (b[1].usageCount || 0) - (a[1].usageCount || 0); }).slice(0, 10);
197
+ if (signaled.length) {
198
+ summaryHtml += '<hr style="opacity:.15;margin:6px 0;"/>';
199
+ summaryHtml += '<div style="font-weight:600;font-size:11px;margin-bottom:4px;">Top Signaled Instructions</div>';
200
+ signaled.forEach(function(e) {
201
+ var id = e[0]; var rec = e[1];
202
+ var c = colors[rec.lastSignal] || '#888';
203
+ var badge = '<span style="background:' + c + '22;color:' + c + ';border:1px solid ' + c + '44;padding:1px 6px;border-radius:3px;font-size:10px;font-weight:600;">' + rec.lastSignal + '</span>';
204
+ var comment = rec.lastComment ? ' <span style="opacity:.5;font-size:10px;" title="' + (rec.lastComment || '').replace(/"/g, '&quot;').slice(0,200) + '">💬</span>' : '';
205
+ summaryHtml += '<div style="display:flex;justify-content:space-between;align-items:center;padding:2px 0;font-size:11px;"><span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%;" title="' + id + '">' + id + '</span><span>' + badge + ' <span style="opacity:.6;">(' + (rec.usageCount || 0) + ' uses)</span>' + comment + '</span></div>';
206
+ });
207
+ }
208
+
209
+ panel.innerHTML = '<div class="metrics-list">' + summaryHtml + '</div>';
210
+ } catch (e) {
211
+ panel.innerHTML = '<div class="error-message">Failed to load usage signals: ' + (e.message || e) + '</div>';
212
+ }
213
+ }
214
+
215
+ // Hook into overview load
216
+ var origLoadOverview = window.loadOverviewData;
217
+ window.loadOverviewData = async function() {
218
+ await Promise.all([origLoadOverview(), loadUsageSignals()]);
219
+ };
220
+ window.loadUsageSignals = loadUsageSignals;
221
+ })();
@@ -0,0 +1,61 @@
1
+ /* eslint-disable */
2
+ // Extracted from admin.html: Resource Trend (CPU/Mem) helpers
3
+ (function(){
4
+ (function initResourceTrendMerge(){
5
+ async function fetchResourceTrends(){
6
+ try {
7
+ const res = await fetch('/api/system/resources?limit=300');
8
+ if(!res.ok) throw new Error('http '+res.status);
9
+ const json = await res.json();
10
+ const samples = json?.data?.samples || [];
11
+ const trend = json?.data?.trend || { cpuSlope:0, memSlope:0 };
12
+ if(samples.length === 0){
13
+ window.__resourceTrendCache = { windowSec:0, sampleCount:0, latestCpu:0, latestHeap:0, cpuSlope:0, memSlope:0, spark:'' };
14
+ return;
15
+ }
16
+ const latest = samples[samples.length-1];
17
+ const first = samples[0];
18
+ const durationSec = ((latest.timestamp - first.timestamp)/1000).toFixed(0);
19
+ const tail = samples.slice(-40);
20
+ const spark = tail.map(s=>{
21
+ const v = Math.min(100, Math.max(0, s.cpuPercent));
22
+ const idx = Math.round(v/12.5);
23
+ const blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
24
+ return blocks[Math.min(blocks.length-1, idx)];
25
+ }).join('');
26
+ const minCpu = tail.reduce((m,s)=> s.cpuPercent<m? s.cpuPercent:m, tail[0].cpuPercent);
27
+ const maxCpu = tail.reduce((m,s)=> s.cpuPercent>m? s.cpuPercent:m, tail[0].cpuPercent);
28
+ const maxHeap = tail.reduce((m,s)=> s.heapUsed>m?s.heapUsed:m,0) || 1;
29
+ const minHeap = tail.reduce((m,s)=> s.heapUsed<m?s.heapUsed:m, tail[0].heapUsed);
30
+ const memSpark = tail.map(s=>{
31
+ const ratio = Math.min(1, Math.max(0, s.heapUsed / maxHeap));
32
+ const idx = Math.round(ratio*7);
33
+ const blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
34
+ return blocks[Math.min(blocks.length-1, idx)];
35
+ }).join('');
36
+ window.__resourceTrendCache = {
37
+ windowSec: durationSec,
38
+ sampleCount: samples.length,
39
+ latestCpu: latest.cpuPercent,
40
+ latestHeap: latest.heapUsed,
41
+ minCpu,
42
+ maxCpu,
43
+ minHeap,
44
+ maxHeap,
45
+ cpuSlope: trend.cpuSlope || 0,
46
+ memSlope: trend.memSlope || 0,
47
+ spark,
48
+ memSpark
49
+ };
50
+ try {
51
+ if(typeof window.lastSystemStats === 'object') displaySystemStats(window.lastSystemStats);
52
+ if(typeof window.lastSystemHealth === 'object') displaySystemHealth(window.lastSystemHealth);
53
+ } catch(e){/*ignore*/}
54
+ } catch(e){
55
+ // ignore failures
56
+ }
57
+ }
58
+ fetchResourceTrends();
59
+ setInterval(fetchResourceTrends, 10000);
60
+ })();
61
+ })();