@oneuptime/common 12.0.5 → 12.0.6

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 (528) hide show
  1. package/Models/DatabaseModels/AIRun.ts +33 -0
  2. package/Models/DatabaseModels/DataSource.ts +744 -0
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
  5. package/Models/DatabaseModels/User.ts +2 -0
  6. package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
  8. package/Models/DatabaseModels/UserSession.ts +2 -0
  9. package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
  10. package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
  11. package/Server/API/AIInsightAPI.ts +47 -4
  12. package/Server/API/AIInvestigationAPI.ts +25 -0
  13. package/Server/API/DashboardAPI.ts +176 -492
  14. package/Server/API/DataSourceAPI.ts +268 -0
  15. package/Server/API/StatusPageAPI.ts +11 -1
  16. package/Server/API/UserAPI.ts +119 -0
  17. package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  22. package/Server/Infrastructure/Queue.ts +26 -0
  23. package/Server/Infrastructure/QueueWorker.ts +17 -0
  24. package/Server/Middleware/TelemetryIngest.ts +8 -3
  25. package/Server/Services/AIInsightService.ts +132 -12
  26. package/Server/Services/AIRunService.ts +34 -0
  27. package/Server/Services/AIService.ts +17 -2
  28. package/Server/Services/AlertService.ts +38 -32
  29. package/Server/Services/AnalyticsDatabaseService.ts +8 -4
  30. package/Server/Services/DataSourceService.ts +200 -0
  31. package/Server/Services/HostService.ts +92 -0
  32. package/Server/Services/IncidentService.ts +45 -0
  33. package/Server/Services/Index.ts +2 -0
  34. package/Server/Services/MonitorService.ts +49 -0
  35. package/Server/Services/MonitorStatusService.ts +166 -0
  36. package/Server/Services/OpenTelemetryIngestService.ts +255 -184
  37. package/Server/Services/RumSessionPinService.ts +7 -21
  38. package/Server/Services/StatusPageSubscriberService.ts +13 -0
  39. package/Server/Services/UserService.ts +280 -9
  40. package/Server/Static/Vendor/README.md +62 -0
  41. package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
  42. package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
  43. package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
  44. package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
  45. package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
  46. package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
  47. package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
  48. package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
  49. package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
  50. package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
  51. package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
  52. package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
  53. package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
  54. package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
  55. package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
  56. package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
  57. package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
  58. package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
  59. package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
  60. package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
  61. package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
  62. package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
  63. package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
  64. package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
  65. package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
  66. package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
  67. package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
  68. package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
  69. package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
  70. package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
  71. package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
  72. package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
  73. package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
  74. package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
  75. package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
  76. package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
  77. package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
  78. package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
  79. package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
  80. package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
  81. package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
  82. package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
  83. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
  84. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
  85. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
  86. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
  90. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
  91. package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
  92. package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
  93. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
  94. package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
  95. package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
  96. package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
  97. package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
  98. package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
  99. package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
  100. package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
  101. package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
  102. package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
  103. package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
  104. package/Server/Utils/DataSource/EgressGuard.ts +446 -0
  105. package/Server/Utils/DataSource/HttpFetch.ts +221 -0
  106. package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
  107. package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
  108. package/Server/Utils/DataSource/Types.ts +93 -0
  109. package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
  110. package/Server/Utils/InProcessMemo.ts +141 -0
  111. package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
  112. package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
  113. package/Server/Utils/Monitor/MonitorResource.ts +14 -0
  114. package/Server/Utils/Response.ts +12 -1
  115. package/Server/Utils/SSRFProtection.ts +237 -0
  116. package/Server/Utils/StartServer.ts +8 -0
  117. package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
  118. package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
  119. package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
  120. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
  121. package/Server/Utils/Telemetry/Telemetry.ts +112 -1
  122. package/Server/Utils/Telemetry.ts +104 -3
  123. package/Server/Utils/VendorAssets.ts +165 -0
  124. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
  125. package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
  126. package/Server/Views/Partials/Head.ejs +21 -7
  127. package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
  128. package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
  129. package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
  130. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
  131. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
  132. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
  133. package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
  134. package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
  135. package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
  136. package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
  137. package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
  138. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
  139. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
  141. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
  142. package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
  143. package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
  144. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
  145. package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
  146. package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
  147. package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
  148. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
  149. package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
  150. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
  151. package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
  152. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
  153. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
  154. package/Tests/Server/Services/AIInsightService.test.ts +266 -11
  155. package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
  156. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
  157. package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
  158. package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
  159. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
  160. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
  161. package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
  162. package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
  163. package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
  165. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
  166. package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
  167. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
  168. package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
  169. package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
  170. package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
  171. package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
  172. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
  173. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
  174. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
  175. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
  176. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
  177. package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
  178. package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
  179. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
  180. package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
  181. package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
  182. package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
  183. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
  184. package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
  185. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
  186. package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
  187. package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
  188. package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
  189. package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
  190. package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
  191. package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
  192. package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
  193. package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
  194. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
  195. package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
  196. package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
  197. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
  198. package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
  199. package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
  200. package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
  201. package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
  202. package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
  203. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
  205. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
  206. package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
  207. package/Tests/Server/Utils/Telemetry.test.ts +87 -0
  208. package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
  209. package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
  210. package/Tests/Server/Views/OfflineRender.test.ts +297 -0
  211. package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
  212. package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
  213. package/Tests/Types/Password.test.ts +363 -0
  214. package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
  215. package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
  216. package/Tests/UI/Components/Modal.test.tsx +281 -1
  217. package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
  218. package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
  219. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
  220. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  221. package/Tests/Utils/Analytics.test.ts +23 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
  223. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
  224. package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
  225. package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
  226. package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
  227. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
  228. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
  229. package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
  230. package/Types/AI/AIInsightEvidence.ts +6 -0
  231. package/Types/Analytics/RevenueEvent.ts +31 -0
  232. package/Types/Dashboard/DashboardComponentType.ts +31 -0
  233. package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
  234. package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
  235. package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
  236. package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
  237. package/Types/DataSource/DataSourceLimits.ts +62 -0
  238. package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
  239. package/Types/DataSource/DataSourceTableResult.ts +38 -0
  240. package/Types/DataSource/DataSourceType.ts +213 -0
  241. package/Types/Date.ts +43 -3
  242. package/Types/Password.ts +64 -0
  243. package/Types/Permission.ts +46 -0
  244. package/Types/UserAuthenticationStatus.ts +34 -0
  245. package/UI/Components/Button/Button.tsx +1 -1
  246. package/UI/Components/ErrorBoundary.tsx +459 -108
  247. package/UI/Components/Icon/Icon.tsx +10 -9
  248. package/UI/Components/Modal/ConfirmModal.tsx +6 -1
  249. package/UI/Components/Modal/Modal.tsx +267 -35
  250. package/UI/Components/Modal/ModalFooter.tsx +6 -1
  251. package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
  252. package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
  253. package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
  254. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
  255. package/UI/Components/StatusPage/ResourceList.tsx +570 -0
  256. package/UI/Styles/Theme.css +18 -0
  257. package/UI/Utils/API/RequestOptions.ts +7 -0
  258. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
  259. package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
  260. package/UI/Utils/TestDataSource.ts +61 -0
  261. package/UI/esbuild-config.js +45 -0
  262. package/Utils/Analytics.ts +15 -0
  263. package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
  264. package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
  265. package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
  266. package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
  267. package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
  268. package/Utils/Dashboard/Components/Index.ts +28 -0
  269. package/Utils/DataSource/DataSourceQueryText.ts +94 -0
  270. package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
  271. package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
  272. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
  273. package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
  274. package/Utils/StatusPage/ResourceExplorer.ts +853 -0
  275. package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
  276. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
  278. package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
  279. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  280. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
  282. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/User.js +2 -0
  284. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
  286. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
  288. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
  290. package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
  292. package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
  294. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  295. package/build/dist/Server/API/AIInsightAPI.js +34 -4
  296. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  297. package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
  298. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  299. package/build/dist/Server/API/DashboardAPI.js +119 -433
  300. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  301. package/build/dist/Server/API/DataSourceAPI.js +173 -0
  302. package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
  303. package/build/dist/Server/API/StatusPageAPI.js +11 -1
  304. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  305. package/build/dist/Server/API/UserAPI.js +94 -2
  306. package/build/dist/Server/API/UserAPI.js.map +1 -1
  307. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
  308. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  309. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
  310. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
  311. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
  312. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
  313. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
  314. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
  315. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  316. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  317. package/build/dist/Server/Infrastructure/Queue.js +27 -0
  318. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  319. package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
  320. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  321. package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
  322. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  323. package/build/dist/Server/Services/AIInsightService.js +110 -10
  324. package/build/dist/Server/Services/AIInsightService.js.map +1 -1
  325. package/build/dist/Server/Services/AIRunService.js +34 -0
  326. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  327. package/build/dist/Server/Services/AIService.js +16 -2
  328. package/build/dist/Server/Services/AIService.js.map +1 -1
  329. package/build/dist/Server/Services/AlertService.js +28 -35
  330. package/build/dist/Server/Services/AlertService.js.map +1 -1
  331. package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
  332. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  333. package/build/dist/Server/Services/DataSourceService.js +159 -0
  334. package/build/dist/Server/Services/DataSourceService.js.map +1 -0
  335. package/build/dist/Server/Services/HostService.js +74 -0
  336. package/build/dist/Server/Services/HostService.js.map +1 -1
  337. package/build/dist/Server/Services/IncidentService.js +35 -24
  338. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  339. package/build/dist/Server/Services/Index.js +2 -0
  340. package/build/dist/Server/Services/Index.js.map +1 -1
  341. package/build/dist/Server/Services/MonitorService.js +45 -0
  342. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  343. package/build/dist/Server/Services/MonitorStatusService.js +129 -0
  344. package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
  345. package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
  346. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  347. package/build/dist/Server/Services/RumSessionPinService.js +7 -15
  348. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  349. package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
  350. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  351. package/build/dist/Server/Services/UserService.js +241 -10
  352. package/build/dist/Server/Services/UserService.js.map +1 -1
  353. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
  354. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
  356. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
  358. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
  360. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  361. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
  362. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  363. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
  364. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  365. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
  374. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  375. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
  377. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
  378. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
  379. package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
  380. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
  381. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
  382. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
  383. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
  384. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
  385. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
  386. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
  387. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
  388. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
  389. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
  390. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
  391. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
  392. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
  393. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
  394. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
  395. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
  396. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
  397. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
  398. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
  399. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
  400. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
  401. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
  402. package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
  403. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
  404. package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
  405. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
  407. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
  408. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
  409. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
  410. package/build/dist/Server/Utils/DataSource/Types.js +2 -0
  411. package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
  412. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
  413. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  414. package/build/dist/Server/Utils/InProcessMemo.js +113 -0
  415. package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
  416. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
  417. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
  418. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
  419. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  420. package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
  421. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  422. package/build/dist/Server/Utils/Response.js +9 -1
  423. package/build/dist/Server/Utils/Response.js.map +1 -1
  424. package/build/dist/Server/Utils/SSRFProtection.js +192 -0
  425. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
  426. package/build/dist/Server/Utils/StartServer.js +7 -0
  427. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  428. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
  429. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
  430. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
  431. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  432. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
  433. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
  434. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
  435. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  436. package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
  437. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  438. package/build/dist/Server/Utils/Telemetry.js +93 -6
  439. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  440. package/build/dist/Server/Utils/VendorAssets.js +121 -0
  441. package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
  442. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
  443. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  444. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
  445. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  446. package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
  447. package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
  448. package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
  449. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  450. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
  451. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
  452. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
  453. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
  454. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
  455. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
  456. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
  457. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
  458. package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
  459. package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
  460. package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
  461. package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
  462. package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
  463. package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
  464. package/build/dist/Types/DataSource/DataSourceType.js +183 -0
  465. package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
  466. package/build/dist/Types/Date.js +38 -3
  467. package/build/dist/Types/Date.js.map +1 -1
  468. package/build/dist/Types/Password.js +56 -0
  469. package/build/dist/Types/Password.js.map +1 -0
  470. package/build/dist/Types/Permission.js +42 -0
  471. package/build/dist/Types/Permission.js.map +1 -1
  472. package/build/dist/Types/UserAuthenticationStatus.js +2 -0
  473. package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
  474. package/build/dist/UI/Components/ErrorBoundary.js +388 -72
  475. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  476. package/build/dist/UI/Components/Icon/Icon.js +10 -4
  477. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  478. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  479. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  480. package/build/dist/UI/Components/Modal/Modal.js +178 -19
  481. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  482. package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
  483. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  484. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
  485. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  486. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
  487. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  488. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
  489. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
  490. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
  491. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
  492. package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
  493. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
  494. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
  495. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  496. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
  497. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  498. package/build/dist/UI/Utils/TestDataSource.js +39 -0
  499. package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
  500. package/build/dist/Utils/Analytics.js +4 -0
  501. package/build/dist/Utils/Analytics.js.map +1 -1
  502. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
  503. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
  504. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
  505. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
  506. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
  507. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
  508. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
  509. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
  510. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
  511. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
  512. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  513. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  514. package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
  515. package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
  516. package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
  517. package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
  518. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
  519. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
  520. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
  521. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  522. package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
  523. package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
  524. package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
  525. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
  526. package/jest.config.json +1 -0
  527. package/package.json +5 -1
  528. package/tsconfig.json +12 -10
