@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,618 @@
1
+ "use strict";
2
+ /* eslint-disable */
3
+ /**
4
+ * legacyDashboardHtml - generates the v1 legacy dashboard HTML page.
5
+ * Extracted from DashboardServer.ts to keep the coordinator within line limits.
6
+ * CSS lives in legacyDashboardStyles.ts to stay within per-file line limits.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.stripGraphTab = stripGraphTab;
10
+ exports.formatUptime = formatUptime;
11
+ exports.generateDashboardHtml = generateDashboardHtml;
12
+ const legacyDashboardStyles_js_1 = require("./legacyDashboardStyles.js");
13
+ // ---------------------------------------------------------------------------
14
+ // stripGraphTab - removes graph-related markup when the graph feature is off
15
+ // ---------------------------------------------------------------------------
16
+ function stripGraphTab(html) {
17
+ html = html.replace(/<button[^>]*data-section="graph"[^>]*>Graph<\/button>\s*/i, "");
18
+ html = html.replace(/<!--\s*Graph Section\s*-->[\s\S]*?(?=<!--\s*Configuration Section\s*-->)/i, "");
19
+ html = html.replace(/<script[^>]*src="js\/admin\.graph\.js[^"]*"[^>]*><\/script>\s*/i, "");
20
+ return html;
21
+ }
22
+ // ---------------------------------------------------------------------------
23
+ // formatUptime - converts milliseconds to a human-readable duration string
24
+ // ---------------------------------------------------------------------------
25
+ function formatUptime(ms) {
26
+ const seconds = Math.floor(ms / 1000);
27
+ const days = Math.floor(seconds / 86400);
28
+ const hours = Math.floor((seconds % 86400) / 3600);
29
+ const minutes = Math.floor((seconds % 3600) / 60);
30
+ if (days > 0)
31
+ return `${days}d ${hours}h ${minutes}m`;
32
+ if (hours > 0)
33
+ return `${hours}h ${minutes}m`;
34
+ return `${minutes}m ${seconds % 60}s`;
35
+ }
36
+ // ---------------------------------------------------------------------------
37
+ // generateDashboardHtml - full legacy v1 dashboard page
38
+ // ---------------------------------------------------------------------------
39
+ function generateDashboardHtml(nonce, snapshot, webSocketUrl) {
40
+ return `<!DOCTYPE html>
41
+ <html lang="en">
42
+ <head>
43
+ <meta charset="UTF-8">
44
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
45
+ <title>Index Server - Enhanced Dashboard v2.0</title>
46
+ <script nonce="${nonce}" src="/js/chart.umd.js"></script>
47
+ <style nonce="${nonce}">
48
+ ${legacyDashboardStyles_js_1.LEGACY_DASHBOARD_CSS}
49
+ </style>
50
+ </head>
51
+ </head>
52
+ <body>
53
+ <div class="header">
54
+ <h1>Index Server Dashboard</h1>
55
+ <div class="subtitle">Enhanced Real-time Monitoring v2.0</div>
56
+ <div class="version">Server v${snapshot.server.version} | Start Time ${new Date(snapshot.server.startTime).toLocaleString()}</div>
57
+ </div>
58
+
59
+ <div class="container">
60
+ <!-- Dashboard Controls -->
61
+ <div class="dashboard-controls">
62
+ <div class="control-group">
63
+ <label class="control-label">WebSocket Status</label>
64
+ <div id="connection-status" class="connection-status ${webSocketUrl ? 'connected' : 'disconnected'}">
65
+ ${webSocketUrl ? 'Connected' : 'Disabled'}
66
+ </div>
67
+ </div>
68
+ <div class="control-group">
69
+ <label class="control-label">Actions</label>
70
+ <button id="refresh-btn" class="control-button">Refresh Metrics</button>
71
+ </div>
72
+ ${!webSocketUrl ? `<div class="control-group">
73
+ <label class="control-label">Manual Refresh</label>
74
+ <button id="reconnect-btn" class="control-button">Enable Real-time</button>
75
+ </div>` : ''}
76
+ </div>
77
+
78
+ <!-- Status Cards -->
79
+ <div class="status-grid">
80
+ <div class="status-card">
81
+ <div class="status-label">Server Uptime</div>
82
+ <div id="uptime-value" class="status-value status-online">${formatUptime(snapshot.server.uptime)}</div>
83
+ </div>
84
+ <div class="status-card">
85
+ <div class="status-label">Total Tool Calls</div>
86
+ <div id="total-requests-value" class="status-value">${Object.values(snapshot.tools).reduce((sum, tool) => sum + tool.callCount, 0).toLocaleString()}</div>
87
+ </div>
88
+ <div class="status-card">
89
+ <div class="status-label">Success Rate</div>
90
+ <div id="success-rate-value" class="status-value status-online">${(snapshot.performance.successRate * 100).toFixed(1)}%</div>
91
+ </div>
92
+ <div class="status-card">
93
+ <div class="status-label">Avg Response Time</div>
94
+ <div id="avg-response-time-value" class="status-value">${snapshot.performance.avgResponseTime.toFixed(0)}ms</div>
95
+ </div>
96
+ <div class="status-card">
97
+ <div class="status-label">Active Connections</div>
98
+ <div id="connections-value" class="status-value">${snapshot.connections.totalConnections}</div>
99
+ </div>
100
+ </div>
101
+
102
+ <!-- Performance Metrics -->
103
+ <div class="performance-metrics">
104
+ <div class="metric-item">
105
+ <div class="metric-label">Requests/Min</div>
106
+ <div id="requests-per-minute" class="metric-value">${snapshot.performance.requestsPerMinute.toFixed(1)}</div>
107
+ </div>
108
+ <div class="metric-item ${snapshot.performance.errorRate > 0.05 ? 'metric-danger' : snapshot.performance.errorRate > 0.01 ? 'metric-warning' : 'metric-success'}">
109
+ <div class="metric-label">Error Rate</div>
110
+ <div id="error-rate-percent" class="metric-value">${(snapshot.performance.errorRate * 100).toFixed(2)}%</div>
111
+ </div>
112
+ </div>
113
+
114
+ <!-- Phase 3 Enhanced Charts with Time Range Selection -->
115
+ <div class="charts-controls">
116
+ <div class="time-range-selector">
117
+ <label for="time-range">Time Range:</label>
118
+ <select id="time-range" class="time-range-select">
119
+ <option value="60">Last Hour</option>
120
+ <option value="360">Last 6 Hours</option>
121
+ <option value="1440" selected>Last 24 Hours</option>
122
+ <option value="10080">Last 7 Days</option>
123
+ <option value="43200">Last 30 Days</option>
124
+ </select>
125
+ </div>
126
+ <div class="chart-actions">
127
+ <button id="refresh-charts" class="action-btn">🔄 Refresh</button>
128
+ <button id="export-charts" class="action-btn">📊 Export</button>
129
+ <button id="fullscreen-toggle" class="action-btn">⛶ Fullscreen</button>
130
+ </div>
131
+ </div>
132
+
133
+ <div class="charts-grid">
134
+ <div class="chart-container">
135
+ <div class="chart-title">
136
+ Requests per Minute
137
+ <span class="chart-status" id="requests-status">●</span>
138
+ </div>
139
+ <div class="chart-wrapper">
140
+ <canvas id="requestsChart"></canvas>
141
+ </div>
142
+ </div>
143
+ <div class="chart-container">
144
+ <div class="chart-title">
145
+ Tool Usage Distribution
146
+ <span class="chart-status" id="usage-status">●</span>
147
+ </div>
148
+ <div class="chart-wrapper">
149
+ <canvas id="toolUsageChart"></canvas>
150
+ </div>
151
+ </div>
152
+ <div class="chart-container">
153
+ <div class="chart-title">
154
+ Response Time Trends
155
+ <span class="chart-status" id="response-status">●</span>
156
+ </div>
157
+ <div class="chart-wrapper">
158
+ <canvas id="responseTimeChart"></canvas>
159
+ </div>
160
+ </div>
161
+ <div class="chart-container">
162
+ <div class="chart-title">
163
+ Error Rate Over Time
164
+ <span class="chart-status" id="error-status">●</span>
165
+ </div>
166
+ <div class="chart-wrapper">
167
+ <canvas id="errorRateChart"></canvas>
168
+ </div>
169
+ </div>
170
+ </div>
171
+
172
+ <!-- Enhanced Tools Section -->
173
+ <div class="tools-section">
174
+ <div class="tools-header">
175
+ <h2 class="tools-title">Tool Registry</h2>
176
+ <input type="text" id="tools-filter" class="tools-filter" placeholder="Filter tools...">
177
+ </div>
178
+ <table class="tools-table">
179
+ <thead>
180
+ <tr>
181
+ <th>Tool Name</th>
182
+ <th>Calls</th>
183
+ <th>Success</th>
184
+ <th>Errors</th>
185
+ <th>Avg Response</th>
186
+ <th>Last Called</th>
187
+ </tr>
188
+ </thead>
189
+ <tbody id="tools-table-body">
190
+ ${Object.entries(snapshot.tools).map(([toolName, metrics]) => `
191
+ <tr>
192
+ <td class="tool-name">${toolName}</td>
193
+ <td class="tool-calls">${metrics.callCount}</td>
194
+ <td class="tool-success">${metrics.successCount}</td>
195
+ <td class="tool-errors">${metrics.errorCount}</td>
196
+ <td class="tool-response-time">${(metrics.totalResponseTime / Math.max(metrics.callCount, 1)).toFixed(0)}ms</td>
197
+ <td class="tool-last-called">${metrics.lastCalled ? new Date(metrics.lastCalled).toLocaleTimeString() : 'Never'}</td>
198
+ </tr>
199
+ `).join('')}
200
+ </tbody>
201
+ </table>
202
+ </div>
203
+ </div>
204
+
205
+ <script nonce="${nonce}">
206
+ // Set global WebSocket URL for client
207
+ window.DASHBOARD_WS_URL = ${webSocketUrl ? `'${webSocketUrl}'` : 'null'};
208
+
209
+ console.log('[Dashboard] Enhanced dashboard v2.0 loaded');
210
+
211
+ // Basic functionality for non-WebSocket environments
212
+ if (!window.DASHBOARD_WS_URL) {
213
+ document.getElementById('refresh-btn')?.addEventListener('click', () => {
214
+ window.location.reload();
215
+ });
216
+
217
+ document.getElementById('reconnect-btn')?.addEventListener('click', () => {
218
+ alert('WebSocket support is disabled. Enable it in server configuration.');
219
+ });
220
+ }
221
+
222
+ // Tools filter functionality
223
+ const filterInput = document.getElementById('tools-filter');
224
+ if (filterInput) {
225
+ filterInput.addEventListener('input', (e) => {
226
+ const searchTerm = e.target.value.toLowerCase();
227
+ const tbody = document.getElementById('tools-table-body');
228
+ if (tbody) {
229
+ const rows = tbody.getElementsByTagName('tr');
230
+ Array.from(rows).forEach(row => {
231
+ const toolName = row.querySelector('.tool-name')?.textContent?.toLowerCase() || '';
232
+ row.style.display = toolName.includes(searchTerm) ? '' : 'none';
233
+ });
234
+ }
235
+ });
236
+ }
237
+
238
+ // Initialize interactions
239
+ document.querySelectorAll('.status-card, .chart-container').forEach(card => {
240
+ card.addEventListener('mouseenter', () => {
241
+ card.style.transform = 'translateY(-2px)';
242
+ });
243
+ card.addEventListener('mouseleave', () => {
244
+ card.style.transform = 'translateY(0)';
245
+ });
246
+ });
247
+
248
+ // Phase 3 Enhanced Dashboard with Interactive Features
249
+ if (window.Chart && window.DASHBOARD_WS_URL) {
250
+ console.log('[Dashboard] Phase 3 initialization - Chart.js available');
251
+
252
+ // Phase 3 state management
253
+ let currentTimeRange = 1440; // 24 hours default
254
+ const charts = {}; // will hold Chart.js instances keyed by id
255
+ let isFullscreen = false;
256
+ const chartConfig = {
257
+ responsive: true,
258
+ maintainAspectRatio: false,
259
+ animation: false,
260
+ interaction: { mode: 'nearest', intersect: false },
261
+ plugins: { legend: { position: 'bottom' } },
262
+ scales: { x: { ticks: { maxRotation: 0, autoSkip: true } }, y: { beginAtZero: true } }
263
+ };
264
+ const metricIdAliases = {
265
+ 'success-rate-percent': ['success-rate-value'],
266
+ 'avg-response-time': ['avg-response-time-value']
267
+ };
268
+ ensureStatusBar();
269
+
270
+ } else {
271
+ console.log('[Dashboard] Phase 3 disabled - WebSocket not available');
272
+ }
273
+
274
+ // Phase 3 Feature Initialization
275
+ function initializePhase3Features() {
276
+ console.log('[Dashboard] Initializing Phase 3 interactive features');
277
+
278
+ // Time range selector
279
+ const timeRangeSelect = document.getElementById('time-range');
280
+ if (timeRangeSelect) {
281
+ timeRangeSelect.addEventListener('change', function() {
282
+ currentTimeRange = parseInt(this.value);
283
+ updateChartsWithTimeRange(currentTimeRange);
284
+ updateChartStatus('updating');
285
+ });
286
+ }
287
+
288
+ // Refresh button
289
+ const refreshBtn = document.getElementById('refresh-charts');
290
+ if (refreshBtn) {
291
+ refreshBtn.addEventListener('click', function() {
292
+ refreshAllCharts();
293
+ updateChartStatus('refreshing');
294
+ });
295
+ }
296
+
297
+ // Export button
298
+ const exportBtn = document.getElementById('export-charts');
299
+ if (exportBtn) {
300
+ exportBtn.addEventListener('click', function() {
301
+ exportChartData();
302
+ });
303
+ }
304
+
305
+ // Fullscreen toggle
306
+ const fullscreenBtn = document.getElementById('fullscreen-toggle');
307
+ if (fullscreenBtn) {
308
+ fullscreenBtn.addEventListener('click', function() {
309
+ toggleFullscreen();
310
+ });
311
+ }
312
+
313
+ // Initialize real-time updates
314
+ startRealtimeUpdates();
315
+ }
316
+
317
+ // Update charts with new time range
318
+ function updateChartsWithTimeRange(minutes) {
319
+ console.log('[Dashboard] Updating charts for ' + minutes + ' minutes');
320
+
321
+ // Update tool usage chart
322
+ fetch('/api/charts/tool-usage?minutes=' + minutes)
323
+ .then(response => response.json())
324
+ .then(data => {
325
+ if (data.success) {
326
+ updateToolUsageChart(data.data);
327
+ }
328
+ })
329
+ .catch(error => console.error('Failed to update tool usage:', error));
330
+
331
+ // Update performance chart
332
+ fetch('/api/charts/performance?minutes=' + minutes)
333
+ .then(response => response.json())
334
+ .then(data => {
335
+ if (data.success) {
336
+ updatePerformanceCharts(data.data);
337
+ }
338
+ })
339
+ .catch(error => console.error('Failed to update performance:', error));
340
+ }
341
+
342
+ // Refresh all charts
343
+ function refreshAllCharts() {
344
+ console.log('[Dashboard] Refreshing all charts');
345
+ updateChartsWithTimeRange(currentTimeRange);
346
+
347
+ // Refresh realtime metrics
348
+ fetch('/api/realtime')
349
+ .then(response => response.json())
350
+ .then(data => {
351
+ if (data.success) {
352
+ updateRealtimeWidgets(data.data);
353
+ }
354
+ })
355
+ .catch(error => console.error('Failed to refresh realtime:', error));
356
+ }
357
+
358
+ // Export chart data
359
+ function exportChartData() {
360
+ console.log('[Dashboard] Exporting chart data');
361
+ const range = getTimeRangeString(currentTimeRange);
362
+ const exportUrl = '/api/charts/export?format=csv&range=' + range;
363
+
364
+ // Create download link
365
+ const link = document.createElement('a');
366
+ link.href = exportUrl;
367
+ link.download = 'dashboard-metrics-' + range + '-' + Date.now() + '.csv';
368
+ document.body.appendChild(link);
369
+ link.click();
370
+ document.body.removeChild(link);
371
+ }
372
+
373
+ // Toggle fullscreen mode
374
+ function toggleFullscreen() {
375
+ const chartsGrid = document.querySelector('.charts-grid');
376
+ if (!chartsGrid) return;
377
+
378
+ if (!isFullscreen) {
379
+ chartsGrid.style.position = 'fixed';
380
+ chartsGrid.style.top = '0';
381
+ chartsGrid.style.left = '0';
382
+ chartsGrid.style.width = '100vw';
383
+ chartsGrid.style.height = '100vh';
384
+ chartsGrid.style.zIndex = '9999';
385
+ chartsGrid.style.background = 'var(--bg-color)';
386
+ chartsGrid.style.padding = '2rem';
387
+ chartsGrid.style.overflow = 'auto';
388
+ isFullscreen = true;
389
+ document.getElementById('fullscreen-toggle').textContent = '⛶ Exit Fullscreen';
390
+ } else {
391
+ chartsGrid.style.position = '';
392
+ chartsGrid.style.top = '';
393
+ chartsGrid.style.left = '';
394
+ chartsGrid.style.width = '';
395
+ chartsGrid.style.height = '';
396
+ chartsGrid.style.zIndex = '';
397
+ chartsGrid.style.background = '';
398
+ chartsGrid.style.padding = '';
399
+ chartsGrid.style.overflow = '';
400
+ isFullscreen = false;
401
+ document.getElementById('fullscreen-toggle').textContent = '⛶ Fullscreen';
402
+ }
403
+ }
404
+
405
+ // Update chart status indicators
406
+ function updateChartStatus(status) {
407
+ const statusElements = document.querySelectorAll('.chart-status');
408
+ statusElements.forEach(el => {
409
+ el.style.color = status === 'updating' ? '#ffc107' :
410
+ status === 'refreshing' ? '#17a2b8' : '#28a745';
411
+ });
412
+
413
+ if (status !== 'normal') {
414
+ setTimeout(() => updateChartStatus('normal'), 2000);
415
+ }
416
+ }
417
+
418
+ // Start real-time updates
419
+ function startRealtimeUpdates() {
420
+ setInterval(() => {
421
+ fetch('/api/realtime')
422
+ .then(response => response.json())
423
+ .then(data => {
424
+ if (data.success) {
425
+ updateRealtimeWidgets(data.data);
426
+ }
427
+ })
428
+ .catch(error => console.error('Realtime update failed:', error));
429
+ }, 30000); // Update every 30 seconds
430
+ }
431
+
432
+ // Helper functions
433
+ function getTimeRangeString(minutes) {
434
+ if (minutes === 60) return '1h';
435
+ if (minutes === 360) return '6h';
436
+ if (minutes === 1440) return '24h';
437
+ if (minutes === 10080) return '7d';
438
+ if (minutes === 43200) return '30d';
439
+ return '1h';
440
+ }
441
+
442
+ function updateToolUsageChart(data) {
443
+ if (!data) return;
444
+ try {
445
+ const canvas = document.getElementById('toolUsageChart');
446
+ if (!canvas) return;
447
+ const labels = data.timestamps?.map(ts => new Date(ts).toLocaleTimeString()) || [];
448
+ const series = (data.series || data.datasets || []);
449
+ if (!charts.toolUsageChart) {
450
+ charts.toolUsageChart = new Chart(canvas.getContext('2d'), {
451
+ type: 'line',
452
+ data: {
453
+ labels,
454
+ datasets: series.map(s => ({
455
+ label: s.label || s.name || 'Series',
456
+ data: s.data || [],
457
+ fill: false,
458
+ tension: 0.25,
459
+ borderWidth: 2
460
+ }))
461
+ },
462
+ options: chartConfig
463
+ });
464
+ } else {
465
+ charts.toolUsageChart.data.labels = labels;
466
+ charts.toolUsageChart.data.datasets.forEach((ds, i) => {
467
+ ds.data = series[i] ? series[i].data : [];
468
+ });
469
+ charts.toolUsageChart.update();
470
+ }
471
+ } catch (e) { console.error('toolUsageChart update failed', e); showErrorBanner('Tool usage chart error'); }
472
+ }
473
+
474
+ function updatePerformanceCharts(data) {
475
+ if (!data) return;
476
+ try {
477
+ const labels = data.timestamps?.map(ts => new Date(ts).toLocaleTimeString()) || [];
478
+ const perfSeries = data.series || data.datasets || [];
479
+ const chartMap = [
480
+ { id: 'requestsChart', key: 'requestsPerMinute' },
481
+ { id: 'responseTimeChart', key: 'avgResponseTime' },
482
+ { id: 'errorRateChart', key: 'errorRate' }
483
+ ];
484
+ chartMap.forEach(cfg => {
485
+ const canvas = document.getElementById(cfg.id);
486
+ if (!canvas) return;
487
+ // Build/find series with matching key
488
+ const s = perfSeries.find(s => s.key === cfg.key || s.label === cfg.key);
489
+ const datasetData = s?.data || [];
490
+ if (!charts[cfg.id]) {
491
+ charts[cfg.id] = new Chart(canvas.getContext('2d'), {
492
+ type: 'line',
493
+ data: { labels, datasets: [{ label: cfg.key, data: datasetData, borderWidth: 2, tension: 0.25, fill: false }] },
494
+ options: chartConfig
495
+ });
496
+ } else {
497
+ charts[cfg.id].data.labels = labels;
498
+ charts[cfg.id].data.datasets[0].data = datasetData;
499
+ charts[cfg.id].update();
500
+ }
501
+ });
502
+ } catch (e) { console.error('performance charts update failed', e); showErrorBanner('Performance chart error'); }
503
+ }
504
+
505
+ function updateRealtimeWidgets(data) {
506
+ // Update real-time metric widgets
507
+ console.log('[Dashboard] Updating realtime widgets', data);
508
+
509
+ // Update metric cards if they exist
510
+ const elements = {
511
+ 'requests-per-minute': data.currentRpm,
512
+ 'active-connections': data.activeConnections,
513
+ 'avg-response-time': data.avgResponseTime + 'ms',
514
+ 'success-rate-percent': (data.successRate * 100).toFixed(2) + '%',
515
+ 'error-rate-percent': (data.errorRate * 100).toFixed(2) + '%'
516
+ };
517
+
518
+ for (const id in elements) {
519
+ let element = document.getElementById(id);
520
+ if (!element && metricIdAliases[id]) {
521
+ for (const alias of metricIdAliases[id]) {
522
+ element = document.getElementById(alias);
523
+ if (element) break;
524
+ }
525
+ }
526
+ if (element) element.textContent = elements[id];
527
+ }
528
+ }
529
+
530
+ // Error banner utilities
531
+ function ensureStatusBar() {
532
+ if (!document.getElementById('dashboard-status-bar')) {
533
+ const bar = document.createElement('div');
534
+ bar.id = 'dashboard-status-bar';
535
+ bar.style.cssText = 'position:fixed;bottom:0;left:0;right:0;font:12px sans-serif;padding:4px 8px;display:flex;gap:12px;align-items:center;background:#222;color:#eee;z-index:99999;';
536
+ bar.innerHTML = '<span id="ws-status">WS: pending</span><span id="error-banner" style="display:none;background:#b00020;padding:2px 6px;border-radius:4px;">Error</span>';
537
+ document.body.appendChild(bar);
538
+ }
539
+ }
540
+ function setWsStatus(text, color) {
541
+ const el = document.getElementById('ws-status');
542
+ if (el) { el.textContent = 'WS: ' + text; el.style.color = color; }
543
+ }
544
+ function showErrorBanner(msg) {
545
+ const el = document.getElementById('error-banner');
546
+ if (el) { el.textContent = msg; el.style.display = 'inline-block'; setTimeout(()=>{ el.style.display='none';}, 5000); }
547
+ }
548
+ // Live metric buffers for incremental chart updates (last 120 points)
549
+ const liveBuffers = { labels: [], rpm: [], avg: [], err: [] };
550
+ const MAX_POINTS = 120;
551
+
552
+ function handleMetricsUpdate(snapshot) {
553
+ if(!snapshot || !snapshot.performance) return;
554
+ const tsLabel = new Date(snapshot.timestamp || Date.now()).toLocaleTimeString();
555
+ liveBuffers.labels.push(tsLabel);
556
+ liveBuffers.rpm.push(snapshot.performance.requestsPerMinute || 0);
557
+ liveBuffers.avg.push(snapshot.performance.avgResponseTime || 0);
558
+ liveBuffers.err.push(snapshot.performance.errorRate || 0);
559
+ if(liveBuffers.labels.length > MAX_POINTS) {
560
+ ['labels','rpm','avg','err'].forEach(k=>liveBuffers[k].splice(0, liveBuffers[k].length - MAX_POINTS));
561
+ }
562
+ // Update existing charts if they exist
563
+ try {
564
+ if (typeof charts !== 'undefined') {
565
+ if (charts.requestsChart) {
566
+ charts.requestsChart.data.labels = liveBuffers.labels.slice();
567
+ charts.requestsChart.data.datasets[0].data = liveBuffers.rpm.slice();
568
+ charts.requestsChart.update();
569
+ }
570
+ if (charts.responseTimeChart) {
571
+ charts.responseTimeChart.data.labels = liveBuffers.labels.slice();
572
+ charts.responseTimeChart.data.datasets[0].data = liveBuffers.avg.slice();
573
+ charts.responseTimeChart.update();
574
+ }
575
+ if (charts.errorRateChart) {
576
+ charts.errorRateChart.data.labels = liveBuffers.labels.slice();
577
+ charts.errorRateChart.data.datasets[0].data = liveBuffers.err.slice();
578
+ charts.errorRateChart.update();
579
+ }
580
+ }
581
+ } catch(e){ console.warn('live chart update failed', e); }
582
+
583
+ // Derive realtime widget shape (normalize successRate to 0-1)
584
+ try {
585
+ const perf = snapshot.performance;
586
+ const derived = {
587
+ currentRpm: perf.requestsPerMinute || 0,
588
+ activeConnections: snapshot.connections?.activeConnections || 0,
589
+ avgResponseTime: perf.avgResponseTime || 0,
590
+ successRate: (perf.successRate > 1 ? perf.successRate/100 : perf.successRate),
591
+ errorRate: (perf.errorRate > 1 ? perf.errorRate/100 : perf.errorRate)
592
+ };
593
+ updateRealtimeWidgets(derived);
594
+ } catch(e){ console.warn('realtime widget update from metrics_update failed', e); }
595
+ }
596
+
597
+ // Establish WebSocket connection for status + metrics streaming
598
+ (function initStatusWebSocket(){
599
+ if(!("WebSocket" in window) || !window.DASHBOARD_WS_URL) { setWsStatus('unavailable','gray'); return; }
600
+ try {
601
+ const ws = new WebSocket(window.DASHBOARD_WS_URL);
602
+ let opened = false;
603
+ ws.addEventListener('open', ()=>{ opened = true; setWsStatus('connected','#16a34a'); });
604
+ ws.addEventListener('message', (ev)=>{
605
+ if(opened) setWsStatus('active','#16a34a');
606
+ try {
607
+ const msg = JSON.parse(ev.data);
608
+ if(msg && msg.type === 'metrics_update') { handleMetricsUpdate(msg.data); }
609
+ } catch { /* non-JSON or ignored */ }
610
+ });
611
+ ws.addEventListener('close', ()=>{ setWsStatus('closed','#dc2626'); setTimeout(()=>{ initStatusWebSocket(); }, 2000); });
612
+ ws.addEventListener('error', ()=>{ setWsStatus('error','#f97316'); try { ws.close(); } catch {/* ignore */} });
613
+ } catch(e){ console.error('ws status init failed', e); setWsStatus('error','#f97316'); }
614
+ })();
615
+ </script>
616
+ </body>
617
+ </html>`;
618
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * legacyDashboardStyles — CSS for the v1 legacy dashboard page.
3
+ * Kept in a separate module so legacyDashboardHtml.ts stays within line limits.
4
+ */
5
+ export declare const LEGACY_DASHBOARD_CSS = "\n /* Phase 2 Enhanced Styles */\n :root {\n --primary-color: #2c3e50;\n --secondary-color: #3498db;\n --accent-color: #3b82f6;\n --accent-hover: #2563eb;\n --success-color: #27ae60;\n --warning-color: #f39c12;\n --error-color: #e74c3c;\n --bg-primary: #f8f9fa;\n --bg-secondary: #e9ecef;\n --card-bg: #ffffff;\n --border-color: #dee2e6;\n --text-primary: #2c3e50;\n --text-secondary: #6c757d;\n --text-muted: #adb5bd;\n --shadow-sm: 0 1px 3px rgba(0,0,0,0.12);\n --shadow-lg: 0 4px 15px rgba(0,0,0,0.08);\n --shadow-xl: 0 10px 25px rgba(0,0,0,0.12);\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background-color: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n }\n\n .header {\n background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));\n color: white;\n padding: 2rem 0;\n text-align: center;\n box-shadow: var(--shadow-lg);\n }\n\n .header h1 {\n font-size: 2.5rem;\n font-weight: 700;\n margin-bottom: 0.5rem;\n }\n\n .header .subtitle {\n font-size: 1.1rem;\n opacity: 0.9;\n }\n\n .header .version {\n font-size: 0.9rem;\n opacity: 0.7;\n margin-top: 0.5rem;\n }\n\n .container {\n max-width: 1400px;\n margin: 0 auto;\n padding: 2rem;\n }\n\n /* Dashboard Controls */\n .dashboard-controls {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--card-bg);\n border-radius: 12px;\n border: 1px solid var(--border-color);\n box-shadow: var(--shadow-sm);\n }\n\n .control-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n\n .control-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--text-secondary);\n }\n\n .control-button {\n padding: 0.5rem 1rem;\n background: var(--accent-color);\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.3s ease;\n }\n\n .control-button:hover {\n background: var(--accent-hover);\n transform: translateY(-1px);\n }\n\n /* Connection Status */\n .connection-status {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border-radius: 20px;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all 0.3s ease;\n }\n\n .connection-status::before {\n content: '';\n width: 8px;\n height: 8px;\n border-radius: 50%;\n animation: pulse 2s infinite;\n }\n\n .connection-status.connected {\n background: rgba(34, 197, 94, 0.1);\n color: #16a34a;\n border: 1px solid rgba(34, 197, 94, 0.2);\n }\n\n .connection-status.connected::before {\n background: #16a34a;\n }\n\n .connection-status.disconnected {\n background: rgba(239, 68, 68, 0.1);\n color: #dc2626;\n border: 1px solid rgba(239, 68, 68, 0.2);\n }\n\n .connection-status.disconnected::before {\n background: #dc2626;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n\n /* Status Cards */\n .status-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n margin-bottom: 2rem;\n }\n\n .status-card {\n background: var(--card-bg);\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: var(--shadow-lg);\n border: 1px solid var(--border-color);\n transition: all 0.3s ease;\n position: relative;\n overflow: hidden;\n }\n\n .status-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--shadow-xl);\n }\n\n .status-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--accent-color);\n }\n\n .status-label {\n font-size: 0.875rem;\n color: var(--text-secondary);\n margin-bottom: 0.5rem;\n font-weight: 500;\n }\n\n .status-value {\n font-size: 2rem;\n font-weight: 700;\n color: var(--primary-color);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n }\n\n .status-online { color: var(--success-color); }\n .status-warning { color: var(--warning-color); }\n .status-error { color: var(--error-color); }\n\n /* Charts Grid */\n .charts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 2rem;\n margin-bottom: 2rem;\n }\n\n .chart-container {\n position: relative;\n height: 350px;\n background: var(--card-bg);\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: var(--shadow-lg);\n border: 1px solid var(--border-color);\n transition: all 0.3s ease;\n }\n\n .chart-container:hover {\n transform: translateY(-2px);\n box-shadow: var(--shadow-xl);\n }\n\n .chart-title {\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--text-primary);\n margin-bottom: 1rem;\n text-align: center;\n }\n\n .chart-wrapper {\n position: relative;\n height: 280px;\n width: 100%;\n }\n\n /* Phase 3 Chart Controls */\n .charts-controls {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n padding: 1rem;\n background: var(--card-bg);\n border-radius: 8px;\n border: 1px solid var(--border-color);\n }\n\n .time-range-selector {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n .time-range-selector label {\n font-weight: 500;\n color: var(--text-secondary);\n }\n\n .time-range-select {\n padding: 0.5rem 1rem;\n border: 1px solid var(--border-color);\n border-radius: 6px;\n background: var(--bg-color);\n color: var(--text-primary);\n font-size: 0.9rem;\n }\n\n .chart-actions {\n display: flex;\n gap: 0.5rem;\n }\n\n .action-btn {\n padding: 0.5rem 1rem;\n border: none;\n border-radius: 6px;\n background: var(--primary-color);\n color: white;\n font-size: 0.85rem;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .action-btn:hover {\n background: var(--primary-hover);\n transform: translateY(-1px);\n }\n\n .chart-status {\n float: right;\n font-size: 0.8rem;\n color: #28a745;\n animation: pulse 2s infinite;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n\n /* Performance Metrics */\n .performance-metrics {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin-bottom: 2rem;\n }\n\n .metric-item {\n background: var(--card-bg);\n border-radius: 8px;\n padding: 1.5rem;\n border: 1px solid var(--border-color);\n transition: all 0.3s ease;\n position: relative;\n box-shadow: var(--shadow-sm);\n }\n\n .metric-item::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n border-radius: 8px 8px 0 0;\n background: var(--border-color);\n transition: all 0.3s ease;\n }\n\n .metric-item.metric-success::before {\n background: var(--success-color);\n }\n\n .metric-item.metric-warning::before {\n background: var(--warning-color);\n }\n\n .metric-item.metric-danger::before {\n background: var(--error-color);\n }\n\n .metric-label {\n font-size: 0.875rem;\n color: var(--text-secondary);\n margin-bottom: 0.5rem;\n }\n\n .metric-value {\n font-size: 1.5rem;\n font-weight: 700;\n color: var(--text-primary);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n }\n\n /* Tools Section */\n .tools-section {\n background: var(--card-bg);\n border-radius: 12px;\n padding: 1.5rem;\n border: 1px solid var(--border-color);\n margin-bottom: 2rem;\n box-shadow: var(--shadow-lg);\n }\n\n .tools-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n gap: 1rem;\n }\n\n .tools-title {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--primary-color);\n }\n\n .tools-filter {\n flex: 1;\n max-width: 300px;\n padding: 0.5rem 1rem;\n border: 1px solid var(--border-color);\n border-radius: 8px;\n background: var(--bg-primary);\n color: var(--text-primary);\n font-size: 0.875rem;\n }\n\n .tools-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n }\n\n .tools-table th {\n background: var(--bg-secondary);\n color: var(--text-secondary);\n font-weight: 600;\n padding: 0.75rem;\n text-align: left;\n border-bottom: 2px solid var(--border-color);\n }\n\n .tools-table td {\n padding: 0.75rem;\n border-bottom: 1px solid var(--border-color);\n color: var(--text-primary);\n }\n\n .tools-table tr:hover {\n background: var(--bg-secondary);\n }\n\n .tool-name {\n font-weight: 500;\n color: var(--accent-color);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n }\n\n .tool-calls,\n .tool-success {\n color: var(--success-color);\n font-weight: 500;\n }\n\n .tool-errors {\n color: var(--error-color);\n font-weight: 500;\n }\n\n .tool-response-time {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n }\n\n .tool-last-called {\n color: var(--text-secondary);\n font-size: 0.8rem;\n }\n\n /* Responsive Design */\n @media (max-width: 768px) {\n .container {\n padding: 1rem;\n }\n\n .dashboard-controls {\n flex-direction: column;\n }\n\n .charts-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .charts-grid .chart-container {\n height: 300px;\n padding: 1rem;\n }\n\n .tools-header {\n flex-direction: column;\n align-items: stretch;\n }\n\n .tools-filter {\n max-width: none;\n }\n\n .performance-metrics {\n grid-template-columns: 1fr;\n }\n }\n";