@@ -74,6 +74,15 @@ jest.mock("../../../UI/Components/Markdown.tsx/MarkdownViewer", () => {
74
74
  };
75
75
  });
76
76
 
77
+ /*
78
+ * The feed owns the "will this draw any steps?" predicate, because several
79
+ * event types only close a step an earlier event opened. The panel asks it
80
+ * instead of counting raw events, so the mock has to answer too — and
81
+ * hasRenderableActivityMock lets a test make the two disagree, which is the
82
+ * case that used to render an empty framed box.
83
+ */
84
+ const hasRenderableActivityMock: MockFunction = getJestMockFunction();
85
+
77
86
  jest.mock(
78
87
  "../../../../App/FeatureSet/Dashboard/src/Components/AIChat/ChatActivityFeed",
79
88
  () => {
@@ -85,6 +94,9 @@ jest.mock(
85
94
  "data-testid": "investigation-activity",
86
95
  });
87
96
  },
97
+ hasRenderableActivity: (events: Array<AIRunEvent>): boolean => {
98
+ return hasRenderableActivityMock(events) as boolean;
99
+ },
88
100
  };
89
101
  },
90
102
  );
@@ -110,6 +122,7 @@ interface ActivityFeedProps {
110
122
  title?: string | undefined;
111
123
  showLiveIndicator?: boolean | undefined;
112
124
  maxVisibleSteps?: number | undefined;
125
+ hideChrome?: boolean | undefined;
113
126
  }
114
127
 
115
128
  interface InvestigationPayloadOptions {
@@ -117,6 +130,7 @@ interface InvestigationPayloadOptions {
117
130
  runId?: string | undefined;
118
131
  events?: JSONArray | undefined;
119
132
  analysisMarkdown?: string | null | undefined;
133
+ analysisTldr?: string | null | undefined;
120
134
  isAnalysisPending?: boolean | undefined;
121
135
  errorMessage?: string | null | undefined;
122
136
  toolCallCount?: number | undefined;
@@ -158,6 +172,8 @@ const ALERT_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
158
172
  const EVENT_ID: string = "55555555-5555-4555-8555-555555555555";
159
173
  const ANALYSIS: string =
160
174
  "## Root cause\n\nThe database connection pool was exhausted.";
175
+ const TLDR: string =
176
+ "Checkout is returning 500s because the database connection pool is exhausted.";
161
177
 
162
178
  const activityEvent: JSONObject = {
163
179
  _id: EVENT_ID,
@@ -191,6 +207,7 @@ function investigationPayload(
191
207
  run,
192
208
  events: options.events || [],
193
209
  analysisMarkdown: options.analysisMarkdown ?? null,
210
+ analysisTldr: options.analysisTldr ?? null,
194
211
  isAnalysisPending: options.isAnalysisPending === true,
195
212
  };
196
213
  }
@@ -205,6 +222,7 @@ function noInvestigationResponse(): ApiResponse {
205
222
  run: null,
206
223
  events: [],
207
224
  analysisMarkdown: null,
225
+ analysisTldr: null,
208
226
  isAnalysisPending: false,
209
227
  },
210
228
  };
@@ -320,6 +338,15 @@ beforeEach(() => {
320
338
  jest.useFakeTimers();
321
339
  jest.setSystemTime(new Date(COMPLETED_AT));
322
340
  getCommonHeadersMock.mockReturnValue({});
341
+ /*
342
+ * Default to the real component's behaviour for the ordinary event shapes
343
+ * these tests use: every step-opening event draws a step.
344
+ */
345
+ hasRenderableActivityMock.mockImplementation(
346
+ (events: Array<AIRunEvent>): boolean => {
347
+ return events.length > 0;
348
+ },
349
+ );
323
350
  getFriendlyMessageMock.mockImplementation((error: unknown): string => {
324
351
  if (
325
352
  typeof error === "object" &&
@@ -343,6 +370,7 @@ afterEach(() => {
343
370
  getCommonHeadersMock.mockReset();
344
371
  markdownViewerMock.mockReset();
345
372
  activityFeedMock.mockReset();
373
+ hasRenderableActivityMock.mockReset();
346
374
  });
347
375
 
348
376
  describe("InvestigationPanel report lifecycle", () => {
@@ -376,7 +404,12 @@ describe("InvestigationPanel report lifecycle", () => {
376
404
  expect(screen.getByText("Investigating…")).toBeInTheDocument();
377
405
  expect(screen.getByTestId("investigation-activity")).toBeInTheDocument();
378
406
  expect(lastActivityProps().events).toHaveLength(1);
379
- expect(lastActivityProps().showLiveIndicator).toBe(true);
407
+ /*
408
+ * The panel frames the feed itself, so the feed drops its own bubble and
409
+ * heading — the "Investigating…" wording must appear exactly once.
410
+ */
411
+ expect(lastActivityProps().hideChrome).toBe(true);
412
+ expect(screen.getAllByText("Investigating…")).toHaveLength(1);
380
413
  expect(
381
414
  document.querySelector('[class~="motion-safe:animate-ping"]'),
382
415
  ).not.toBeNull();
@@ -406,7 +439,7 @@ describe("InvestigationPanel report lifecycle", () => {
406
439
  expect(screen.getByText("Investigation activity")).toBeInTheDocument();
407
440
  expect(lastActivityProps()).toEqual(
408
441
  expect.objectContaining({
409
- title: "Completed activity",
442
+ hideChrome: true,
410
443
  showLiveIndicator: false,
411
444
  maxVisibleSteps: 10,
412
445
  }),
@@ -415,6 +448,9 @@ describe("InvestigationPanel report lifecycle", () => {
415
448
  const usage: HTMLElement = screen.getByLabelText("Investigation usage");
416
449
  expect(usage).toHaveTextContent("2 telemetry queries");
417
450
  expect(usage).toHaveTextContent("1,234 tokens");
451
+ expect(usage).toHaveTextContent(
452
+ "Read-only — nothing in your systems was changed",
453
+ );
418
454
  expect(fixButton()).toBeEnabled();
419
455
  expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
420
456
  expect(screen.getByRole("button", { name: "Rejected" })).toBeEnabled();
@@ -612,9 +648,15 @@ describe("InvestigationPanel report lifecycle", () => {
612
648
 
613
649
  expect(screen.getByText("Investigation did not finish")).toBeVisible();
614
650
  expect(screen.getByText("The model provider timed out.")).toBeVisible();
651
+ expect(
652
+ screen.getByText("The investigation stopped before it could report."),
653
+ ).toBeVisible();
654
+ expect(
655
+ screen.getByText("What the investigation got through"),
656
+ ).toBeVisible();
615
657
  expect(lastActivityProps()).toEqual(
616
658
  expect.objectContaining({
617
- title: "Investigation activity",
659
+ hideChrome: true,
618
660
  showLiveIndicator: false,
619
661
  }),
620
662
  );
@@ -637,6 +679,475 @@ describe("InvestigationPanel report lifecycle", () => {
637
679
  });
638
680
  });
639
681
 
682
+ /*
683
+ * Every state of the card has to stand on its own: a responder can land on it
684
+ * while the run is queued, live, failed, or finished. These tests pin the
685
+ * framing and the plain-language explanation each state owes the reader.
686
+ */
687
+ describe("InvestigationPanel card states", () => {
688
+ test("frames the live run and says what it is doing and that it cannot change anything", async () => {
689
+ postMock.mockResolvedValue(
690
+ successfulResponse(
691
+ investigationPayload({
692
+ status: AIRunStatus.Running,
693
+ events: [activityEvent],
694
+ }),
695
+ ) as never,
696
+ );
697
+
698
+ renderPanel();
699
+ await flush();
700
+
701
+ const live: HTMLElement = screen.getByLabelText("Live investigation");
702
+ expect(live).toHaveTextContent("OneUptime AI is investigating");
703
+ expect(live).toHaveTextContent("Read-only — nothing is changed");
704
+ expect(live).toContainElement(screen.getByTestId("investigation-activity"));
705
+ });
706
+
707
+ test("explains the wait while the run is only queued", async () => {
708
+ postMock.mockResolvedValue(
709
+ successfulResponse(
710
+ investigationPayload({ status: AIRunStatus.Queued }),
711
+ ) as never,
712
+ );
713
+
714
+ renderPanel();
715
+ await flush();
716
+
717
+ expect(screen.getByLabelText("Live investigation")).toHaveTextContent(
718
+ "Waiting for a worker to pick this up",
719
+ );
720
+ expect(screen.getByText("Starting investigation…")).toBeVisible();
721
+ });
722
+
723
+ test("puts a copy control on the report so it can be pasted elsewhere", async () => {
724
+ postMock.mockResolvedValue(completedResponse() as never);
725
+
726
+ renderPanel();
727
+ await flush();
728
+
729
+ const report: HTMLElement = screen.getByLabelText("Investigation report");
730
+ expect(report).toHaveTextContent("AI generated");
731
+ expect(report).toContainElement(
732
+ screen.getByRole("button", { name: "Copy report" }),
733
+ );
734
+ });
735
+
736
+ /*
737
+ * A queued run carries a stats object whose counts are all zero, so an
738
+ * ungated strip would tell the reader the AI ran zero queries and changed
739
+ * nothing — a past-tense report on work that has not started, directly
740
+ * under "waiting for a worker".
741
+ */
742
+ test.each([AIRunStatus.Running, AIRunStatus.Queued])(
743
+ "shows no usage strip while a %s run has not produced anything yet",
744
+ async (status: AIRunStatus) => {
745
+ postMock.mockResolvedValue(
746
+ successfulResponse(
747
+ investigationPayload({
748
+ status,
749
+ toolCallCount: 0,
750
+ totalTokens: 0,
751
+ }),
752
+ ) as never,
753
+ );
754
+
755
+ renderPanel();
756
+ await flush();
757
+
758
+ expect(screen.queryByLabelText("Investigation usage")).toBeNull();
759
+ expect(
760
+ screen.queryByText(/nothing in your systems was changed/),
761
+ ).toBeNull();
762
+ },
763
+ );
764
+
765
+ /*
766
+ * Events and rendered steps are not the same thing: RunFailed and the
767
+ * completion halves of tool/LLM calls only close a step an earlier event
768
+ * opened. A run whose RunStarted failed to persist and then failed outright
769
+ * carries one event and draws nothing, and counting raw events would frame
770
+ * an empty panel instead of saying what happened.
771
+ */
772
+ test("explains an empty trail instead of framing a blank panel", async () => {
773
+ hasRenderableActivityMock.mockReturnValue(false);
774
+ postMock.mockResolvedValue(
775
+ successfulResponse(
776
+ investigationPayload({
777
+ status: AIRunStatus.Error,
778
+ errorMessage: "The provider timed out.",
779
+ events: [activityEvent],
780
+ }),
781
+ ) as never,
782
+ );
783
+
784
+ renderPanel();
785
+ await flush();
786
+
787
+ expect(screen.queryByTestId("investigation-activity")).toBeNull();
788
+ expect(
789
+ screen.getByText("No investigation steps were recorded."),
790
+ ).toBeVisible();
791
+ });
792
+
793
+ test("hides the completed activity disclosure when no step would render", async () => {
794
+ hasRenderableActivityMock.mockReturnValue(false);
795
+ postMock.mockResolvedValue(completedResponse() as never);
796
+
797
+ renderPanel();
798
+ await flush();
799
+
800
+ expect(screen.getByLabelText("Investigation report")).toBeInTheDocument();
801
+ expect(screen.queryByText("Investigation activity")).toBeNull();
802
+ });
803
+
804
+ test("reports a single query without pluralising it", async () => {
805
+ postMock.mockResolvedValue(
806
+ completedResponse({ toolCallCount: 1, totalTokens: 0 }) as never,
807
+ );
808
+
809
+ renderPanel();
810
+ await flush();
811
+
812
+ const usage: HTMLElement = screen.getByLabelText("Investigation usage");
813
+ expect(usage).toHaveTextContent("1 telemetry query");
814
+ expect(usage).not.toHaveTextContent("tokens");
815
+ });
816
+ });
817
+
818
+ /*
819
+ * The TL;DR is the first thing on the card, and it is AI prose about the
820
+ * report below it. So it must never appear without that report, must never be
821
+ * rendered as markdown, and must be dropped the instant the panel changes
822
+ * subject — a summary of the previous incident is worse than no summary.
823
+ */
824
+ describe("InvestigationPanel TL;DR", () => {
825
+ function markdownTexts(): Array<string> {
826
+ return (
827
+ markdownViewerMock.mock.calls as Array<Array<MarkdownViewerProps>>
828
+ ).map((call: Array<MarkdownViewerProps>): string => {
829
+ return call[0]!.text;
830
+ });
831
+ }
832
+
833
+ test("leads the completed card with the AI summary, as plain text above the report", async () => {
834
+ postMock.mockResolvedValue(
835
+ completedResponse({ analysisTldr: TLDR }) as never,
836
+ );
837
+
838
+ renderPanel();
839
+ await flush();
840
+
841
+ const summary: HTMLElement = screen.getByLabelText("Investigation summary");
842
+ expect(summary).toHaveTextContent("TL;DR");
843
+ expect(summary).toHaveTextContent(TLDR);
844
+
845
+ // The summary is never routed through the markdown renderer.
846
+ expect(markdownTexts().length).toBeGreaterThan(0);
847
+ expect(
848
+ markdownTexts().every((text: string): boolean => {
849
+ return text === ANALYSIS;
850
+ }),
851
+ ).toBe(true);
852
+
853
+ // It sits above the report it summarizes.
854
+ const report: HTMLElement = screen.getByLabelText("Investigation report");
855
+ expect(
856
+ summary.compareDocumentPosition(report) &
857
+ Node.DOCUMENT_POSITION_FOLLOWING,
858
+ ).toBeTruthy();
859
+ });
860
+
861
+ test("omits the block for a run that has no stored summary", async () => {
862
+ postMock.mockResolvedValue(completedResponse() as never);
863
+
864
+ renderPanel();
865
+ await flush();
866
+
867
+ expect(screen.getByLabelText("Investigation report")).toBeInTheDocument();
868
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
869
+ expect(screen.queryByText("TL;DR")).toBeNull();
870
+ });
871
+
872
+ test("omits a blank summary rather than rendering an empty banner", async () => {
873
+ postMock.mockResolvedValue(
874
+ completedResponse({ analysisTldr: " \n " }) as never,
875
+ );
876
+
877
+ renderPanel();
878
+ await flush();
879
+
880
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
881
+ });
882
+
883
+ test("never shows a summary before the report it describes is published", async () => {
884
+ postMock.mockResolvedValue(
885
+ completedResponse({
886
+ analysisMarkdown: null,
887
+ analysisTldr: TLDR,
888
+ isAnalysisPending: true,
889
+ }) as never,
890
+ );
891
+
892
+ renderPanel();
893
+ await flush();
894
+
895
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
896
+ expect(screen.queryByText(TLDR)).toBeNull();
897
+ expect(screen.getByText("Preparing the final report")).toBeVisible();
898
+ });
899
+
900
+ test("appears on the poll that publishes the report", async () => {
901
+ postMock
902
+ .mockResolvedValueOnce(
903
+ completedResponse({
904
+ analysisMarkdown: null,
905
+ analysisTldr: null,
906
+ isAnalysisPending: true,
907
+ }) as never,
908
+ )
909
+ .mockResolvedValue(completedResponse({ analysisTldr: TLDR }) as never);
910
+
911
+ renderPanel();
912
+ await flush();
913
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
914
+
915
+ await advanceFastPolls();
916
+
917
+ expect(screen.getByLabelText("Investigation summary")).toHaveTextContent(
918
+ TLDR,
919
+ );
920
+ });
921
+
922
+ test("is not shown for a run that never completed", async () => {
923
+ postMock.mockResolvedValue(
924
+ successfulResponse(
925
+ investigationPayload({
926
+ status: AIRunStatus.Error,
927
+ analysisTldr: TLDR,
928
+ errorMessage: "The provider timed out.",
929
+ }),
930
+ ) as never,
931
+ );
932
+
933
+ renderPanel();
934
+ await flush();
935
+
936
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
937
+ expect(screen.getByText("The provider timed out.")).toBeVisible();
938
+ });
939
+
940
+ /*
941
+ * The report is recomputed from the feed on every poll, so it can vanish
942
+ * (a deleted feed item) while the run stays Completed. The summary must go
943
+ * with it — a summary of a report the reader cannot see is worse than none.
944
+ * Cadence matters: a settled Recommended run polls at the SETTLED interval,
945
+ * so advancing by the fast interval would make this pass vacuously.
946
+ */
947
+ test("drops the summary if the report it describes disappears on a later poll", async () => {
948
+ postMock
949
+ .mockResolvedValueOnce(completedResponse({ analysisTldr: TLDR }) as never)
950
+ .mockResolvedValue(
951
+ completedResponse({
952
+ analysisMarkdown: null,
953
+ analysisTldr: TLDR,
954
+ }) as never,
955
+ );
956
+
957
+ renderPanel();
958
+ await flush();
959
+ expect(screen.getByLabelText("Investigation summary")).toHaveTextContent(
960
+ TLDR,
961
+ );
962
+
963
+ await tick(SETTLED_POLL_INTERVAL_MS);
964
+
965
+ expect(postMock).toHaveBeenCalledTimes(2);
966
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
967
+ expect(screen.queryByText(TLDR)).toBeNull();
968
+ });
969
+
970
+ /*
971
+ * "Never attributed to the wrong run" — the same subject can be
972
+ * re-investigated, and the previous run's summary must not survive onto the
973
+ * new run's report.
974
+ */
975
+ test("does not carry a summary over to a new run on the same subject", async () => {
976
+ const nextAnalysis: string = "## Root cause\n\nA second, different cause.";
977
+ postMock
978
+ .mockResolvedValueOnce(completedResponse({ analysisTldr: TLDR }) as never)
979
+ .mockResolvedValue(
980
+ completedResponse({
981
+ runId: NEXT_RUN_ID,
982
+ analysisMarkdown: nextAnalysis,
983
+ analysisTldr: null,
984
+ }) as never,
985
+ );
986
+
987
+ renderPanel();
988
+ await flush();
989
+ expect(screen.getByLabelText("Investigation summary")).toBeInTheDocument();
990
+
991
+ await tick(SETTLED_POLL_INTERVAL_MS);
992
+
993
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
994
+ expect(screen.queryByText(TLDR)).toBeNull();
995
+ expect(screen.getByTestId("investigation-markdown")).toHaveTextContent(
996
+ "A second, different cause.",
997
+ );
998
+ });
999
+
1000
+ /*
1001
+ * The module's threat model is "the worst a prompt injection achieves is a
1002
+ * misleading sentence". That holds only while the summary is rendered as
1003
+ * inert text — never as markdown, never as HTML.
1004
+ */
1005
+ test("renders hostile summary content inertly, as text", async () => {
1006
+ const hostile: string =
1007
+ '<img src=x onerror="window.__pwned = true"> **bold** [link](https://evil.example)';
1008
+ postMock.mockResolvedValue(
1009
+ completedResponse({ analysisTldr: hostile }) as never,
1010
+ );
1011
+
1012
+ renderPanel();
1013
+ await flush();
1014
+
1015
+ const summary: HTMLElement = screen.getByLabelText("Investigation summary");
1016
+ expect(summary).toHaveTextContent(hostile);
1017
+ expect(summary.querySelector("img")).toBeNull();
1018
+ expect(summary.querySelector("a")).toBeNull();
1019
+ expect(
1020
+ (window as unknown as { __pwned?: boolean }).__pwned,
1021
+ ).toBeUndefined();
1022
+ // The summary never reaches the markdown renderer.
1023
+ expect(
1024
+ markdownTexts().every((text: string): boolean => {
1025
+ return text === ANALYSIS;
1026
+ }),
1027
+ ).toBe(true);
1028
+ });
1029
+
1030
+ test("drops the previous subject's summary the moment the subject changes", async () => {
1031
+ const nextSubject: Deferred<ApiResponse> = createDeferred<ApiResponse>();
1032
+ postMock
1033
+ .mockResolvedValueOnce(completedResponse({ analysisTldr: TLDR }) as never)
1034
+ .mockReturnValueOnce(nextSubject.promise as never);
1035
+
1036
+ const view: ReturnType<typeof render> = renderPanel();
1037
+ await flush();
1038
+ expect(screen.getByLabelText("Investigation summary")).toBeInTheDocument();
1039
+
1040
+ view.rerender(
1041
+ <InvestigationPanel subjectType="alert" subjectId={ALERT_ID} />,
1042
+ );
1043
+ await flush();
1044
+
1045
+ expect(screen.queryByLabelText("Investigation summary")).toBeNull();
1046
+
1047
+ await resolveDeferred(
1048
+ nextSubject,
1049
+ completedResponse({
1050
+ runId: NEXT_RUN_ID,
1051
+ analysisTldr: "The alert cleared on its own after the pod restarted.",
1052
+ }),
1053
+ );
1054
+
1055
+ expect(screen.getByLabelText("Investigation summary")).toHaveTextContent(
1056
+ "The alert cleared on its own after the pod restarted.",
1057
+ );
1058
+ });
1059
+ });
1060
+
1061
+ /*
1062
+ * The verdict prompt is a single question with two answers, so both choices
1063
+ * live in one labelled group; once answered it collapses to the recorded
1064
+ * verdict plus a way back. These tests pin that shape — the earlier suites
1065
+ * cover the request/optimistic-state contract behind it.
1066
+ */
1067
+ describe("InvestigationPanel verdict control", () => {
1068
+ function verdictGroup(): HTMLElement | null {
1069
+ return screen.queryByRole("group", { name: "Rate this investigation" });
1070
+ }
1071
+
1072
+ test("offers both verdicts inside one labelled group", async () => {
1073
+ postMock.mockResolvedValue(completedResponse() as never);
1074
+
1075
+ renderPanel();
1076
+ await flush();
1077
+
1078
+ const group: HTMLElement = verdictGroup()!;
1079
+ expect(group).toBeInTheDocument();
1080
+ expect(
1081
+ screen.getByRole("button", { name: "Confirmed" }),
1082
+ ).toBeInTheDocument();
1083
+ expect(
1084
+ screen.getByRole("button", { name: "Rejected" }),
1085
+ ).toBeInTheDocument();
1086
+ expect(group).toContainElement(
1087
+ screen.getByRole("button", { name: "Confirmed" }),
1088
+ );
1089
+ expect(group).toContainElement(
1090
+ screen.getByRole("button", { name: "Rejected" }),
1091
+ );
1092
+ });
1093
+
1094
+ test("collapses to the recorded verdict and back again through Change", async () => {
1095
+ postMock
1096
+ .mockResolvedValueOnce(completedResponse() as never)
1097
+ .mockResolvedValueOnce(successfulResponse({}) as never);
1098
+
1099
+ renderPanel();
1100
+ await flush();
1101
+ fireEvent.click(screen.getByRole("button", { name: "Rejected" }));
1102
+ await flush();
1103
+
1104
+ expect(verdictGroup()).toBeNull();
1105
+ expect(screen.getByText(/You rejected this analysis/)).toBeVisible();
1106
+
1107
+ fireEvent.click(screen.getByRole("button", { name: "Change" }));
1108
+
1109
+ expect(verdictGroup()).toBeInTheDocument();
1110
+ expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
1111
+ expect(screen.getByRole("button", { name: "Rejected" })).toBeEnabled();
1112
+ // Reopening the prompt must not itself save anything.
1113
+ expect(postMock).toHaveBeenCalledTimes(2);
1114
+ });
1115
+
1116
+ test("locks both choices while a verdict is saving", async () => {
1117
+ const save: Deferred<ApiResponse> = createDeferred<ApiResponse>();
1118
+ postMock
1119
+ .mockResolvedValueOnce(completedResponse() as never)
1120
+ .mockReturnValueOnce(save.promise as never);
1121
+
1122
+ renderPanel();
1123
+ await flush();
1124
+ fireEvent.click(screen.getByRole("button", { name: "Confirmed" }));
1125
+ await flush();
1126
+
1127
+ // Optimistic: the pill replaces the prompt immediately.
1128
+ expect(screen.getByText(/You confirmed this analysis/)).toBeVisible();
1129
+
1130
+ fireEvent.click(screen.getByRole("button", { name: "Change" }));
1131
+ expect(screen.getByRole("button", { name: "Confirmed" })).toBeDisabled();
1132
+ expect(screen.getByRole("button", { name: "Rejected" })).toBeDisabled();
1133
+
1134
+ await resolveDeferred(save, successfulResponse({}));
1135
+
1136
+ expect(screen.getByRole("button", { name: "Confirmed" })).toBeEnabled();
1137
+ });
1138
+
1139
+ test("shows the run status as a badge in the card header", async () => {
1140
+ postMock.mockResolvedValue(completedResponse() as never);
1141
+
1142
+ renderPanel();
1143
+ await flush();
1144
+
1145
+ expect(screen.getByLabelText("Investigation status")).toHaveTextContent(
1146
+ "Investigation complete",
1147
+ );
1148
+ });
1149
+ });
1150
+
640
1151
  describe("InvestigationPanel code-fix recommendation", () => {
641
1152
  test("shows the fix action only for an explicit Recommended decision", async () => {
642
1153
  postMock.mockResolvedValue(completedResponse() as never);