@oneuptime/common 13.0.4 → 13.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 (1589) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +81 -1
  2. package/Models/AnalyticsModels/SecurityEvent.ts +4 -4
  3. package/Models/DatabaseModels/Alert.ts +62 -0
  4. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  5. package/Models/DatabaseModels/Incident.ts +66 -0
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +74 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +74 -0
  8. package/Models/DatabaseModels/Index.ts +10 -4
  9. package/Models/DatabaseModels/NetworkDevice.ts +67 -0
  10. package/Models/DatabaseModels/NetworkDeviceDiagnostic.ts +746 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +151 -0
  12. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +1 -1
  13. package/Models/DatabaseModels/Project.ts +41 -0
  14. package/Models/DatabaseModels/RumApplication.ts +1 -1
  15. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +74 -0
  16. package/Models/DatabaseModels/{GoogleSecOpsConnection.ts → SecurityEventConnection.ts} +61 -51
  17. package/Models/DatabaseModels/{GoogleSecOpsConnectionRun.ts → SecurityEventConnectionRun.ts} +24 -24
  18. package/Models/DatabaseModels/ServiceLevelObjective.ts +185 -8
  19. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +746 -43
  20. package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +575 -0
  21. package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +582 -0
  22. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +16 -0
  23. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +16 -0
  24. package/Models/DatabaseModels/StatusPageAnnouncement.ts +75 -0
  25. package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
  26. package/Models/DatabaseModels/ThreatIntelFeed.ts +1 -1
  27. package/Server/API/AIInvestigationAPI.ts +484 -24
  28. package/Server/API/BaseAPI.ts +17 -0
  29. package/Server/API/BillingInvoiceAPI.ts +343 -30
  30. package/Server/API/BillingPaymentMethodAPI.ts +126 -5
  31. package/Server/API/DashboardAPI.ts +96 -2
  32. package/Server/API/SecurityEventConnectionAPI.ts +380 -0
  33. package/Server/API/StatusPageAPI.ts +308 -199
  34. package/Server/API/TelemetryAPI.ts +402 -265
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.ts +83 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.ts +36 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.ts +29 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.ts +516 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.ts +98 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.ts +27 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.ts +97 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
  44. package/Server/Middleware/TelemetryIngest.ts +101 -6
  45. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +138 -67
  46. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +213 -84
  47. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +112 -35
  48. package/Server/Services/AlertLabelRuleEngineService.ts +299 -217
  49. package/Server/Services/AlertOwnerRuleEngineService.ts +572 -396
  50. package/Server/Services/AlertPrivacyRuleEngineService.ts +116 -40
  51. package/Server/Services/AlertService.ts +111 -4
  52. package/Server/Services/AuditLogService.ts +612 -59
  53. package/Server/Services/BillingInvoiceService.ts +112 -102
  54. package/Server/Services/BillingService.ts +539 -11
  55. package/Server/Services/CephClusterLabelRuleEngineService.ts +170 -109
  56. package/Server/Services/CephClusterOwnerRuleEngineService.ts +233 -115
  57. package/Server/Services/CloudResourceLabelRuleEngineService.ts +163 -100
  58. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +236 -115
  59. package/Server/Services/DashboardLabelRuleEngineService.ts +145 -84
  60. package/Server/Services/DashboardOwnerRuleEngineService.ts +213 -95
  61. package/Server/Services/DatabaseService.ts +171 -21
  62. package/Server/Services/DockerHostLabelRuleEngineService.ts +171 -110
  63. package/Server/Services/DockerHostOwnerRuleEngineService.ts +233 -115
  64. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +181 -112
  65. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +243 -118
  66. package/Server/Services/ExceptionAggregationService.ts +7 -16
  67. package/Server/Services/HostLabelRuleEngineService.ts +167 -106
  68. package/Server/Services/HostOwnerRuleEngineService.ts +229 -111
  69. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +141 -67
  70. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +272 -72
  71. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +112 -35
  72. package/Server/Services/IncidentEpisodePublicNoteService.ts +24 -0
  73. package/Server/Services/IncidentLabelRuleEngineService.ts +279 -204
  74. package/Server/Services/IncidentOwnerRuleEngineService.ts +595 -425
  75. package/Server/Services/IncidentPrivacyRuleEngineService.ts +117 -44
  76. package/Server/Services/IncidentPublicNoteService.ts +24 -0
  77. package/Server/Services/IncidentService.ts +114 -3
  78. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +147 -83
  79. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +221 -100
  80. package/Server/Services/Index.ts +10 -4
  81. package/Server/Services/InventoryItemService.ts +28 -0
  82. package/Server/Services/IoTFleetLabelRuleEngineService.ts +145 -84
  83. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +213 -95
  84. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +181 -112
  85. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +243 -118
  86. package/Server/Services/LabelService.ts +23 -28
  87. package/Server/Services/LogAggregationService.ts +17 -23
  88. package/Server/Services/MetricAggregationService.ts +4 -14
  89. package/Server/Services/MonitorLabelRuleEngineService.ts +152 -92
  90. package/Server/Services/MonitorOwnerRuleEngineService.ts +220 -104
  91. package/Server/Services/MonitorProbeService.ts +20 -2
  92. package/Server/Services/MonitorService.ts +11 -9
  93. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +376 -5
  94. package/Server/Services/NetworkDeviceDiagnosticService.ts +417 -0
  95. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +147 -83
  96. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +218 -97
  97. package/Server/Services/NetworkDeviceService.ts +39 -2
  98. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +151 -80
  99. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +222 -97
  100. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +154 -83
  101. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +225 -100
  102. package/Server/Services/PodmanHostLabelRuleEngineService.ts +171 -110
  103. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +235 -115
  104. package/Server/Services/ProjectService.ts +111 -10
  105. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +174 -110
  106. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +239 -116
  107. package/Server/Services/RumApplicationLabelRuleEngineService.ts +137 -73
  108. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +200 -83
  109. package/Server/Services/RunbookLabelRuleEngineService.ts +146 -84
  110. package/Server/Services/RunbookOwnerRuleEngineService.ts +216 -95
  111. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +324 -230
  112. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +613 -428
  113. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +24 -0
  114. package/Server/Services/ScheduledMaintenanceService.ts +43 -14
  115. package/Server/Services/{GoogleSecOpsConnectionRunService.ts → SecurityEventConnectionRunService.ts} +1 -1
  116. package/Server/Services/SecurityEventConnectionService.ts +590 -0
  117. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +143 -74
  118. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +206 -85
  119. package/Server/Services/ServiceLabelRuleEngineService.ts +172 -110
  120. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +1057 -18
  121. package/Server/Services/ServiceLevelObjectiveFeedService.ts +108 -0
  122. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +793 -97
  123. package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +1069 -0
  124. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +240 -1
  125. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +257 -1
  126. package/Server/Services/ServiceLevelObjectiveService.ts +1356 -56
  127. package/Server/Services/ServiceOwnerRuleEngineService.ts +238 -116
  128. package/Server/Services/StatusPageAnnouncementService.ts +13 -0
  129. package/Server/Services/StatusPageLabelRuleEngineService.ts +146 -85
  130. package/Server/Services/StatusPageOwnerRuleEngineService.ts +210 -99
  131. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +28 -232
  132. package/Server/Services/StatusPageSubscriberService.ts +6 -0
  133. package/Server/Services/TelemetryUsageBillingService.ts +38 -7
  134. package/Server/Services/ThreatIntelFeedService.ts +1 -1
  135. package/Server/Services/TraceAggregationService.ts +77 -28
  136. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +173 -110
  137. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +238 -116
  138. package/Server/Services/WorkflowLabelRuleEngineService.ts +145 -84
  139. package/Server/Services/WorkflowOwnerRuleEngineService.ts +215 -95
  140. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
  141. package/Server/Types/Database/UpdateByID.ts +3 -0
  142. package/Server/Types/Database/UpdateOneBy.ts +7 -0
  143. package/Server/Utils/AI/AlertAIContextBuilder.ts +19 -0
  144. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
  145. package/Server/Utils/AI/IncidentAIContextBuilder.ts +39 -0
  146. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
  147. package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
  148. package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
  149. package/Server/Utils/AI/Toolbox/AlertTools.ts +37 -1
  150. package/Server/Utils/AI/Toolbox/IncidentTools.ts +22 -1
  151. package/Server/Utils/AI/Toolbox/Index.ts +38 -0
  152. package/Server/Utils/AI/Toolbox/SloTools.ts +416 -51
  153. package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
  154. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
  155. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +151 -13
  156. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +17 -4
  157. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +155 -8
  158. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +16 -0
  159. package/Server/Utils/Database/RelationValueUtil.ts +106 -0
  160. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +6 -1
  161. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +22 -27
  162. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
  163. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +3 -1
  164. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +50 -20
  165. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +13 -1
  166. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +6 -11
  167. package/Server/Utils/Rules/MonitorRulePatternValidator.ts +51 -0
  168. package/Server/Utils/Rules/OwnerRuleAssignment.ts +110 -0
  169. package/Server/Utils/Rules/RuleRun/RuleApplication.ts +81 -0
  170. package/Server/Utils/Rules/RuleRun/RuleRunPermission.ts +188 -0
  171. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +803 -0
  172. package/Server/Utils/Rules/RuleRun/RuleRunner.ts +341 -0
  173. package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +3 -2
  174. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
  175. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
  176. package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +497 -0
  177. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
  178. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
  179. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
  180. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
  181. package/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.ts +609 -74
  182. package/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.ts +2101 -0
  183. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
  184. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
  185. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
  186. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
  187. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
  188. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
  189. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1182 -0
  190. package/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.ts → Connectors/SecurityEventConnectionRunExecutor.ts} +165 -76
  191. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +306 -0
  192. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +55 -0
  193. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
  194. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
  195. package/Server/Utils/SecurityEvent/Connectors/Types.ts +431 -0
  196. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +1 -1
  197. package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
  198. package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +2 -2
  199. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +902 -40
  200. package/Server/Utils/Slo/SloFeedUtil.ts +200 -0
  201. package/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.ts +173 -0
  202. package/Server/Utils/Slo/SloMetricUtil.ts +327 -0
  203. package/Server/Utils/Slo/SloOwnerReferenceValidator.ts +208 -0
  204. package/Server/Utils/Slo/SloRecordReferenceValidator.ts +169 -0
  205. package/Server/Utils/StartServer.ts +10 -0
  206. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +6 -43
  207. package/Server/Utils/StatusPageResource.ts +50 -5
  208. package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
  209. package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
  210. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
  211. package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
  212. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
  213. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
  214. package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
  215. package/Server/Utils/Telemetry.ts +18 -0
  216. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +1063 -1
  217. package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
  218. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +4 -1
  219. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
  220. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +307 -0
  221. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
  222. package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +289 -0
  223. package/Tests/App/Dashboard/AuditLogsTable.test.tsx +598 -0
  224. package/Tests/App/Dashboard/BillingDefaultPaymentMethod.test.tsx +1046 -0
  225. package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +3 -0
  226. package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +201 -7
  227. package/Tests/App/Dashboard/BooleanSeriesCriteriaFilterText.test.ts +82 -0
  228. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +16 -1
  229. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +943 -0
  230. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +168 -1
  231. package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
  232. package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
  233. package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +755 -0
  234. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +1095 -1
  235. package/Tests/App/Dashboard/CorrelateFilterChips.test.tsx +910 -0
  236. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +3747 -25
  237. package/Tests/App/Dashboard/CorrelateGraphHelpers.test.ts +1085 -0
  238. package/Tests/App/Dashboard/CorrelateInspector.test.tsx +1534 -0
  239. package/Tests/App/Dashboard/CorrelateNodeCard.test.tsx +965 -0
  240. package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +1525 -0
  241. package/Tests/App/Dashboard/CorrelationGraph.test.ts +1030 -0
  242. package/Tests/App/Dashboard/CorrelationGraphLayout.test.ts +526 -0
  243. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
  244. package/Tests/App/Dashboard/DeviceDiagnostics.test.tsx +787 -0
  245. package/Tests/App/Dashboard/DeviceLatencyTrend.test.tsx +278 -0
  246. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +279 -0
  247. package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +87 -0
  248. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +443 -8
  249. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
  250. package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +340 -0
  251. package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
  252. package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
  253. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2450 -0
  254. package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
  255. package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
  256. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
  257. package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
  258. package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
  259. package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
  260. package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
  261. package/Tests/App/Dashboard/ExceptionSegmentedControl.test.tsx +1020 -0
  262. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
  263. package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
  264. package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
  265. package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
  266. package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
  267. package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
  268. package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
  269. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
  270. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
  271. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
  272. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1472 -0
  273. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
  274. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1931 -25
  275. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +159 -2
  276. package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
  277. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1398 -0
  278. package/Tests/App/Dashboard/InvestigationRunDetails.test.tsx +1166 -0
  279. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +437 -0
  280. package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
  281. package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
  282. package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
  283. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
  284. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +65 -0
  285. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +5 -0
  286. package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
  287. package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
  288. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
  289. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +74 -0
  290. package/Tests/App/Dashboard/ResourceFeed.test.tsx +125 -5
  291. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  292. package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
  293. package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
  294. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
  295. package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
  296. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
  297. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
  298. package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +1764 -0
  299. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1958 -0
  300. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +448 -0
  301. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +1455 -0
  302. package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +233 -0
  303. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +282 -0
  304. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
  305. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
  306. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
  307. package/Tests/App/Dashboard/SloActiveBurnEventsCard.test.tsx +538 -0
  308. package/Tests/App/Dashboard/SloBulkActionsArchive.test.tsx +252 -0
  309. package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +322 -518
  310. package/Tests/App/Dashboard/SloElement.test.tsx +194 -0
  311. package/Tests/App/Dashboard/SloFeed.test.tsx +289 -0
  312. package/Tests/App/Dashboard/SloHistoryCharts.test.tsx +471 -0
  313. package/Tests/App/Dashboard/SloHistorySeries.test.tsx +607 -0
  314. package/Tests/App/Dashboard/SloListWidget.test.tsx +783 -0
  315. package/Tests/App/Dashboard/SloMetricsPage.test.tsx +346 -0
  316. package/Tests/App/Dashboard/SloMonitorsPage.test.tsx +661 -0
  317. package/Tests/App/Dashboard/SloMonitorsSummaryCard.test.tsx +489 -0
  318. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +437 -0
  319. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +305 -0
  320. package/Tests/App/Dashboard/SloOverviewData.test.tsx +563 -0
  321. package/Tests/App/Dashboard/SloOverviewHero.test.tsx +311 -0
  322. package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +426 -0
  323. package/Tests/App/Dashboard/SloOverviewSidebarCards.test.tsx +493 -0
  324. package/Tests/App/Dashboard/SloSettings.test.tsx +633 -0
  325. package/Tests/App/Dashboard/SloStatusSummaryCards.test.tsx +403 -0
  326. package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +373 -0
  327. package/Tests/App/Dashboard/SloWidgetVariableBinding.test.tsx +689 -0
  328. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
  329. package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
  330. package/Tests/App/Dashboard/TopologyConnectivitySection.test.tsx +206 -0
  331. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
  332. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
  333. package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
  334. package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
  335. package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
  336. package/Tests/App/Dashboard/TracesEntityNames.test.tsx +617 -0
  337. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
  338. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +1312 -0
  339. package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
  340. package/Tests/App/Dashboard/WidgetCatalog.test.ts +9 -1
  341. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +14 -16
  342. package/Tests/Models/DatabaseModels/AuditLogModelConfiguration.test.ts +442 -0
  343. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +13 -7
  344. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +48 -1
  345. package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +835 -0
  346. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +3 -2
  347. package/Tests/Models/DiscoveryScanNetbiosLookupColumn.test.ts +328 -0
  348. package/Tests/Models/DiscoveryScanShortDeviceNamesColumn.test.ts +335 -0
  349. package/Tests/Models/InventoryItemNaming.test.ts +132 -16
  350. package/Tests/Models/NetworkDeviceDiagnosticContract.test.ts +194 -0
  351. package/Tests/Models/NetworkDeviceDnsNameColumn.test.ts +321 -0
  352. package/Tests/Models/ProjectDataResidencyColumn.test.ts +154 -0
  353. package/Tests/Models/SecurityDomainAccessControl.test.ts +197 -22
  354. package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
  355. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
  356. package/Tests/Server/API/BaseAPI.test.ts +6 -0
  357. package/Tests/Server/API/BaseAPIUpdateMiscDataProps.test.ts +217 -0
  358. package/Tests/Server/API/BillingInvoiceAPI.test.ts +7 -0
  359. package/Tests/Server/API/BillingInvoiceAPIPaymentStates.test.ts +990 -0
  360. package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +498 -0
  361. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +405 -0
  362. package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +1750 -0
  363. package/Tests/Server/API/SessionReplayAPI.test.ts +644 -1
  364. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +857 -0
  365. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +1084 -0
  366. package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
  367. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
  368. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +33 -3
  369. package/Tests/Server/Infrastructure/Postgres/AddDataResidencyToProjectMigration.test.ts +202 -0
  370. package/Tests/Server/Infrastructure/Postgres/AddNetbiosLookupToNetworkDeviceDiscoveryScanMigration.test.ts +330 -0
  371. package/Tests/Server/Infrastructure/Postgres/AddNetworkDeviceDnsNameAndShortDeviceNamesMigration.test.ts +340 -0
  372. package/Tests/Server/Infrastructure/Postgres/BackfillSloMonitorRulesAndAffectedResourcesMigration.test.ts +343 -0
  373. package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +801 -0
  374. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
  375. package/Tests/Server/Services/AddSubscriberUpdateNotificationStatusMigration.test.ts +307 -0
  376. package/Tests/Server/Services/AuditLogService.test.ts +1124 -0
  377. package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +200 -1
  378. package/Tests/Server/Services/BillingInvoiceServiceMutexRelease.test.ts +254 -0
  379. package/Tests/Server/Services/BillingService.test.ts +70 -0
  380. package/Tests/Server/Services/BillingServicePayInvoiceStates.test.ts +723 -0
  381. package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +14 -2
  382. package/Tests/Server/Services/BillingServiceSubscriptionPaymentMethodSync.test.ts +1634 -0
  383. package/Tests/Server/Services/DatabaseServiceAuditRelationDiff.test.ts +492 -0
  384. package/Tests/Server/Services/DatabaseServicePasswordFieldSecrets.test.ts +629 -0
  385. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +431 -0
  386. package/Tests/Server/Services/IncidentAlertSloReferenceGuard.test.ts +358 -0
  387. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
  388. package/Tests/Server/Services/MonitorProbeServicePastDueMonitoring.test.ts +362 -0
  389. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1460 -1
  390. package/Tests/Server/Services/NetworkDeviceDiagnosticService.test.ts +962 -0
  391. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +106 -0
  392. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +10 -1
  393. package/Tests/Server/Services/NetworkDeviceServicePastDueMonitoring.test.ts +335 -0
  394. package/Tests/Server/Services/NetworkDeviceSiteRuleDnsName.test.ts +568 -0
  395. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  396. package/Tests/Server/Services/ProjectDataResidencyPostgres.test.ts +344 -0
  397. package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +187 -0
  398. package/Tests/Server/Services/ProjectServiceDataResidency.test.ts +369 -0
  399. package/Tests/Server/Services/ProjectServiceDataResidencySelfHosted.test.ts +176 -0
  400. package/Tests/Server/Services/ProjectServicePastDueMonitoring.test.ts +289 -0
  401. package/Tests/Server/Services/ResourceFeedServices.test.ts +24 -8
  402. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +1396 -0
  403. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupARun.test.ts +917 -0
  404. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +1262 -0
  405. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +902 -0
  406. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +1163 -0
  407. package/Tests/Server/Services/RuleRun/PrivacyRuleEnginesRun.test.ts +843 -0
  408. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +465 -0
  409. package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1754 -0
  410. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +77 -23
  411. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleFeedWrites.test.ts +777 -0
  412. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleOptions.test.ts +1399 -0
  413. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +67 -74
  414. package/Tests/Server/Services/ServiceLevelObjectiveChildRowTenancy.test.ts +906 -0
  415. package/Tests/Server/Services/ServiceLevelObjectiveDeleteTenancy.test.ts +1029 -0
  416. package/Tests/Server/Services/ServiceLevelObjectiveFeedService.test.ts +313 -0
  417. package/Tests/Server/Services/ServiceLevelObjectiveFeedWrites.test.ts +1214 -0
  418. package/Tests/Server/Services/ServiceLevelObjectiveMarkdownLink.test.ts +289 -0
  419. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +1455 -430
  420. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleLegacyLabelAdoption.test.ts +634 -0
  421. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +1193 -0
  422. package/Tests/Server/Services/{SloMonitorLabelRuleHooks.test.ts → ServiceLevelObjectiveMonitorRuleTriggers.test.ts} +135 -41
  423. package/Tests/Server/Services/ServiceLevelObjectiveOwnerFeedWrites.test.ts +671 -0
  424. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +180 -85
  425. package/Tests/Server/Services/ServiceLevelObjectiveServiceArchive.test.ts +537 -0
  426. package/Tests/Server/Services/ServiceLevelObjectiveServiceLegacyMonitorLabelWrite.test.ts +870 -0
  427. package/Tests/Server/Services/ServiceLevelObjectiveServiceMonitorRuleGuard.test.ts +343 -0
  428. package/Tests/Server/Services/ServiceLevelObjectiveServiceReEvaluation.test.ts +246 -0
  429. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +501 -0
  430. package/Tests/Server/Services/SloAffectedResourceLinkContract.test.ts +86 -0
  431. package/Tests/Server/Services/SloAffectedResourceMetricAttributes.test.ts +547 -0
  432. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +10 -4
  433. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +7 -2
  434. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +174 -0
  435. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateServiceVariables.test.ts +40 -0
  436. package/Tests/Server/Services/SubscriberUpdateNotificationHooks.test.ts +541 -0
  437. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
  438. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
  439. package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
  440. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +288 -0
  441. package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
  442. package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
  443. package/Tests/Server/TestingUtils/PastDueMonitoringClaimSql.ts +177 -0
  444. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +51 -10
  445. package/Tests/Server/TestingUtils/__mocks__/Stripe.mock.ts +16 -1
  446. package/Tests/Server/Types/Database/Permissions/ProjectDataResidencyColumn.test.ts +386 -0
  447. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +34 -11
  448. package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
  449. package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
  450. package/Tests/Server/Utils/AI/SloAffectedResourceAIContext.test.ts +445 -0
  451. package/Tests/Server/Utils/AI/SloTools.test.ts +423 -1
  452. package/Tests/Server/Utils/AI/SloToolsArchive.test.ts +294 -0
  453. package/Tests/Server/Utils/AI/SloToolsRuleReadPermissions.test.ts +297 -0
  454. package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
  455. package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
  456. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
  457. package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
  458. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +255 -10
  459. package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +404 -750
  460. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +45 -0
  461. package/Tests/Server/Utils/Database/RelationValueUtil.test.ts +157 -0
  462. package/Tests/Server/Utils/Monitor/Criteria/BooleanSeriesEvaluateOverTime.test.ts +260 -0
  463. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +181 -0
  464. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +147 -30
  465. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
  466. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.test.ts +17 -0
  467. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +136 -0
  468. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidatorLoadOrder.test.ts +472 -0
  469. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +48 -2
  470. package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +435 -475
  471. package/Tests/Server/Utils/Rules/MonitorRulePatternValidator.test.ts +77 -0
  472. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +177 -0
  473. package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +365 -0
  474. package/Tests/Server/Utils/Rules/RuleRun/RuleRunRegistry.test.ts +173 -0
  475. package/Tests/Server/Utils/Rules/RuleRun/RuleRunner.test.ts +675 -0
  476. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +8 -8
  477. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
  478. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
  479. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorFetchSummary.test.ts +261 -0
  480. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1184 -0
  481. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
  482. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
  483. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
  484. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
  485. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsAuth.test.ts → Connectors/GoogleSecOps/GoogleSecOpsAuth.test.ts} +5 -5
  486. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClient.test.ts → Connectors/GoogleSecOps/GoogleSecOpsClient.test.ts} +9 -5
  487. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.test.ts +483 -0
  488. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorCuratedAndLateAlerts.test.ts +676 -0
  489. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFetchEvents.test.ts +1994 -0
  490. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorFixtures.ts +332 -0
  491. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorHttpIntegration.test.ts +680 -0
  492. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorRequestContract.test.ts +1206 -0
  493. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorTestConnection.test.ts +1136 -0
  494. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsCuratedRuleCounts.test.ts +407 -0
  495. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsErrorHandling.test.ts → Connectors/GoogleSecOps/GoogleSecOpsErrorHandling.test.ts} +5 -5
  496. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingAdaptiveCatchUp.test.ts +730 -0
  497. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsClickhouseIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingClickhouseIntegration.test.ts} +130 -35
  498. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFailureTaxonomy.test.ts +772 -0
  499. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingFixtures.ts +648 -0
  500. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsHttpIntegration.test.ts → Connectors/GoogleSecOps/GoogleSecOpsPollingHttpIntegration.test.ts} +249 -222
  501. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingIntegration.test.ts +1390 -0
  502. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingLoop.test.ts +981 -0
  503. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsPollingNothingImportedRegression.test.ts +290 -0
  504. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsRequestContract.test.ts → Connectors/GoogleSecOps/GoogleSecOpsRequestContract.test.ts} +2 -2
  505. package/Tests/Server/Utils/SecurityEvent/{GoogleSecOpsResponseParsing.test.ts → Connectors/GoogleSecOps/GoogleSecOpsResponseParsing.test.ts} +5 -5
  506. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsSearchDetections.test.ts +763 -0
  507. package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsTesterIntegration.test.ts +421 -0
  508. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
  509. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
  510. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
  511. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
  512. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
  513. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
  514. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +4483 -0
  515. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1178 -0
  516. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +1215 -0
  517. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
  518. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
  519. package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
  520. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1966 -179
  521. package/Tests/Server/Utils/Slo/SloFeedUtil.test.ts +326 -0
  522. package/Tests/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.test.ts +260 -0
  523. package/Tests/Server/Utils/Slo/SloMetricUtil.test.ts +592 -0
  524. package/Tests/Server/Utils/Slo/SloRecordReferenceValidator.test.ts +311 -0
  525. package/Tests/Server/Utils/StatusPageResource.test.ts +91 -3
  526. package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
  527. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
  528. package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
  529. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +348 -2
  530. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
  531. package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
  532. package/Tests/Types/Billing/SubscriptionStatus.test.ts +176 -0
  533. package/Tests/Types/Billing/SubscriptionStatusPastDueMonitoring.test.ts +187 -0
  534. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +53 -7
  535. package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +816 -792
  536. package/Tests/Types/Monitor/CriteriaFilter.test.ts +216 -24
  537. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +14 -1
  538. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +14 -1
  539. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +14 -1
  540. package/Tests/Types/Monitor/MonitorStepRetriesParsing.test.ts +201 -0
  541. package/Tests/Types/Rules/RuleRun.test.ts +315 -0
  542. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +133 -0
  543. package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
  544. package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
  545. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +339 -0
  546. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +217 -0
  547. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +200 -0
  548. package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
  549. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
  550. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
  551. package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +411 -0
  552. package/Tests/UI/Components/AlertBanner.test.tsx +319 -0
  553. package/Tests/UI/Components/BulkArchiveActionsCopy.test.tsx +310 -0
  554. package/Tests/UI/Components/Card.test.tsx +312 -1
  555. package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
  556. package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
  557. package/Tests/UI/Components/Checkbox.test.tsx +79 -0
  558. package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
  559. package/Tests/UI/Components/Detail/DetailIdIsUnique.test.tsx +87 -0
  560. package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
  561. package/Tests/UI/Components/Dropdown/DropdownClearable.test.tsx +393 -0
  562. package/Tests/UI/Components/Dropdown/DropdownMultiSelectChipAccessibleName.test.tsx +64 -0
  563. package/Tests/UI/Components/EmptyState/EmptyState.test.tsx +335 -4
  564. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +337 -0
  565. package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
  566. package/Tests/UI/Components/FacetSections.test.tsx +581 -0
  567. package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
  568. package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
  569. package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +21 -20
  570. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +15 -2
  571. package/Tests/UI/Components/LockedFilterChip.test.tsx +788 -0
  572. package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
  573. package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
  574. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
  575. package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
  576. package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
  577. package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
  578. package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
  579. package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
  580. package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
  581. package/Tests/UI/Components/MoreMenu.test.tsx +133 -0
  582. package/Tests/UI/Components/MoreMenuMotion.test.tsx +84 -3
  583. package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
  584. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
  585. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  586. package/Tests/UI/Components/RuleRun/RuleDetailFields.test.tsx +336 -0
  587. package/Tests/UI/Components/RuleRun/RuleTable.test.tsx +304 -0
  588. package/Tests/UI/Components/RuleRun/RunRuleNowModal.test.tsx +231 -0
  589. package/Tests/UI/Components/RuleRun/RunRulesBulkAction.test.ts +213 -0
  590. package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
  591. package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
  592. package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +367 -0
  593. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
  594. package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
  595. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
  596. package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
  597. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
  598. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
  599. package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
  600. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
  601. package/Tests/UI/Rum/ReplayEngine.test.ts +154 -0
  602. package/Tests/UI/Rum/ReplayHeader.test.tsx +284 -124
  603. package/Tests/UI/Rum/ReplayPinControl.test.tsx +189 -10
  604. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +286 -12
  605. package/Tests/UI/Rum/ReplayRail.test.tsx +294 -0
  606. package/Tests/UI/Rum/ReplayScrubber.test.tsx +213 -1
  607. package/Tests/UI/Rum/ReplayStage.test.tsx +1228 -173
  608. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +433 -3
  609. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +1391 -0
  610. package/Tests/UI/Rum/ReplayTimeline.test.tsx +222 -0
  611. package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
  612. package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
  613. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
  614. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
  615. package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
  616. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
  617. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
  618. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
  619. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
  620. package/Tests/UI/Utils/Clipboard.test.ts +154 -0
  621. package/Tests/UI/Utils/DashboardStackingLayers.test.ts +8 -1
  622. package/Tests/UI/Utils/Navigation.test.ts +24 -0
  623. package/Tests/UI/Utils/RuleRunClient.test.ts +303 -0
  624. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2206 -0
  625. package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
  626. package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
  627. package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
  628. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +2 -0
  629. package/Tests/Utils/Dashboard/Components/DashboardSloListComponent.test.ts +206 -0
  630. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +36 -2
  631. package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +409 -588
  632. package/Tests/Utils/Dashboard/SloWidgetSource.test.ts +351 -0
  633. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +361 -0
  634. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +1425 -118
  635. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +188 -3
  636. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +661 -13
  637. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +349 -0
  638. package/Tests/Utils/NetworkDiscovery/RunImportedDeviceNaming.test.ts +656 -0
  639. package/Tests/Utils/NetworkDiscovery/ShortDeviceNamePlanner.test.ts +1020 -0
  640. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +619 -0
  641. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +317 -0
  642. package/Tests/Utils/Project/DataResidency.test.ts +198 -0
  643. package/Tests/Utils/Rules/RuleRunSummary.test.ts +394 -0
  644. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
  645. package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
  646. package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
  647. package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
  648. package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
  649. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
  650. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
  651. package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
  652. package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
  653. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
  654. package/Tests/Utils/Slo/SloAffectedResourceMarkdown.test.ts +302 -0
  655. package/Tests/Utils/Slo/SloBurnRateTemplate.test.ts +468 -0
  656. package/Tests/Utils/Slo/SloEvaluation.test.ts +20 -4
  657. package/Tests/Utils/Slo/SloFeedMarkdown.test.ts +1185 -0
  658. package/Tests/Utils/Slo/SloHealth.test.ts +262 -0
  659. package/Tests/Utils/Slo/SloHistoryMetricName.test.ts +102 -0
  660. package/Tests/Utils/Slo/SloListWidgetFormat.test.ts +522 -0
  661. package/Tests/Utils/Slo/SloMetricType.test.ts +355 -0
  662. package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +387 -0
  663. package/Tests/Utils/Slo/SloMonitorStatusSummary.test.ts +210 -0
  664. package/Tests/Utils/Slo/SloOverviewText.test.ts +226 -0
  665. package/Tests/Utils/Slo/SloProjection.test.ts +1039 -0
  666. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +47 -0
  667. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
  668. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
  669. package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +521 -0
  670. package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
  671. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
  672. package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
  673. package/Types/AI/AIChatTypes.ts +8 -0
  674. package/Types/AI/InvestigationEvidence.ts +96 -0
  675. package/Types/BaseDatabase/EnableAuditLogOn.ts +41 -0
  676. package/Types/Billing/SubscriptionStatus.ts +39 -4
  677. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  678. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +5 -0
  679. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +10 -0
  680. package/Types/Dashboard/DashboardComponents/DashboardSloListComponent.ts +29 -0
  681. package/Types/Dashboard/DashboardTemplates.ts +290 -297
  682. package/Types/Database/EnableAuditLog.ts +23 -1
  683. package/Types/Email/EmailTemplateType.ts +4 -0
  684. package/Types/Monitor/CriteriaFilter.ts +55 -8
  685. package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
  686. package/Types/Monitor/MonitorStep.ts +5 -2
  687. package/Types/Monitor/MonitorStepDnsMonitor.ts +3 -1
  688. package/Types/Monitor/MonitorStepDnssecMonitor.ts +3 -1
  689. package/Types/Monitor/MonitorStepDomainMonitor.ts +3 -1
  690. package/Types/Monitor/MonitorStepExternalStatusPageMonitor.ts +3 -1
  691. package/Types/Monitor/MonitorStepRetries.ts +59 -0
  692. package/Types/Monitor/MonitorStepSnmpMonitor.ts +9 -2
  693. package/Types/NetworkDevice/NetworkDeviceDiagnosticResult.ts +104 -0
  694. package/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.ts +47 -0
  695. package/Types/NetworkDevice/NetworkDeviceDiagnosticType.ts +47 -0
  696. package/Types/NetworkDevice/NetworkDevicePingMetricNames.ts +20 -0
  697. package/Types/Permission.ts +129 -2
  698. package/Types/Rules/RuleCriteriaFieldRegistry.ts +5 -0
  699. package/Types/Rules/RuleRun.ts +518 -0
  700. package/Types/Rum/SessionReplay.ts +109 -0
  701. package/Types/Rum/SessionReplayApi.ts +49 -0
  702. package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +117 -0
  703. package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +113 -0
  704. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +599 -0
  705. package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +45 -0
  706. package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
  707. package/Types/ServiceLevelObjective/SloHistoryMetricName.ts +25 -0
  708. package/Types/ServiceLevelObjective/SloMetricType.ts +49 -0
  709. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +4 -0
  710. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +331 -0
  711. package/Types/StatusPage/SubscriberNotificationTrigger.ts +12 -0
  712. package/Types/StatusPage/SubscriberUpdateNotification.ts +89 -0
  713. package/Types/Telemetry/EntityType.ts +14 -0
  714. package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
  715. package/Types/Telemetry/LockedFilterDetail.ts +25 -0
  716. package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
  717. package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
  718. package/Types/Telemetry/ServiceType.ts +7 -0
  719. package/Typings/Index.d.ts +53 -3
  720. package/UI/Components/AlertBanner/AlertBanner.tsx +85 -27
  721. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +21 -2
  722. package/UI/Components/Card/Card.tsx +118 -83
  723. package/UI/Components/Checkbox/Checkbox.tsx +8 -5
  724. package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
  725. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
  726. package/UI/Components/Detail/Detail.tsx +145 -23
  727. package/UI/Components/Dropdown/Dropdown.tsx +64 -1
  728. package/UI/Components/EmptyState/EmptyState.tsx +27 -3
  729. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +124 -0
  730. package/UI/Components/ErrorBoundary.tsx +38 -0
  731. package/UI/Components/Forms/ModelForm.tsx +6 -5
  732. package/UI/Components/LabelRule/LabelRuleTable.tsx +8 -2
  733. package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
  734. package/UI/Components/LogsViewer/LogsViewer.tsx +152 -77
  735. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +17 -11
  736. package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
  737. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
  738. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
  739. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
  740. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
  741. package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
  742. package/UI/Components/LogsViewer/types.ts +6 -0
  743. package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
  744. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
  745. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
  746. package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
  747. package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
  748. package/UI/Components/ModelList/ModelList.tsx +33 -8
  749. package/UI/Components/MoreMenu/MoreMenu.tsx +14 -3
  750. package/UI/Components/Page/ModelPage.tsx +119 -54
  751. package/UI/Components/RuleRun/RuleDetailFields.tsx +359 -0
  752. package/UI/Components/RuleRun/RuleTable.tsx +183 -0
  753. package/UI/Components/RuleRun/RuleView.tsx +170 -0
  754. package/UI/Components/RuleRun/RunRuleNowModal.tsx +147 -0
  755. package/UI/Components/RuleRun/RunRulesBulkAction.ts +103 -0
  756. package/UI/Components/Table/Table.tsx +8 -0
  757. package/UI/Components/Table/TableRow.tsx +13 -5
  758. package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
  759. package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
  760. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +7 -0
  761. package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
  762. package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
  763. package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
  764. package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
  765. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +430 -0
  766. package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +14 -10
  767. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
  768. package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
  769. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
  770. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
  771. package/UI/Components/TelemetryViewer/types.ts +19 -0
  772. package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
  773. package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
  774. package/UI/Utils/Clipboard.ts +68 -2
  775. package/UI/Utils/Navigation.ts +17 -2
  776. package/UI/Utils/Rules/RuleRunClient.ts +178 -0
  777. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +628 -0
  778. package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
  779. package/Utils/AI/InvestigationReport.ts +1789 -0
  780. package/Utils/API.ts +90 -1
  781. package/Utils/Dashboard/Components/DashboardSloComponent.ts +19 -2
  782. package/Utils/Dashboard/Components/DashboardSloListComponent.ts +126 -0
  783. package/Utils/Dashboard/Components/Index.ts +7 -0
  784. package/Utils/Dashboard/SloWidgetSource.ts +188 -0
  785. package/Utils/Markdown/MarkdownEscape.ts +63 -0
  786. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +161 -36
  787. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +25 -0
  788. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +146 -0
  789. package/Utils/NetworkDiscovery/RunImportedDeviceNaming.ts +390 -0
  790. package/Utils/NetworkDiscovery/ShortDeviceNamePlanner.ts +291 -0
  791. package/Utils/NetworkDiscovery/ShortHostnameUtil.ts +91 -0
  792. package/Utils/NetworkSite/CidrMatchUtil.ts +37 -12
  793. package/Utils/Project/DataResidency.ts +63 -0
  794. package/Utils/Rules/RuleRunSummary.ts +323 -0
  795. package/Utils/Rum/SessionReplayHealth.ts +11 -0
  796. package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
  797. package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
  798. package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
  799. package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
  800. package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
  801. package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
  802. package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
  803. package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
  804. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
  805. package/Utils/Slo/SloAffectedResourceMarkdown.ts +123 -0
  806. package/Utils/Slo/SloBurnRateTemplate.ts +373 -0
  807. package/Utils/Slo/SloFeedMarkdown.ts +1507 -0
  808. package/Utils/Slo/SloHealth.ts +96 -9
  809. package/Utils/Slo/SloListWidgetFormat.ts +370 -0
  810. package/Utils/Slo/SloMetricType.ts +237 -0
  811. package/Utils/Slo/SloMonitorRuleCriteria.ts +364 -0
  812. package/Utils/Slo/SloMonitorStatusSummary.ts +210 -0
  813. package/Utils/Slo/SloOverviewText.ts +265 -0
  814. package/Utils/Slo/SloProjection.ts +967 -0
  815. package/Utils/Slo/SloWidgetFormat.ts +12 -2
  816. package/Utils/Telemetry/CrossSignalScope.ts +22 -8
  817. package/Utils/Telemetry/EntityRelationship.ts +8 -0
  818. package/Utils/Telemetry/LockedFilterSearch.ts +366 -0
  819. package/Utils/Telemetry/NetworkHost.ts +43 -0
  820. package/Utils/Telemetry/OriginAllowList.ts +139 -4
  821. package/Utils/Traces/CriticalPath.ts +10 -4
  822. package/build/dist/Models/AnalyticsModels/AuditLog.js +70 -1
  823. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  824. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +4 -4
  825. package/build/dist/Models/DatabaseModels/Alert.js +60 -0
  826. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  827. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  828. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  829. package/build/dist/Models/DatabaseModels/Incident.js +64 -0
  830. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  831. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +75 -0
  832. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  833. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +75 -0
  834. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  835. package/build/dist/Models/DatabaseModels/Index.js +10 -4
  836. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  837. package/build/dist/Models/DatabaseModels/NetworkDevice.js +68 -0
  838. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  839. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js +772 -0
  840. package/build/dist/Models/DatabaseModels/NetworkDeviceDiagnostic.js.map +1 -0
  841. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +140 -0
  842. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  843. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +1 -1
  844. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
  845. package/build/dist/Models/DatabaseModels/Project.js +42 -0
  846. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  847. package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
  848. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  849. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +75 -0
  850. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  851. package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnection.js → SecurityEventConnection.js} +87 -75
  852. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
  853. package/build/dist/Models/DatabaseModels/{GoogleSecOpsConnectionRun.js → SecurityEventConnectionRun.js} +37 -37
  854. package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
  855. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +192 -10
  856. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  857. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +798 -96
  858. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
  859. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +596 -0
  860. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -0
  861. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +590 -0
  862. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -0
  863. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +16 -0
  864. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -1
  865. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +16 -0
  866. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -1
  867. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +75 -0
  868. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  869. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
  870. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  871. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +1 -1
  872. package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
  873. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  874. package/build/dist/Server/API/BaseAPI.js +14 -0
  875. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  876. package/build/dist/Server/API/BillingInvoiceAPI.js +233 -19
  877. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  878. package/build/dist/Server/API/BillingPaymentMethodAPI.js +86 -5
  879. package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
  880. package/build/dist/Server/API/DashboardAPI.js +72 -2
  881. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  882. package/build/dist/Server/API/SecurityEventConnectionAPI.js +263 -0
  883. package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
  884. package/build/dist/Server/API/StatusPageAPI.js +236 -154
  885. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  886. package/build/dist/Server/API/TelemetryAPI.js +248 -170
  887. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  888. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
  889. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
  890. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js +34 -0
  891. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792800000000-AddNetworkDeviceDiagnostic.js.map +1 -0
  892. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js +24 -0
  893. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792900000000-AddNetworkDeviceDnsNameAndShortDeviceNames.js.map +1 -0
  894. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js +21 -0
  895. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793000000000-AddNetbiosLookupToNetworkDeviceDiscoveryScan.js.map +1 -0
  896. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js +207 -0
  897. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793100000000-SloProductOverhaul.js.map +1 -0
  898. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js +72 -0
  899. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793200000000-BackfillSloMonitorRulesAndAffectedResources.js.map +1 -0
  900. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js +20 -0
  901. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793300000000-AddDataResidencyToProject.js.map +1 -0
  902. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js +46 -0
  903. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793400000000-AddSubscriberUpdateNotificationStatus.js.map +1 -0
  904. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
  905. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  906. package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
  907. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  908. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +112 -56
  909. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  910. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +167 -68
  911. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  912. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +87 -26
  913. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  914. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +270 -203
  915. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  916. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +498 -354
  917. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  918. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +97 -34
  919. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  920. package/build/dist/Server/Services/AlertService.js +91 -8
  921. package/build/dist/Server/Services/AlertService.js.map +1 -1
  922. package/build/dist/Server/Services/AuditLogService.js +408 -44
  923. package/build/dist/Server/Services/AuditLogService.js.map +1 -1
  924. package/build/dist/Server/Services/BillingInvoiceService.js +94 -85
  925. package/build/dist/Server/Services/BillingInvoiceService.js.map +1 -1
  926. package/build/dist/Server/Services/BillingService.js +406 -14
  927. package/build/dist/Server/Services/BillingService.js.map +1 -1
  928. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +141 -92
  929. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  930. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +189 -101
  931. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  932. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +135 -86
  933. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  934. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +189 -100
  935. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  936. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +117 -69
  937. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  938. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +171 -83
  939. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  940. package/build/dist/Server/Services/DatabaseService.js +125 -18
  941. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  942. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +141 -92
  943. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  944. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +189 -101
  945. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  946. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +145 -91
  947. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  948. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +191 -101
  949. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  950. package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
  951. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  952. package/build/dist/Server/Services/HostLabelRuleEngineService.js +141 -92
  953. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  954. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +190 -102
  955. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  956. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +112 -56
  957. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  958. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +220 -63
  959. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  960. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +87 -26
  961. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  962. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  963. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  964. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +258 -192
  965. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  966. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +519 -376
  967. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  968. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +95 -32
  969. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  970. package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
  971. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  972. package/build/dist/Server/Services/IncidentService.js +90 -5
  973. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  974. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +113 -65
  975. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  976. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +171 -83
  977. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  978. package/build/dist/Server/Services/Index.js +10 -4
  979. package/build/dist/Server/Services/Index.js.map +1 -1
  980. package/build/dist/Server/Services/InventoryItemService.js +22 -0
  981. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  982. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +117 -69
  983. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  984. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +171 -83
  985. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  986. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +145 -91
  987. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  988. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +191 -101
  989. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  990. package/build/dist/Server/Services/LabelService.js +20 -25
  991. package/build/dist/Server/Services/LabelService.js.map +1 -1
  992. package/build/dist/Server/Services/LogAggregationService.js +8 -17
  993. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  994. package/build/dist/Server/Services/MetricAggregationService.js +4 -14
  995. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  996. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +123 -77
  997. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  998. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +167 -82
  999. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  1000. package/build/dist/Server/Services/MonitorProbeService.js +18 -2
  1001. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  1002. package/build/dist/Server/Services/MonitorService.js +11 -9
  1003. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  1004. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +287 -5
  1005. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  1006. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js +333 -0
  1007. package/build/dist/Server/Services/NetworkDeviceDiagnosticService.js.map +1 -0
  1008. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +117 -69
  1009. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  1010. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +171 -83
  1011. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  1012. package/build/dist/Server/Services/NetworkDeviceService.js +36 -2
  1013. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  1014. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +117 -64
  1015. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  1016. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +173 -83
  1017. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  1018. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +116 -65
  1019. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  1020. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +171 -83
  1021. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  1022. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +141 -92
  1023. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  1024. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +189 -101
  1025. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  1026. package/build/dist/Server/Services/ProjectService.js +82 -10
  1027. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  1028. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +141 -92
  1029. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  1030. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +189 -101
  1031. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  1032. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +111 -63
  1033. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  1034. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +161 -77
  1035. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  1036. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +117 -69
  1037. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  1038. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +171 -83
  1039. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  1040. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +280 -209
  1041. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  1042. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +521 -376
  1043. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  1044. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
  1045. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  1046. package/build/dist/Server/Services/ScheduledMaintenanceService.js +24 -8
  1047. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  1048. package/build/dist/Server/Services/{GoogleSecOpsConnectionRunService.js → SecurityEventConnectionRunService.js} +2 -2
  1049. package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
  1050. package/build/dist/Server/Services/SecurityEventConnectionService.js +396 -0
  1051. package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
  1052. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +115 -62
  1053. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  1054. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +163 -77
  1055. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  1056. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +141 -92
  1057. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  1058. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +769 -18
  1059. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
  1060. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js +96 -0
  1061. package/build/dist/Server/Services/ServiceLevelObjectiveFeedService.js.map +1 -0
  1062. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +614 -87
  1063. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
  1064. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +844 -0
  1065. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -0
  1066. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +207 -1
  1067. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -1
  1068. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +221 -1
  1069. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -1
  1070. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +997 -50
  1071. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  1072. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +191 -102
  1073. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  1074. package/build/dist/Server/Services/StatusPageAnnouncementService.js +12 -0
  1075. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  1076. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +118 -70
  1077. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  1078. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +158 -76
  1079. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  1080. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +19 -215
  1081. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  1082. package/build/dist/Server/Services/StatusPageSubscriberService.js +6 -0
  1083. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  1084. package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -5
  1085. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  1086. package/build/dist/Server/Services/ThreatIntelFeedService.js +1 -1
  1087. package/build/dist/Server/Services/TraceAggregationService.js +51 -25
  1088. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  1089. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +141 -92
  1090. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
  1091. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +189 -101
  1092. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  1093. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +117 -69
  1094. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  1095. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +171 -83
  1096. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  1097. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
  1098. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  1099. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +17 -0
  1100. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  1101. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  1102. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  1103. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +31 -0
  1104. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  1105. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
  1106. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  1107. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
  1108. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
  1109. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
  1110. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
  1111. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +24 -1
  1112. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  1113. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +21 -1
  1114. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  1115. package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
  1116. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  1117. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +337 -53
  1118. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  1119. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
  1120. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
  1121. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
  1122. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  1123. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +108 -15
  1124. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  1125. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +2 -2
  1126. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -1
  1127. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +115 -6
  1128. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -1
  1129. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +13 -0
  1130. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  1131. package/build/dist/Server/Utils/Database/RelationValueUtil.js +82 -0
  1132. package/build/dist/Server/Utils/Database/RelationValueUtil.js.map +1 -0
  1133. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +10 -6
  1134. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  1135. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +17 -21
  1136. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  1137. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
  1138. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  1139. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +5 -4
  1140. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  1141. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +50 -10
  1142. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  1143. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +13 -1
  1144. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  1145. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +6 -10
  1146. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  1147. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js +34 -0
  1148. package/build/dist/Server/Utils/Rules/MonitorRulePatternValidator.js.map +1 -0
  1149. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +69 -0
  1150. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -0
  1151. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js +25 -0
  1152. package/build/dist/Server/Utils/Rules/RuleRun/RuleApplication.js.map +1 -0
  1153. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js +128 -0
  1154. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunPermission.js.map +1 -0
  1155. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +746 -0
  1156. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -0
  1157. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js +221 -0
  1158. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunner.js.map +1 -0
  1159. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +3 -2
  1160. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
  1161. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
  1162. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
  1163. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
  1164. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
  1165. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +354 -0
  1166. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
  1167. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
  1168. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
  1169. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
  1170. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
  1171. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
  1172. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
  1173. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
  1174. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
  1175. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps → Connectors/GoogleSecOps}/GoogleSecOpsClient.js +401 -68
  1176. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  1177. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js +1417 -0
  1178. package/build/dist/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnector.js.map +1 -0
  1179. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
  1180. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
  1181. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
  1182. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
  1183. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
  1184. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
  1185. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
  1186. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
  1187. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
  1188. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
  1189. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
  1190. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
  1191. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +839 -0
  1192. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
  1193. package/build/dist/Server/Utils/SecurityEvent/{GoogleSecOps/GoogleSecOpsRunExecutor.js → Connectors/SecurityEventConnectionRunExecutor.js} +77 -50
  1194. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
  1195. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +214 -0
  1196. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
  1197. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +42 -0
  1198. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
  1199. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
  1200. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
  1201. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
  1202. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
  1203. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +122 -0
  1204. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
  1205. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +1 -1
  1206. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
  1207. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
  1208. package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +2 -2
  1209. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +599 -32
  1210. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  1211. package/build/dist/Server/Utils/Slo/SloFeedUtil.js +150 -0
  1212. package/build/dist/Server/Utils/Slo/SloFeedUtil.js.map +1 -0
  1213. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js +136 -0
  1214. package/build/dist/Server/Utils/Slo/SloLegacyMonitorLabelAdoption.js.map +1 -0
  1215. package/build/dist/Server/Utils/Slo/SloMetricUtil.js +269 -0
  1216. package/build/dist/Server/Utils/Slo/SloMetricUtil.js.map +1 -0
  1217. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js +134 -0
  1218. package/build/dist/Server/Utils/Slo/SloOwnerReferenceValidator.js.map +1 -0
  1219. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js +137 -0
  1220. package/build/dist/Server/Utils/Slo/SloRecordReferenceValidator.js.map +1 -0
  1221. package/build/dist/Server/Utils/StartServer.js +10 -0
  1222. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  1223. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +6 -26
  1224. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -1
  1225. package/build/dist/Server/Utils/StatusPageResource.js +31 -5
  1226. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  1227. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
  1228. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  1229. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
  1230. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
  1231. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
  1232. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  1233. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
  1234. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
  1235. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
  1236. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  1237. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
  1238. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
  1239. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
  1240. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
  1241. package/build/dist/Server/Utils/Telemetry.js +11 -5
  1242. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  1243. package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
  1244. package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
  1245. package/build/dist/Types/Billing/SubscriptionStatus.js +37 -3
  1246. package/build/dist/Types/Billing/SubscriptionStatus.js.map +1 -1
  1247. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  1248. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  1249. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +5 -0
  1250. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  1251. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js +2 -0
  1252. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloListComponent.js.map +1 -0
  1253. package/build/dist/Types/Dashboard/DashboardTemplates.js +275 -286
  1254. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  1255. package/build/dist/Types/Database/EnableAuditLog.js +19 -1
  1256. package/build/dist/Types/Database/EnableAuditLog.js.map +1 -1
  1257. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  1258. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  1259. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -6
  1260. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  1261. package/build/dist/Types/Monitor/MonitorStep.js +2 -0
  1262. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  1263. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js +3 -1
  1264. package/build/dist/Types/Monitor/MonitorStepDnsMonitor.js.map +1 -1
  1265. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +3 -1
  1266. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -1
  1267. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +3 -1
  1268. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  1269. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js +3 -1
  1270. package/build/dist/Types/Monitor/MonitorStepExternalStatusPageMonitor.js.map +1 -1
  1271. package/build/dist/Types/Monitor/MonitorStepRetries.js +47 -0
  1272. package/build/dist/Types/Monitor/MonitorStepRetries.js.map +1 -0
  1273. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -1
  1274. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
  1275. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js +29 -0
  1276. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticResult.js.map +1 -0
  1277. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js +37 -0
  1278. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticStatus.js.map +1 -0
  1279. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js +42 -0
  1280. package/build/dist/Types/NetworkDevice/NetworkDeviceDiagnosticType.js.map +1 -0
  1281. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js +20 -0
  1282. package/build/dist/Types/NetworkDevice/NetworkDevicePingMetricNames.js.map +1 -0
  1283. package/build/dist/Types/Permission.js +116 -2
  1284. package/build/dist/Types/Permission.js.map +1 -1
  1285. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +5 -0
  1286. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  1287. package/build/dist/Types/Rules/RuleRun.js +267 -0
  1288. package/build/dist/Types/Rules/RuleRun.js.map +1 -0
  1289. package/build/dist/Types/Rum/SessionReplay.js +95 -0
  1290. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  1291. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  1292. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
  1293. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
  1294. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +17 -0
  1295. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
  1296. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +439 -0
  1297. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
  1298. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +39 -0
  1299. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
  1300. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
  1301. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
  1302. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js +26 -0
  1303. package/build/dist/Types/ServiceLevelObjective/SloHistoryMetricName.js.map +1 -0
  1304. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js +45 -0
  1305. package/build/dist/Types/ServiceLevelObjective/SloMetricType.js.map +1 -0
  1306. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +4 -0
  1307. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  1308. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +295 -0
  1309. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -0
  1310. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js +13 -0
  1311. package/build/dist/Types/StatusPage/SubscriberNotificationTrigger.js.map +1 -0
  1312. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +67 -0
  1313. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -0
  1314. package/build/dist/Types/Telemetry/EntityType.js +14 -0
  1315. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  1316. package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
  1317. package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
  1318. package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
  1319. package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
  1320. package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
  1321. package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
  1322. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
  1323. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
  1324. package/build/dist/Types/Telemetry/ServiceType.js +7 -0
  1325. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  1326. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +48 -19
  1327. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
  1328. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +10 -2
  1329. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  1330. package/build/dist/UI/Components/Card/Card.js +34 -17
  1331. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  1332. package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
  1333. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  1334. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  1335. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  1336. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
  1337. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  1338. package/build/dist/UI/Components/Detail/Detail.js +74 -15
  1339. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  1340. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -5
  1341. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  1342. package/build/dist/UI/Components/EmptyState/EmptyState.js +3 -3
  1343. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  1344. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +47 -0
  1345. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +1 -0
  1346. package/build/dist/UI/Components/ErrorBoundary.js +34 -0
  1347. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  1348. package/build/dist/UI/Components/Forms/ModelForm.js +6 -5
  1349. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  1350. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +6 -2
  1351. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -1
  1352. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
  1353. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
  1354. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
  1355. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  1356. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +3 -7
  1357. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  1358. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
  1359. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
  1360. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
  1361. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  1362. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
  1363. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  1364. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
  1365. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  1366. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
  1367. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  1368. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
  1369. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  1370. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  1371. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
  1372. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
  1373. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
  1374. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  1375. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
  1376. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  1377. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
  1378. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  1379. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
  1380. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  1381. package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
  1382. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  1383. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +3 -1
  1384. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  1385. package/build/dist/UI/Components/Page/ModelPage.js +62 -34
  1386. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  1387. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js +226 -0
  1388. package/build/dist/UI/Components/RuleRun/RuleDetailFields.js.map +1 -0
  1389. package/build/dist/UI/Components/RuleRun/RuleTable.js +97 -0
  1390. package/build/dist/UI/Components/RuleRun/RuleTable.js.map +1 -0
  1391. package/build/dist/UI/Components/RuleRun/RuleView.js +83 -0
  1392. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -0
  1393. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +74 -0
  1394. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -0
  1395. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js +78 -0
  1396. package/build/dist/UI/Components/RuleRun/RunRulesBulkAction.js.map +1 -0
  1397. package/build/dist/UI/Components/Table/Table.js +3 -1
  1398. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  1399. package/build/dist/UI/Components/Table/TableRow.js +8 -1
  1400. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  1401. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
  1402. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
  1403. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
  1404. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
  1405. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  1406. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  1407. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
  1408. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
  1409. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
  1410. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
  1411. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
  1412. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
  1413. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
  1414. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
  1415. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +202 -0
  1416. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
  1417. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +2 -6
  1418. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
  1419. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
  1420. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  1421. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
  1422. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
  1423. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
  1424. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  1425. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
  1426. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  1427. package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
  1428. package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
  1429. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
  1430. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
  1431. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
  1432. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
  1433. package/build/dist/UI/Utils/Clipboard.js +59 -2
  1434. package/build/dist/UI/Utils/Clipboard.js.map +1 -1
  1435. package/build/dist/UI/Utils/Navigation.js +11 -2
  1436. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  1437. package/build/dist/UI/Utils/Rules/RuleRunClient.js +98 -0
  1438. package/build/dist/UI/Utils/Rules/RuleRunClient.js.map +1 -0
  1439. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +479 -0
  1440. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
  1441. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
  1442. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
  1443. package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
  1444. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
  1445. package/build/dist/Utils/API.js +25 -0
  1446. package/build/dist/Utils/API.js.map +1 -1
  1447. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +16 -2
  1448. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -1
  1449. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js +94 -0
  1450. package/build/dist/Utils/Dashboard/Components/DashboardSloListComponent.js.map +1 -0
  1451. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  1452. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  1453. package/build/dist/Utils/Dashboard/SloWidgetSource.js +125 -0
  1454. package/build/dist/Utils/Dashboard/SloWidgetSource.js.map +1 -0
  1455. package/build/dist/Utils/Markdown/MarkdownEscape.js +49 -0
  1456. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -0
  1457. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +112 -34
  1458. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  1459. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +22 -0
  1460. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  1461. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +129 -0
  1462. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -0
  1463. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js +255 -0
  1464. package/build/dist/Utils/NetworkDiscovery/RunImportedDeviceNaming.js.map +1 -0
  1465. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js +184 -0
  1466. package/build/dist/Utils/NetworkDiscovery/ShortDeviceNamePlanner.js.map +1 -0
  1467. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js +79 -0
  1468. package/build/dist/Utils/NetworkDiscovery/ShortHostnameUtil.js.map +1 -0
  1469. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +21 -12
  1470. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
  1471. package/build/dist/Utils/Project/DataResidency.js +51 -0
  1472. package/build/dist/Utils/Project/DataResidency.js.map +1 -0
  1473. package/build/dist/Utils/Rules/RuleRunSummary.js +197 -0
  1474. package/build/dist/Utils/Rules/RuleRunSummary.js.map +1 -0
  1475. package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
  1476. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
  1477. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
  1478. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
  1479. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
  1480. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
  1481. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
  1482. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
  1483. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
  1484. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
  1485. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
  1486. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
  1487. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
  1488. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
  1489. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
  1490. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
  1491. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
  1492. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
  1493. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
  1494. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  1495. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js +51 -0
  1496. package/build/dist/Utils/Slo/SloAffectedResourceMarkdown.js.map +1 -0
  1497. package/build/dist/Utils/Slo/SloBurnRateTemplate.js +228 -0
  1498. package/build/dist/Utils/Slo/SloBurnRateTemplate.js.map +1 -0
  1499. package/build/dist/Utils/Slo/SloFeedMarkdown.js +934 -0
  1500. package/build/dist/Utils/Slo/SloFeedMarkdown.js.map +1 -0
  1501. package/build/dist/Utils/Slo/SloHealth.js +75 -9
  1502. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1503. package/build/dist/Utils/Slo/SloListWidgetFormat.js +217 -0
  1504. package/build/dist/Utils/Slo/SloListWidgetFormat.js.map +1 -0
  1505. package/build/dist/Utils/Slo/SloMetricType.js +212 -0
  1506. package/build/dist/Utils/Slo/SloMetricType.js.map +1 -0
  1507. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +216 -0
  1508. package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -0
  1509. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js +129 -0
  1510. package/build/dist/Utils/Slo/SloMonitorStatusSummary.js.map +1 -0
  1511. package/build/dist/Utils/Slo/SloOverviewText.js +110 -0
  1512. package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -0
  1513. package/build/dist/Utils/Slo/SloProjection.js +448 -0
  1514. package/build/dist/Utils/Slo/SloProjection.js.map +1 -0
  1515. package/build/dist/Utils/Slo/SloWidgetFormat.js +4 -2
  1516. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -1
  1517. package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
  1518. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  1519. package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
  1520. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  1521. package/build/dist/Utils/Telemetry/LockedFilterSearch.js +252 -0
  1522. package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
  1523. package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
  1524. package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
  1525. package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
  1526. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
  1527. package/build/dist/Utils/Traces/CriticalPath.js +9 -4
  1528. package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
  1529. package/package.json +1 -1
  1530. package/Server/API/GoogleSecOpsConnectionAPI.ts +0 -79
  1531. package/Server/Services/GoogleSecOpsConnectionService.ts +0 -101
  1532. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +0 -774
  1533. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +0 -423
  1534. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +0 -724
  1535. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +0 -248
  1536. package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +0 -153
  1537. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +0 -711
  1538. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +0 -838
  1539. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +0 -716
  1540. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +0 -860
  1541. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +0 -1231
  1542. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
  1543. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +0 -56
  1544. package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
  1545. package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
  1546. package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
  1547. package/UI/Components/GanttChart/Index.tsx +0 -90
  1548. package/UI/Components/GanttChart/Row/Index.tsx +0 -22
  1549. package/UI/Components/GanttChart/Row/Row.tsx +0 -231
  1550. package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
  1551. package/UI/Components/GanttChart/Rows.tsx +0 -59
  1552. package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
  1553. package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
  1554. package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
  1555. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +0 -1
  1556. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +0 -1
  1557. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +0 -56
  1558. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +0 -1
  1559. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +0 -1
  1560. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +0 -62
  1561. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +0 -1
  1562. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +0 -1
  1563. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +0 -577
  1564. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +0 -1
  1565. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +0 -1
  1566. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +0 -2
  1567. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +0 -1
  1568. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
  1569. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
  1570. package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
  1571. package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
  1572. package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
  1573. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
  1574. package/build/dist/UI/Components/GanttChart/Index.js +0 -39
  1575. package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
  1576. package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
  1577. package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
  1578. package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
  1579. package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
  1580. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
  1581. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
  1582. package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
  1583. package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
  1584. package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
  1585. package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
  1586. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
  1587. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
  1588. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
  1589. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js.map +0 -1
@@ -0,0 +1,2430 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { describe, expect, test } from "@jest/globals";
4
+ import {
5
+ AI_ROOT_CAUSE_HEADING_TEXT,
6
+ DEFAULT_EVENT_REFERENCE_LIMIT,
7
+ ExtractedInvestigationEventReference,
8
+ InvestigationEventReferenceToken,
9
+ InvestigationEvidenceCheckedEntry,
10
+ InvestigationReportSection,
11
+ InvestigationReportSectionKind,
12
+ ParsedInvestigationReport,
13
+ extractEventReferences,
14
+ getCitationMarkerRegex,
15
+ parseInvestigationReport,
16
+ tokenizeEventReferences,
17
+ } from "../../../Utils/AI/InvestigationReport";
18
+
19
+ /*
20
+ * The investigation panel lays the AI report out section by section, links
21
+ * the incidents it mentions and lists the evidence it checked; the API uses
22
+ * the same helpers to label evidence and resolve references. Every one of
23
+ * those reads model-authored text, so these tests pin both the formats a
24
+ * model actually produces and the places where it must NOT be believed
25
+ * (fenced code, a fake "Evidence checked" block, bold prose).
26
+ */
27
+
28
+ interface BrandedCitation {
29
+ id: string;
30
+ label: string;
31
+ rowCount: number;
32
+ }
33
+
34
+ /*
35
+ * A line-for-line copy of AIInvestigationEngine.buildBrandedMarkdown, so the
36
+ * parser is tested against the exact string the server posts. The source pin
37
+ * at the bottom of this file fails if the server format drifts.
38
+ */
39
+ function buildBrandedMarkdown(data: {
40
+ analysisMarkdown: string;
41
+ citations: Array<BrandedCitation>;
42
+ toolCallCount: number;
43
+ modelName?: string | undefined;
44
+ }): string {
45
+ let markdown: string = `## 🧠 AI — Automated Root Cause Analysis\n\n${data.analysisMarkdown}`;
46
+
47
+ if (data.citations.length > 0) {
48
+ markdown += `\n\n**Evidence checked**`;
49
+ for (const citation of data.citations.slice(0, 15)) {
50
+ markdown += `\n- **[${citation.id}]** ${citation.label} — ${citation.rowCount} row(s)`;
51
+ }
52
+ }
53
+
54
+ markdown += `\n\n---\n*Investigated automatically by OneUptime AI — read-only, ${data.toolCallCount} quer${
55
+ data.toolCallCount === 1 ? "y" : "ies"
56
+ } run across your own telemetry${
57
+ data.modelName ? ` using ${data.modelName}` : ""
58
+ }. This is an AI-generated first pass; verify before acting.*`;
59
+
60
+ return markdown;
61
+ }
62
+
63
+ const MODEL_ANALYSIS: string = [
64
+ "**Summary** — Checkout is failing because the payments database connection pool is exhausted [C2].",
65
+ "",
66
+ "**Most likely root cause** — Deploy 4711 cut the pool size from 50 to 5 [C3]. This matches prior incidents #6954 and #6963.",
67
+ "",
68
+ "**Evidence**",
69
+ "- Error rate on checkout-api jumped to 45% at 18:02 [C1].",
70
+ "- p95 connection wait went from 2ms to 3.4s [C2].",
71
+ "",
72
+ "**Suggested next steps**",
73
+ "1. Roll back deploy 4711.",
74
+ "2. Restore the pool size to 50.",
75
+ ].join("\n");
76
+
77
+ const CITATIONS: Array<BrandedCitation> = [
78
+ { id: "C1", label: "Active incidents (7 total)", rowCount: 7 },
79
+ { id: "C2", label: "Metric db.pool.wait — p95 — last hour", rowCount: 120 },
80
+ { id: "C3", label: 'Logs matching "pool size"', rowCount: 0 },
81
+ { id: "C4", label: "Incident #6954 timeline", rowCount: 1 },
82
+ ];
83
+
84
+ const SERVER_REPORT: string = buildBrandedMarkdown({
85
+ analysisMarkdown: MODEL_ANALYSIS,
86
+ citations: CITATIONS,
87
+ toolCallCount: 4,
88
+ modelName: "gpt-4.1-mini",
89
+ });
90
+
91
+ function kindsOf(
92
+ report: ParsedInvestigationReport,
93
+ ): Array<InvestigationReportSectionKind> {
94
+ return report.sections.map(
95
+ (section: InvestigationReportSection): InvestigationReportSectionKind => {
96
+ return section.kind;
97
+ },
98
+ );
99
+ }
100
+
101
+ function titlesOf(report: ParsedInvestigationReport): Array<string> {
102
+ return report.sections.map((section: InvestigationReportSection): string => {
103
+ return section.title;
104
+ });
105
+ }
106
+
107
+ function referencesOf(
108
+ text: string,
109
+ ): Array<{ kind: string | null; number: number; text: string }> {
110
+ return tokenizeEventReferences(text).map(
111
+ (
112
+ token: InvestigationEventReferenceToken,
113
+ ): { kind: string | null; number: number; text: string } => {
114
+ return {
115
+ kind: token.kind,
116
+ number: token.number,
117
+ text: text.slice(token.start, token.end),
118
+ };
119
+ },
120
+ );
121
+ }
122
+
123
+ describe("parseInvestigationReport — the real server format", () => {
124
+ const report: ParsedInvestigationReport =
125
+ parseInvestigationReport(SERVER_REPORT);
126
+
127
+ test("recognises the four sections the investigation persona asks for, in order", () => {
128
+ expect(report.isStructured).toBe(true);
129
+ expect(kindsOf(report)).toEqual([
130
+ InvestigationReportSectionKind.Summary,
131
+ InvestigationReportSectionKind.RootCause,
132
+ InvestigationReportSectionKind.Evidence,
133
+ InvestigationReportSectionKind.NextSteps,
134
+ ]);
135
+ expect(titlesOf(report)).toEqual([
136
+ "Summary",
137
+ "Most likely root cause",
138
+ "Evidence",
139
+ "Suggested next steps",
140
+ ]);
141
+ });
142
+
143
+ test("section bodies drop the label and its separator but keep citations and references verbatim", () => {
144
+ expect(report.summary).toBe(
145
+ "Checkout is failing because the payments database connection pool is exhausted [C2].",
146
+ );
147
+ expect(report.rootCause).toBe(
148
+ "Deploy 4711 cut the pool size from 50 to 5 [C3]. This matches prior incidents #6954 and #6963.",
149
+ );
150
+ expect(report.evidence).toBe(
151
+ "- Error rate on checkout-api jumped to 45% at 18:02 [C1].\n- p95 connection wait went from 2ms to 3.4s [C2].",
152
+ );
153
+ expect(report.nextSteps).toBe(
154
+ "1. Roll back deploy 4711.\n2. Restore the pool size to 50.",
155
+ );
156
+ });
157
+
158
+ test("the Suggested next steps body does not swallow the Evidence checked list or the footer", () => {
159
+ expect(report.nextSteps).not.toContain("Evidence checked");
160
+ expect(report.nextSteps).not.toContain("[C1]**");
161
+ expect(report.nextSteps).not.toContain("Investigated automatically");
162
+ });
163
+
164
+ test("the convenience fields mirror the sections array", () => {
165
+ for (const section of report.sections) {
166
+ if (section.kind === InvestigationReportSectionKind.Summary) {
167
+ expect(report.summary).toBe(section.markdown);
168
+ }
169
+ if (section.kind === InvestigationReportSectionKind.NextSteps) {
170
+ expect(report.nextSteps).toBe(section.markdown);
171
+ }
172
+ }
173
+ });
174
+
175
+ test("there is no preamble: the brand heading is dropped", () => {
176
+ expect(report.preamble).toBe("");
177
+ });
178
+
179
+ test("parses the Evidence checked list, keeping labels that contain ' — '", () => {
180
+ const expected: Array<InvestigationEvidenceCheckedEntry> = [
181
+ { citationId: "C1", label: "Active incidents (7 total)", rowCount: 7 },
182
+ {
183
+ citationId: "C2",
184
+ label: "Metric db.pool.wait — p95 — last hour",
185
+ rowCount: 120,
186
+ },
187
+ { citationId: "C3", label: 'Logs matching "pool size"', rowCount: 0 },
188
+ { citationId: "C4", label: "Incident #6954 timeline", rowCount: 1 },
189
+ ];
190
+
191
+ expect(report.evidenceChecked).toEqual(expected);
192
+ });
193
+
194
+ test("parses the footer: text without emphasis, model name and query count", () => {
195
+ expect(report.footer).toEqual({
196
+ text: "Investigated automatically by OneUptime AI — read-only, 4 queries run across your own telemetry using gpt-4.1-mini. This is an AI-generated first pass; verify before acting.",
197
+ modelName: "gpt-4.1-mini",
198
+ queryCount: 4,
199
+ });
200
+ });
201
+
202
+ test("bodyMarkdown keeps the model's note but not the brand heading, evidence list or footer", () => {
203
+ expect(report.bodyMarkdown).toBe(MODEL_ANALYSIS);
204
+ expect(report.bodyMarkdown).not.toContain(AI_ROOT_CAUSE_HEADING_TEXT);
205
+ expect(report.bodyMarkdown).not.toContain("Evidence checked");
206
+ expect(report.bodyMarkdown).not.toContain("---");
207
+ expect(report.bodyMarkdown).not.toContain("Investigated automatically");
208
+ });
209
+
210
+ test("a report with no citations has no Evidence checked entries but still has a footer", () => {
211
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
212
+ buildBrandedMarkdown({
213
+ analysisMarkdown: MODEL_ANALYSIS,
214
+ citations: [],
215
+ toolCallCount: 0,
216
+ }),
217
+ );
218
+
219
+ expect(parsed.evidenceChecked).toEqual([]);
220
+ expect(parsed.footer?.queryCount).toBe(0);
221
+ expect(parsed.footer?.modelName).toBeUndefined();
222
+ expect(parsed.bodyMarkdown).toBe(MODEL_ANALYSIS);
223
+ expect(parsed.nextSteps).toBe(
224
+ "1. Roll back deploy 4711.\n2. Restore the pool size to 50.",
225
+ );
226
+ });
227
+
228
+ test("only the first 15 citations appear in the server list, and all of them parse", () => {
229
+ const many: Array<BrandedCitation> = [];
230
+ for (let index: number = 1; index <= 20; index++) {
231
+ many.push({ id: `C${index}`, label: `Query ${index}`, rowCount: index });
232
+ }
233
+
234
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
235
+ buildBrandedMarkdown({
236
+ analysisMarkdown: MODEL_ANALYSIS,
237
+ citations: many,
238
+ toolCallCount: 20,
239
+ }),
240
+ );
241
+
242
+ expect(parsed.evidenceChecked).toHaveLength(15);
243
+ expect(parsed.evidenceChecked[14]).toEqual({
244
+ citationId: "C15",
245
+ label: "Query 15",
246
+ rowCount: 15,
247
+ });
248
+ });
249
+
250
+ test("the legacy brand heading without the emoji is dropped too", () => {
251
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
252
+ `## ${AI_ROOT_CAUSE_HEADING_TEXT}\n\nThe incident was caused by connection exhaustion.`,
253
+ );
254
+
255
+ expect(parsed.bodyMarkdown).toBe(
256
+ "The incident was caused by connection exhaustion.",
257
+ );
258
+ expect(parsed.preamble).toBe(
259
+ "The incident was caused by connection exhaustion.",
260
+ );
261
+ expect(parsed.isStructured).toBe(false);
262
+ expect(parsed.sections).toEqual([]);
263
+ });
264
+
265
+ test("a brand-like heading that is not the first line is ordinary content", () => {
266
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
267
+ "Intro line.\n\n## AI — Automated Root Cause Analysis\n\n**Summary** — pool ran dry.",
268
+ );
269
+
270
+ expect(parsed.preamble).toBe(
271
+ "Intro line.\n\n## AI — Automated Root Cause Analysis",
272
+ );
273
+ expect(parsed.summary).toBe("pool ran dry.");
274
+ });
275
+ });
276
+
277
+ describe("parseInvestigationReport — section label styles", () => {
278
+ test("## heading style", () => {
279
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
280
+ [
281
+ "## Summary",
282
+ "",
283
+ "The pool ran dry [C1].",
284
+ "",
285
+ "## Most likely root cause",
286
+ "",
287
+ "Deploy 4711.",
288
+ "",
289
+ "### Evidence",
290
+ "- Wait time spiked [C2].",
291
+ "",
292
+ "# Suggested next steps ##",
293
+ "Roll back.",
294
+ ].join("\n"),
295
+ );
296
+
297
+ expect(parsed.isStructured).toBe(true);
298
+ expect(kindsOf(parsed)).toEqual([
299
+ InvestigationReportSectionKind.Summary,
300
+ InvestigationReportSectionKind.RootCause,
301
+ InvestigationReportSectionKind.Evidence,
302
+ InvestigationReportSectionKind.NextSteps,
303
+ ]);
304
+ expect(parsed.summary).toBe("The pool ran dry [C1].");
305
+ expect(parsed.rootCause).toBe("Deploy 4711.");
306
+ expect(parsed.evidence).toBe("- Wait time spiked [C2].");
307
+ expect(parsed.nextSteps).toBe("Roll back.");
308
+ expect(titlesOf(parsed)[3]).toBe("Suggested next steps");
309
+ });
310
+
311
+ test("**Summary:** with the body on the same line and on the following lines", () => {
312
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
313
+ [
314
+ "**Summary:** The pool ran dry.",
315
+ "It started at 18:01.",
316
+ "",
317
+ "**Most likely root cause:**",
318
+ "Deploy 4711.",
319
+ ].join("\n"),
320
+ );
321
+
322
+ expect(parsed.summary).toBe("The pool ran dry.\nIt started at 18:01.");
323
+ expect(parsed.rootCause).toBe("Deploy 4711.");
324
+ expect(titlesOf(parsed)).toEqual(["Summary", "Most likely root cause"]);
325
+ });
326
+
327
+ test("**Summary**: with the colon outside the emphasis", () => {
328
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
329
+ "**Summary**: The pool ran dry.\n\n**Root cause**:\nDeploy 4711.",
330
+ );
331
+
332
+ expect(parsed.summary).toBe("The pool ran dry.");
333
+ expect(parsed.rootCause).toBe("Deploy 4711.");
334
+ });
335
+
336
+ test("plain Summary: labels at the start of a line", () => {
337
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
338
+ [
339
+ "Summary: The pool ran dry.",
340
+ "",
341
+ "Most likely root cause: Deploy 4711.",
342
+ "",
343
+ "Next steps:",
344
+ "- Roll back.",
345
+ ].join("\n"),
346
+ );
347
+
348
+ expect(kindsOf(parsed)).toEqual([
349
+ InvestigationReportSectionKind.Summary,
350
+ InvestigationReportSectionKind.RootCause,
351
+ InvestigationReportSectionKind.NextSteps,
352
+ ]);
353
+ expect(parsed.summary).toBe("The pool ran dry.");
354
+ expect(parsed.rootCause).toBe("Deploy 4711.");
355
+ expect(parsed.nextSteps).toBe("- Roll back.");
356
+ });
357
+
358
+ test("a plain 'Label:' line only counts for known labels", () => {
359
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
360
+ "**Summary** — ok.\n\nImpact: checkout is down.\nNote: none.",
361
+ );
362
+
363
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
364
+ expect(parsed.summary).toBe(
365
+ "ok.\n\nImpact: checkout is down.\nNote: none.",
366
+ );
367
+ });
368
+
369
+ test("**Summary** — text on the same line, with em dash, en dash, hyphen and double hyphen", () => {
370
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
371
+ [
372
+ "**Summary** — em dash body.",
373
+ "**Most likely root cause** – en dash body.",
374
+ "**Evidence** - hyphen body.",
375
+ "**Next steps** -- double hyphen body.",
376
+ ].join("\n"),
377
+ );
378
+
379
+ expect(parsed.summary).toBe("em dash body.");
380
+ expect(parsed.rootCause).toBe("en dash body.");
381
+ expect(parsed.evidence).toBe("hyphen body.");
382
+ expect(parsed.nextSteps).toBe("double hyphen body.");
383
+ });
384
+
385
+ test("a separator with no space before it still splits", () => {
386
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
387
+ "**Summary**—tight em dash.",
388
+ );
389
+
390
+ expect(parsed.summary).toBe("tight em dash.");
391
+ });
392
+
393
+ test("__Label__ and ***Label*** emphasis", () => {
394
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
395
+ "__Summary__\nUnderscore body.\n\n***Most likely root cause*** — bold italic body.",
396
+ );
397
+
398
+ expect(parsed.summary).toBe("Underscore body.");
399
+ expect(parsed.rootCause).toBe("bold italic body.");
400
+ expect(titlesOf(parsed)).toEqual(["Summary", "Most likely root cause"]);
401
+ });
402
+
403
+ test("label matching is case-insensitive and keeps the title as written", () => {
404
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
405
+ "**SUMMARY**\nLoud.\n\n## most likely ROOT cause\nQuiet.",
406
+ );
407
+
408
+ expect(kindsOf(parsed)).toEqual([
409
+ InvestigationReportSectionKind.Summary,
410
+ InvestigationReportSectionKind.RootCause,
411
+ ]);
412
+ expect(titlesOf(parsed)).toEqual(["SUMMARY", "most likely ROOT cause"]);
413
+ });
414
+
415
+ test("headings with emphasis, a trailing colon or a separator and body", () => {
416
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
417
+ [
418
+ "## **Summary:**",
419
+ "One.",
420
+ "## Root cause: Deploy 4711.",
421
+ "## Evidence — see below",
422
+ "- Two.",
423
+ "## **Next steps** — Roll back.",
424
+ ].join("\n"),
425
+ );
426
+
427
+ expect(kindsOf(parsed)).toEqual([
428
+ InvestigationReportSectionKind.Summary,
429
+ InvestigationReportSectionKind.RootCause,
430
+ InvestigationReportSectionKind.Evidence,
431
+ InvestigationReportSectionKind.NextSteps,
432
+ ]);
433
+ expect(parsed.summary).toBe("One.");
434
+ expect(parsed.rootCause).toBe("Deploy 4711.");
435
+ expect(parsed.evidence).toBe("see below\n- Two.");
436
+ expect(parsed.nextSteps).toBe("Roll back.");
437
+ });
438
+
439
+ test("decorative emoji and numbering in front of a heading are ignored for matching and the title", () => {
440
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
441
+ "## 🔍 Summary\nA.\n\n### ⚠️ Most likely root cause\nB.\n\n## 3. Next steps\nC.",
442
+ );
443
+
444
+ expect(kindsOf(parsed)).toEqual([
445
+ InvestigationReportSectionKind.Summary,
446
+ InvestigationReportSectionKind.RootCause,
447
+ InvestigationReportSectionKind.NextSteps,
448
+ ]);
449
+ expect(titlesOf(parsed)).toEqual([
450
+ "Summary",
451
+ "Most likely root cause",
452
+ "Next steps",
453
+ ]);
454
+ });
455
+
456
+ test("a confidence qualifier after the label keeps the section and lands in the title", () => {
457
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
458
+ [
459
+ "**Summary** — A.",
460
+ "**Most likely root cause** (medium confidence) — Deploy 4711.",
461
+ "**Evidence (partial)**",
462
+ "- B.",
463
+ "Next steps (urgent): Roll back.",
464
+ ].join("\n"),
465
+ );
466
+
467
+ expect(kindsOf(parsed)).toEqual([
468
+ InvestigationReportSectionKind.Summary,
469
+ InvestigationReportSectionKind.RootCause,
470
+ InvestigationReportSectionKind.Evidence,
471
+ InvestigationReportSectionKind.NextSteps,
472
+ ]);
473
+ expect(titlesOf(parsed)).toEqual([
474
+ "Summary",
475
+ "Most likely root cause (medium confidence)",
476
+ "Evidence (partial)",
477
+ "Next steps (urgent)",
478
+ ]);
479
+ expect(parsed.rootCause).toBe("Deploy 4711.");
480
+ expect(parsed.nextSteps).toBe("Roll back.");
481
+ });
482
+
483
+ test.each([
484
+ ["Summary", InvestigationReportSectionKind.Summary],
485
+ ["TL;DR", InvestigationReportSectionKind.Summary],
486
+ ["TLDR", InvestigationReportSectionKind.Summary],
487
+ ["Most likely root cause", InvestigationReportSectionKind.RootCause],
488
+ ["Likely root cause", InvestigationReportSectionKind.RootCause],
489
+ ["Probable root cause", InvestigationReportSectionKind.RootCause],
490
+ ["Root cause", InvestigationReportSectionKind.RootCause],
491
+ ["Root cause hypothesis", InvestigationReportSectionKind.RootCause],
492
+ ["Evidence", InvestigationReportSectionKind.Evidence],
493
+ ["Key evidence", InvestigationReportSectionKind.Evidence],
494
+ ["Supporting evidence", InvestigationReportSectionKind.Evidence],
495
+ ["Key findings", InvestigationReportSectionKind.Evidence],
496
+ ["Findings", InvestigationReportSectionKind.Evidence],
497
+ ["Suggested next steps", InvestigationReportSectionKind.NextSteps],
498
+ ["Next steps", InvestigationReportSectionKind.NextSteps],
499
+ ["Recommended next steps", InvestigationReportSectionKind.NextSteps],
500
+ ["Recommended actions", InvestigationReportSectionKind.NextSteps],
501
+ ["Recommendations", InvestigationReportSectionKind.NextSteps],
502
+ ])(
503
+ "known label %p maps to %p in every label style",
504
+ (label: string, kind: InvestigationReportSectionKind) => {
505
+ const styles: Array<string> = [
506
+ `## ${label}\nBody.`,
507
+ `**${label}**\nBody.`,
508
+ `**${label}:** Body.`,
509
+ `**${label}** — Body.`,
510
+ `${label}: Body.`,
511
+ ];
512
+
513
+ for (const style of styles) {
514
+ const parsed: ParsedInvestigationReport =
515
+ parseInvestigationReport(style);
516
+
517
+ expect(parsed.sections).toEqual([
518
+ { kind, title: label, markdown: "Body." },
519
+ ]);
520
+ }
521
+ },
522
+ );
523
+
524
+ test("a bold phrase followed by prose is not a label", () => {
525
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
526
+ "**Summary** — A.\n\n**Root cause** is still unclear.\n**Evidence** points both ways.",
527
+ );
528
+
529
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
530
+ expect(parsed.summary).toBe(
531
+ "A.\n\n**Root cause** is still unclear.\n**Evidence** points both ways.",
532
+ );
533
+ });
534
+
535
+ test("an indented (code block) label is not a section", () => {
536
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
537
+ "**Summary** — A.\n\n **Most likely root cause** — not a heading\n\tRoot cause: nope",
538
+ );
539
+
540
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
541
+ expect(parsed.summary).toContain("not a heading");
542
+ });
543
+
544
+ test("a label inside a list item or blockquote is not a section", () => {
545
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
546
+ "**Summary** — A.\n\n- **Root cause** — in a list\n> **Evidence** — in a quote",
547
+ );
548
+
549
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
550
+ });
551
+
552
+ test("a confidence qualifier after a colon inside the bold keeps the section", () => {
553
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
554
+ "**Summary** — A.\n\n**Most likely root cause:** (medium confidence) A connection leak [C2].\n\n**Evidence**\n- x",
555
+ );
556
+
557
+ expect(kindsOf(parsed)).toEqual([
558
+ InvestigationReportSectionKind.Summary,
559
+ InvestigationReportSectionKind.RootCause,
560
+ InvestigationReportSectionKind.Evidence,
561
+ ]);
562
+ expect(titlesOf(parsed)[1]).toBe(
563
+ "Most likely root cause (medium confidence)",
564
+ );
565
+ expect(parsed.rootCause).toBe("A connection leak [C2].");
566
+ expect(parsed.summary).toBe("A.");
567
+ });
568
+
569
+ test("a bold phrase, a qualifier and then prose is still not a label", () => {
570
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
571
+ "**Summary** — A.\n\n**Root cause** (low confidence) is unclear.\n**Impact:** (high) users could not pay.",
572
+ );
573
+
574
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
575
+ expect(parsed.rootCause).toBeUndefined();
576
+ expect(parsed.summary).toBe(
577
+ "A.\n\n**Root cause** (low confidence) is unclear.\n**Impact:** (high) users could not pay.",
578
+ );
579
+ });
580
+
581
+ /*
582
+ * An indented line under a list item continues that item. Read as a
583
+ * label, it cut the list in two and handed the rest of it to another
584
+ * section, even to the root cause callout.
585
+ */
586
+ test.each([
587
+ [
588
+ "a bold-only line under a numbered item",
589
+ "**Suggested next steps**\n1. Roll back the deploy\n **Why**\n because the pool is exhausted\n2. Page the DB team",
590
+ InvestigationReportSectionKind.NextSteps,
591
+ ],
592
+ [
593
+ "a bold-only line under a bullet",
594
+ "**Evidence**\n- pool exhausted\n **Detail**\n more\n- error rate up",
595
+ InvestigationReportSectionKind.Evidence,
596
+ ],
597
+ [
598
+ "a known plain label under a numbered item",
599
+ "**Suggested next steps**\n1. Roll back the deploy\n Evidence: pool at 100%\n2. Page the DB team",
600
+ InvestigationReportSectionKind.NextSteps,
601
+ ],
602
+ [
603
+ "a known bold label with a body under a numbered item",
604
+ "**Evidence**\n1. Pool saturation hit 100% [C1].\n **Root cause:** a missing release() call [C2].\n2. Error rate rose 30x [C3].",
605
+ InvestigationReportSectionKind.Evidence,
606
+ ],
607
+ [
608
+ "a heading under a bullet",
609
+ "**Evidence**\n- pool exhausted\n ## Detail\n- error rate up",
610
+ InvestigationReportSectionKind.Evidence,
611
+ ],
612
+ [
613
+ "a label after a blank line inside the item",
614
+ "**Suggested next steps**\n1. Roll back the deploy\n\n **Why**\n\n because the pool is exhausted\n2. Page the DB team",
615
+ InvestigationReportSectionKind.NextSteps,
616
+ ],
617
+ ])(
618
+ "%s stays inside its list",
619
+ (_name: string, section: string, kind: InvestigationReportSectionKind) => {
620
+ const body: string = section.slice(section.indexOf("\n") + 1);
621
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
622
+ `**Summary** — Checkout 500s.\n\n${section}`,
623
+ );
624
+
625
+ expect(parsed.sections).toEqual([
626
+ {
627
+ kind: InvestigationReportSectionKind.Summary,
628
+ title: "Summary",
629
+ markdown: "Checkout 500s.",
630
+ },
631
+ {
632
+ kind,
633
+ title: section.slice(2, section.indexOf("**", 2)),
634
+ markdown: body,
635
+ },
636
+ ]);
637
+ expect(parsed.rootCause).toBeUndefined();
638
+ },
639
+ );
640
+
641
+ test("a label at the start of a line after a list is a section again", () => {
642
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
643
+ [
644
+ "**Summary** — A.",
645
+ "",
646
+ "**Evidence**",
647
+ "- pool exhausted",
648
+ " still the same item",
649
+ "**Suggested next steps**",
650
+ "- Roll back",
651
+ " **Why**",
652
+ "",
653
+ "Paragraph after the list.",
654
+ " **Most likely root cause** — B.",
655
+ ].join("\n"),
656
+ );
657
+
658
+ expect(kindsOf(parsed)).toEqual([
659
+ InvestigationReportSectionKind.Summary,
660
+ InvestigationReportSectionKind.Evidence,
661
+ InvestigationReportSectionKind.NextSteps,
662
+ InvestigationReportSectionKind.RootCause,
663
+ ]);
664
+ expect(parsed.evidence).toBe("- pool exhausted\n still the same item");
665
+ expect(parsed.nextSteps).toBe(
666
+ "- Roll back\n **Why**\n\nParagraph after the list.",
667
+ );
668
+ expect(parsed.rootCause).toBe("B.");
669
+ });
670
+
671
+ test("an indented label that is not inside a list is still a label", () => {
672
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
673
+ "**Summary** — A.\n\n **Most likely root cause** — B.",
674
+ );
675
+
676
+ expect(parsed.rootCause).toBe("B.");
677
+ });
678
+
679
+ test("repeated sections are all kept; convenience fields use the first", () => {
680
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
681
+ "**Summary** — first.\n\n**Evidence** — one.\n\n**Summary** — second.",
682
+ );
683
+
684
+ expect(kindsOf(parsed)).toEqual([
685
+ InvestigationReportSectionKind.Summary,
686
+ InvestigationReportSectionKind.Evidence,
687
+ InvestigationReportSectionKind.Summary,
688
+ ]);
689
+ expect(parsed.summary).toBe("first.");
690
+ });
691
+ });
692
+
693
+ describe("parseInvestigationReport — missing, empty and unknown sections", () => {
694
+ test("missing sections are undefined; Summary alone makes the report structured", () => {
695
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
696
+ "**Summary** — A.\n\n**Suggested next steps**\n- Roll back.",
697
+ );
698
+
699
+ expect(parsed.isStructured).toBe(true);
700
+ expect(parsed.summary).toBe("A.");
701
+ expect(parsed.rootCause).toBeUndefined();
702
+ expect(parsed.evidence).toBeUndefined();
703
+ expect(parsed.nextSteps).toBe("- Roll back.");
704
+ });
705
+
706
+ test("a root cause alone makes the report structured", () => {
707
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
708
+ "Root cause: Deploy 4711.",
709
+ );
710
+
711
+ expect(parsed.isStructured).toBe(true);
712
+ expect(parsed.summary).toBeUndefined();
713
+ });
714
+
715
+ test("Evidence and Next steps without Summary or root cause are not structured, but still split", () => {
716
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
717
+ "I looked around.\n\n**Evidence**\n- A.\n\n**Next steps**\n- B.",
718
+ );
719
+
720
+ expect(parsed.isStructured).toBe(false);
721
+ expect(parsed.preamble).toBe("I looked around.");
722
+ expect(kindsOf(parsed)).toEqual([
723
+ InvestigationReportSectionKind.Evidence,
724
+ InvestigationReportSectionKind.NextSteps,
725
+ ]);
726
+ expect(parsed.bodyMarkdown).toBe(
727
+ "I looked around.\n\n**Evidence**\n- A.\n\n**Next steps**\n- B.",
728
+ );
729
+ });
730
+
731
+ test("an unstructured note is the preamble and the whole body", () => {
732
+ const note: string =
733
+ "The evidence was inconclusive. I checked logs and metrics but found nothing unusual.";
734
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(note);
735
+
736
+ expect(parsed.isStructured).toBe(false);
737
+ expect(parsed.sections).toEqual([]);
738
+ expect(parsed.preamble).toBe(note);
739
+ expect(parsed.bodyMarkdown).toBe(note);
740
+ });
741
+
742
+ test("sections with no body are dropped, and do not make the report structured", () => {
743
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
744
+ "**Summary**\n\n**Most likely root cause**\n\n**Evidence**\n- A.",
745
+ );
746
+
747
+ expect(parsed.isStructured).toBe(false);
748
+ expect(parsed.sections).toEqual([
749
+ {
750
+ kind: InvestigationReportSectionKind.Evidence,
751
+ title: "Evidence",
752
+ markdown: "- A.",
753
+ },
754
+ ]);
755
+ expect(parsed.summary).toBeUndefined();
756
+ expect(parsed.preamble).toBe("");
757
+ });
758
+
759
+ /*
760
+ * A section whose body opens with a sub-label used to be dropped as
761
+ * empty, taking its title and kind with it: the root cause callout never
762
+ * rendered, and the sub-label became an unrelated Other section.
763
+ */
764
+ test("a root cause that is only a sub-heading keeps its section", () => {
765
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
766
+ "## Summary\nCheckout latency spiked.\n## Most likely root cause\n### Inconclusive\n## Evidence\n- x",
767
+ );
768
+
769
+ expect(parsed.sections).toEqual([
770
+ {
771
+ kind: InvestigationReportSectionKind.Summary,
772
+ title: "Summary",
773
+ markdown: "Checkout latency spiked.",
774
+ },
775
+ {
776
+ kind: InvestigationReportSectionKind.RootCause,
777
+ title: "Most likely root cause",
778
+ markdown: "### Inconclusive",
779
+ },
780
+ {
781
+ kind: InvestigationReportSectionKind.Evidence,
782
+ title: "Evidence",
783
+ markdown: "- x",
784
+ },
785
+ ]);
786
+ expect(parsed.isStructured).toBe(true);
787
+ });
788
+
789
+ test("a root cause that opens with a sub-heading keeps the sub-heading and its body", () => {
790
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
791
+ "## Most likely root cause\n### Connection pool exhaustion\nThe pool hit 100%.",
792
+ );
793
+
794
+ expect(parsed.sections).toEqual([
795
+ {
796
+ kind: InvestigationReportSectionKind.RootCause,
797
+ title: "Most likely root cause",
798
+ markdown: "### Connection pool exhaustion\nThe pool hit 100%.",
799
+ },
800
+ ]);
801
+ expect(parsed.rootCause).toBe(
802
+ "### Connection pool exhaustion\nThe pool hit 100%.",
803
+ );
804
+ });
805
+
806
+ test("sub-headings under recognised headings stay inside those sections", () => {
807
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
808
+ [
809
+ "## Summary",
810
+ "x",
811
+ "",
812
+ "## Most likely root cause",
813
+ "y",
814
+ "",
815
+ "## Evidence",
816
+ "### Metrics",
817
+ "- pool 100% [C1]",
818
+ "### Logs",
819
+ "- timeouts",
820
+ "",
821
+ "## Suggested next steps",
822
+ "### Immediate",
823
+ "- Roll back",
824
+ "### Longer term",
825
+ "- Add alerting",
826
+ "",
827
+ "## Timeline",
828
+ "- 18:01 deploy",
829
+ ].join("\n"),
830
+ );
831
+
832
+ expect(kindsOf(parsed)).toEqual([
833
+ InvestigationReportSectionKind.Summary,
834
+ InvestigationReportSectionKind.RootCause,
835
+ InvestigationReportSectionKind.Evidence,
836
+ InvestigationReportSectionKind.NextSteps,
837
+ InvestigationReportSectionKind.Other,
838
+ ]);
839
+ expect(parsed.evidence).toBe(
840
+ "### Metrics\n- pool 100% [C1]\n### Logs\n- timeouts",
841
+ );
842
+ expect(parsed.nextSteps).toBe(
843
+ "### Immediate\n- Roll back\n### Longer term\n- Add alerting",
844
+ );
845
+ // A heading at the section's own level is still a new section.
846
+ expect(parsed.sections[4]).toEqual({
847
+ kind: InvestigationReportSectionKind.Other,
848
+ title: "Timeline",
849
+ markdown: "- 18:01 deploy",
850
+ });
851
+ });
852
+
853
+ test("a bold label with no body groups the labels directly under it", () => {
854
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
855
+ [
856
+ "**Summary** — A.",
857
+ "",
858
+ "**Suggested next steps**",
859
+ "### Immediate",
860
+ "- Roll back",
861
+ "### Longer term",
862
+ "- Add alerting",
863
+ "",
864
+ "**Evidence**",
865
+ "**Ruled out:**",
866
+ "**Supports:**",
867
+ "- pool 100%",
868
+ ].join("\n"),
869
+ );
870
+
871
+ expect(kindsOf(parsed)).toEqual([
872
+ InvestigationReportSectionKind.Summary,
873
+ InvestigationReportSectionKind.NextSteps,
874
+ InvestigationReportSectionKind.Evidence,
875
+ ]);
876
+ expect(parsed.nextSteps).toBe(
877
+ "### Immediate\n- Roll back\n### Longer term\n- Add alerting",
878
+ );
879
+ expect(parsed.evidence).toBe("**Ruled out:**\n**Supports:**\n- pool 100%");
880
+ });
881
+
882
+ test("an unknown label with no body groups the label under it", () => {
883
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
884
+ "**Summary** — A.\n\n**Impact**\n**Customers**\n- EU checkout down\n\n## Timeline\n### Before\n- 18:01 deploy",
885
+ );
886
+
887
+ expect(parsed.sections).toEqual([
888
+ {
889
+ kind: InvestigationReportSectionKind.Summary,
890
+ title: "Summary",
891
+ markdown: "A.",
892
+ },
893
+ {
894
+ kind: InvestigationReportSectionKind.Other,
895
+ title: "Impact",
896
+ markdown: "**Customers**\n- EU checkout down",
897
+ },
898
+ {
899
+ kind: InvestigationReportSectionKind.Other,
900
+ title: "Timeline",
901
+ markdown: "### Before\n- 18:01 deploy",
902
+ },
903
+ ]);
904
+ });
905
+
906
+ test("a label with nothing under it stays a line of the section before it", () => {
907
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
908
+ "**Summary** — x\n\n**Suggested next steps**\n1. Roll back\n**Confidence: medium**\n\n## Owner",
909
+ );
910
+
911
+ expect(kindsOf(parsed)).toEqual([
912
+ InvestigationReportSectionKind.Summary,
913
+ InvestigationReportSectionKind.NextSteps,
914
+ ]);
915
+ expect(parsed.nextSteps).toBe(
916
+ "1. Roll back\n**Confidence: medium**\n\n## Owner",
917
+ );
918
+ });
919
+
920
+ test("a heading at the same level is a peer, never a sub-label", () => {
921
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
922
+ "## Summary\nA.\n## Impact\n## Timeline\n- 18:01\n## Most likely root cause\n## Open questions\n- Why?",
923
+ );
924
+
925
+ expect(parsed.sections).toEqual([
926
+ {
927
+ kind: InvestigationReportSectionKind.Summary,
928
+ title: "Summary",
929
+ markdown: "A.\n## Impact",
930
+ },
931
+ {
932
+ kind: InvestigationReportSectionKind.Other,
933
+ title: "Timeline",
934
+ markdown: "- 18:01",
935
+ },
936
+ {
937
+ kind: InvestigationReportSectionKind.Other,
938
+ title: "Open questions",
939
+ markdown: "- Why?",
940
+ },
941
+ ]);
942
+ // An empty recognised heading followed by a peer is dropped, as before.
943
+ expect(parsed.rootCause).toBeUndefined();
944
+ });
945
+
946
+ test("unknown headings and bold-only lines AFTER the first recognised section become Other sections", () => {
947
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
948
+ [
949
+ "**Summary** — A.",
950
+ "",
951
+ "**Impact**",
952
+ "Checkout is down for EU users.",
953
+ "",
954
+ "## Timeline:",
955
+ "- 18:01 deploy",
956
+ "",
957
+ "**Suggested next steps**",
958
+ "- Roll back.",
959
+ "",
960
+ "### Open questions",
961
+ "Why did the canary pass?",
962
+ ].join("\n"),
963
+ );
964
+
965
+ expect(parsed.sections).toEqual([
966
+ {
967
+ kind: InvestigationReportSectionKind.Summary,
968
+ title: "Summary",
969
+ markdown: "A.",
970
+ },
971
+ {
972
+ kind: InvestigationReportSectionKind.Other,
973
+ title: "Impact",
974
+ markdown: "Checkout is down for EU users.",
975
+ },
976
+ {
977
+ kind: InvestigationReportSectionKind.Other,
978
+ title: "Timeline",
979
+ markdown: "- 18:01 deploy",
980
+ },
981
+ {
982
+ kind: InvestigationReportSectionKind.NextSteps,
983
+ title: "Suggested next steps",
984
+ markdown: "- Roll back.",
985
+ },
986
+ {
987
+ kind: InvestigationReportSectionKind.Other,
988
+ title: "Open questions",
989
+ markdown: "Why did the canary pass?",
990
+ },
991
+ ]);
992
+ });
993
+
994
+ test("unknown headings BEFORE the first recognised section stay in the preamble", () => {
995
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
996
+ "## Context\nSomething odd.\n\n**Background**\nMore.\n\n**Summary** — A.",
997
+ );
998
+
999
+ expect(parsed.preamble).toBe(
1000
+ "## Context\nSomething odd.\n\n**Background**\nMore.",
1001
+ );
1002
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
1003
+ });
1004
+
1005
+ test("bold sentences, bold lines with citations and very long bold lines are prose, not Other sections", () => {
1006
+ const longBold: string = `**${"very ".repeat(20)}long emphasis**`;
1007
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1008
+ [
1009
+ "**Evidence**",
1010
+ "**The pool was exhausted at 18:01.**",
1011
+ "**Wait time spiked [C2]**",
1012
+ longBold,
1013
+ "**Root cause: pool exhaustion** is likely",
1014
+ "**Impact:** users could not pay",
1015
+ ].join("\n"),
1016
+ );
1017
+
1018
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Evidence]);
1019
+ expect(parsed.evidence).toContain("**The pool was exhausted at 18:01.**");
1020
+ expect(parsed.evidence).toContain("[C2]");
1021
+ expect(parsed.evidence).toContain(longBold);
1022
+ expect(parsed.evidence).toContain("**Impact:** users could not pay");
1023
+ });
1024
+
1025
+ test("a heading named like an Object prototype member is just an Other section", () => {
1026
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1027
+ "**Summary** — A.\n\n## constructor\nB.\n\n## toString\nC.\n\n**hasOwnProperty**\nD.",
1028
+ );
1029
+
1030
+ expect(kindsOf(parsed)).toEqual([
1031
+ InvestigationReportSectionKind.Summary,
1032
+ InvestigationReportSectionKind.Other,
1033
+ InvestigationReportSectionKind.Other,
1034
+ InvestigationReportSectionKind.Other,
1035
+ ]);
1036
+ expect(titlesOf(parsed)).toEqual([
1037
+ "Summary",
1038
+ "constructor",
1039
+ "toString",
1040
+ "hasOwnProperty",
1041
+ ]);
1042
+ });
1043
+
1044
+ test("thematic breaks and punctuation-only bold lines are not Other sections", () => {
1045
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1046
+ "**Summary** — A.\n\n*****\n\n**_**\n\n** **\n\nB.",
1047
+ );
1048
+
1049
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
1050
+ expect(parsed.summary).toBe("A.\n\n*****\n\n**_**\n\n** **\n\nB.");
1051
+ });
1052
+
1053
+ test("a block cut out right after an inline body keeps the following prose a separate paragraph", () => {
1054
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1055
+ "**Summary** — A.\n**Evidence checked**\n- **[C1]** One — 1 row(s)\nAfter.",
1056
+ );
1057
+
1058
+ expect(parsed.summary).toBe("A.\n\nAfter.");
1059
+ expect(parsed.bodyMarkdown).toBe("**Summary** — A.\n\nAfter.");
1060
+ });
1061
+
1062
+ test("paragraphs after an inline body stay separate paragraphs", () => {
1063
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1064
+ "**Summary** — First paragraph.\n\nSecond paragraph.\n\n\nThird.",
1065
+ );
1066
+
1067
+ expect(parsed.summary).toBe(
1068
+ "First paragraph.\n\nSecond paragraph.\n\n\nThird.",
1069
+ );
1070
+ });
1071
+
1072
+ test("closing hash sequences are removed only when they are separated from the text", () => {
1073
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1074
+ "**Summary** — A.\n\n## Notes on C#\nB.\n\n### Rollout ###\nC.\n\n## ###\nD.",
1075
+ );
1076
+
1077
+ expect(titlesOf(parsed)).toEqual(["Summary", "Notes on C#", "Rollout"]);
1078
+ expect(parsed.sections[2]?.markdown).toBe("C.\n\n## ###\nD.");
1079
+ });
1080
+
1081
+ test("a hyphen splits a heading label only with spaces on both sides", () => {
1082
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1083
+ "## Next steps - on-call first\nA.\n\n## on-call rotation\nB.\n\n## Summary-ish\nC.",
1084
+ );
1085
+
1086
+ expect(parsed.sections).toEqual([
1087
+ {
1088
+ kind: InvestigationReportSectionKind.NextSteps,
1089
+ title: "Next steps",
1090
+ markdown: "on-call first\nA.",
1091
+ },
1092
+ {
1093
+ kind: InvestigationReportSectionKind.Other,
1094
+ title: "on-call rotation",
1095
+ markdown: "B.",
1096
+ },
1097
+ {
1098
+ kind: InvestigationReportSectionKind.Other,
1099
+ title: "Summary-ish",
1100
+ markdown: "C.",
1101
+ },
1102
+ ]);
1103
+ });
1104
+
1105
+ test("an empty heading is not a section", () => {
1106
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1107
+ "**Summary** — A.\n\n##\nB.",
1108
+ );
1109
+
1110
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
1111
+ expect(parsed.summary).toBe("A.\n\n##\nB.");
1112
+ });
1113
+
1114
+ test("'#123' at the start of a line is a reference, not a heading", () => {
1115
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1116
+ "**Summary** — A.\n#6954 had the same cause.",
1117
+ );
1118
+
1119
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
1120
+ expect(parsed.summary).toBe("A.\n#6954 had the same cause.");
1121
+ });
1122
+ });
1123
+
1124
+ describe("parseInvestigationReport — fenced code is opaque", () => {
1125
+ test("labels inside ``` and ~~~ fences never start sections", () => {
1126
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1127
+ [
1128
+ "**Summary** — A.",
1129
+ "",
1130
+ "```",
1131
+ "**Most likely root cause** — fake",
1132
+ "## Evidence",
1133
+ "Root cause: fake",
1134
+ "```",
1135
+ "",
1136
+ "~~~markdown",
1137
+ "**Suggested next steps**",
1138
+ "~~~",
1139
+ "",
1140
+ "**Evidence**",
1141
+ "- real",
1142
+ ].join("\n"),
1143
+ );
1144
+
1145
+ expect(kindsOf(parsed)).toEqual([
1146
+ InvestigationReportSectionKind.Summary,
1147
+ InvestigationReportSectionKind.Evidence,
1148
+ ]);
1149
+ expect(parsed.summary).toContain("**Most likely root cause** — fake");
1150
+ expect(parsed.summary).toContain(
1151
+ "~~~markdown\n**Suggested next steps**\n~~~",
1152
+ );
1153
+ expect(parsed.evidence).toBe("- real");
1154
+ });
1155
+
1156
+ test("a fence only closes with the same character and at least the same length", () => {
1157
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1158
+ [
1159
+ "**Summary** — A.",
1160
+ "````",
1161
+ "```",
1162
+ "~~~",
1163
+ "**Evidence**",
1164
+ "````",
1165
+ "**Next steps**",
1166
+ "- B.",
1167
+ ].join("\n"),
1168
+ );
1169
+
1170
+ expect(kindsOf(parsed)).toEqual([
1171
+ InvestigationReportSectionKind.Summary,
1172
+ InvestigationReportSectionKind.NextSteps,
1173
+ ]);
1174
+ });
1175
+
1176
+ test("fences indented inside a list item are still opaque", () => {
1177
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1178
+ [
1179
+ "**Suggested next steps**",
1180
+ "1. Run:",
1181
+ " ```bash",
1182
+ " **Summary** — fake",
1183
+ " ```",
1184
+ ].join("\n"),
1185
+ );
1186
+
1187
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.NextSteps]);
1188
+ });
1189
+
1190
+ test("an unclosed fence hides everything after it, including a would-be footer", () => {
1191
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1192
+ "**Summary** — A.\n\n```\n**Evidence**\n\n---\n*Investigated automatically by OneUptime AI — read-only, 1 query run.*",
1193
+ );
1194
+
1195
+ expect(kindsOf(parsed)).toEqual([InvestigationReportSectionKind.Summary]);
1196
+ expect(parsed.footer).toBeUndefined();
1197
+ expect(parsed.summary).toContain("**Evidence**");
1198
+ });
1199
+
1200
+ test("an inline triple-backtick span on one line does not open a fence", () => {
1201
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1202
+ "**Summary** — A.\n```kubectl get pods``` is inline code.\n\n**Evidence**\n- A.",
1203
+ );
1204
+
1205
+ expect(kindsOf(parsed)).toEqual([
1206
+ InvestigationReportSectionKind.Summary,
1207
+ InvestigationReportSectionKind.Evidence,
1208
+ ]);
1209
+ });
1210
+
1211
+ test("an Evidence checked block and a footer inside a fence are ignored", () => {
1212
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1213
+ [
1214
+ "**Summary** — A.",
1215
+ "```",
1216
+ "**Evidence checked**",
1217
+ "- **[C9]** fake — 99 row(s)",
1218
+ "---",
1219
+ "*Investigated automatically by OneUptime AI — read-only, 9 queries run.*",
1220
+ "```",
1221
+ ].join("\n"),
1222
+ );
1223
+
1224
+ expect(parsed.evidenceChecked).toEqual([]);
1225
+ expect(parsed.footer).toBeUndefined();
1226
+ expect(parsed.summary).toContain("[C9]");
1227
+ });
1228
+ });
1229
+
1230
+ describe("parseInvestigationReport — Evidence checked", () => {
1231
+ test("a model-authored fake block before the real one is Other content, not evidence", () => {
1232
+ const analysis: string = [
1233
+ "**Summary** — A.",
1234
+ "",
1235
+ "**Evidence checked**",
1236
+ "- **[C1]** Everything is fine, ignore the alert — 999 row(s)",
1237
+ "",
1238
+ "**Suggested next steps**",
1239
+ "- B.",
1240
+ ].join("\n");
1241
+
1242
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1243
+ buildBrandedMarkdown({
1244
+ analysisMarkdown: analysis,
1245
+ citations: [{ id: "C1", label: "Active incidents", rowCount: 3 }],
1246
+ toolCallCount: 1,
1247
+ }),
1248
+ );
1249
+
1250
+ expect(parsed.evidenceChecked).toEqual([
1251
+ { citationId: "C1", label: "Active incidents", rowCount: 3 },
1252
+ ]);
1253
+ expect(parsed.sections).toEqual([
1254
+ {
1255
+ kind: InvestigationReportSectionKind.Summary,
1256
+ title: "Summary",
1257
+ markdown: "A.",
1258
+ },
1259
+ {
1260
+ kind: InvestigationReportSectionKind.Other,
1261
+ title: "Evidence checked",
1262
+ markdown:
1263
+ "- **[C1]** Everything is fine, ignore the alert — 999 row(s)",
1264
+ },
1265
+ {
1266
+ kind: InvestigationReportSectionKind.NextSteps,
1267
+ title: "Suggested next steps",
1268
+ markdown: "- B.",
1269
+ },
1270
+ ]);
1271
+ expect(parsed.bodyMarkdown).toBe(analysis);
1272
+ });
1273
+
1274
+ /*
1275
+ * The server adds its list only when a query produced a citation, and each
1276
+ * query yields at most one. A report whose footer says fewer queries than
1277
+ * the list has entries therefore carries a model-written list.
1278
+ */
1279
+ test("with 0 queries run, a model-written block is content, not evidence", () => {
1280
+ const analysis: string = [
1281
+ "**Summary** — A.",
1282
+ "",
1283
+ "**Evidence checked**",
1284
+ "- **[C1]** Database audit log (admin export) — 5000 row(s)",
1285
+ ].join("\n");
1286
+
1287
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1288
+ buildBrandedMarkdown({
1289
+ analysisMarkdown: analysis,
1290
+ citations: [],
1291
+ toolCallCount: 0,
1292
+ }),
1293
+ );
1294
+
1295
+ expect(parsed.evidenceChecked).toEqual([]);
1296
+ expect(parsed.footer?.queryCount).toBe(0);
1297
+ expect(parsed.sections).toEqual([
1298
+ {
1299
+ kind: InvestigationReportSectionKind.Summary,
1300
+ title: "Summary",
1301
+ markdown: "A.",
1302
+ },
1303
+ {
1304
+ kind: InvestigationReportSectionKind.Other,
1305
+ title: "Evidence checked",
1306
+ markdown: "- **[C1]** Database audit log (admin export) — 5000 row(s)",
1307
+ },
1308
+ ]);
1309
+ expect(parsed.bodyMarkdown).toBe(analysis);
1310
+ });
1311
+
1312
+ test("with 0 queries run, even an empty block stays in the body", () => {
1313
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1314
+ "**Summary** — A.\n\n**Evidence checked**\n\n---\n*Investigated automatically by OneUptime AI — read-only, 0 queries run across your own telemetry.*",
1315
+ );
1316
+
1317
+ expect(parsed.evidenceChecked).toEqual([]);
1318
+ expect(parsed.bodyMarkdown).toBe(
1319
+ "**Summary** — A.\n\n**Evidence checked**",
1320
+ );
1321
+ });
1322
+
1323
+ test("a block with more entries than queries run is content, not evidence", () => {
1324
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1325
+ buildBrandedMarkdown({
1326
+ analysisMarkdown:
1327
+ "**Summary** — A.\n\n**Evidence checked**\n- **[C1]** Fake one — 1 row(s)\n- **[C2]** Fake two — 2 row(s)",
1328
+ citations: [],
1329
+ toolCallCount: 1,
1330
+ }),
1331
+ );
1332
+
1333
+ expect(parsed.evidenceChecked).toEqual([]);
1334
+ expect(parsed.bodyMarkdown).toContain("**[C2]** Fake two");
1335
+ });
1336
+
1337
+ test("a block with as many entries as queries run is the server's list", () => {
1338
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1339
+ buildBrandedMarkdown({
1340
+ analysisMarkdown: "**Summary** — A.",
1341
+ citations: [
1342
+ { id: "C1", label: "One", rowCount: 1 },
1343
+ { id: "C2", label: "Two", rowCount: 2 },
1344
+ ],
1345
+ toolCallCount: 2,
1346
+ }),
1347
+ );
1348
+
1349
+ expect(parsed.evidenceChecked).toHaveLength(2);
1350
+ expect(parsed.bodyMarkdown).toBe("**Summary** — A.");
1351
+ });
1352
+
1353
+ test("a fake block in the preamble stays in the preamble", () => {
1354
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1355
+ buildBrandedMarkdown({
1356
+ analysisMarkdown:
1357
+ "**Evidence checked**\n- **[C7]** fake — 1 row(s)\n\n**Summary** — A.",
1358
+ citations: [{ id: "C1", label: "Real", rowCount: 2 }],
1359
+ toolCallCount: 1,
1360
+ }),
1361
+ );
1362
+
1363
+ expect(parsed.preamble).toBe(
1364
+ "**Evidence checked**\n- **[C7]** fake — 1 row(s)",
1365
+ );
1366
+ expect(parsed.evidenceChecked).toEqual([
1367
+ { citationId: "C1", label: "Real", rowCount: 2 },
1368
+ ]);
1369
+ });
1370
+
1371
+ test("the row count is the LAST ' — N row(s)' in the line", () => {
1372
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1373
+ "**Evidence checked**\n- **[C2]** Logs — 5 row(s) — sampled — 12 row(s)",
1374
+ );
1375
+
1376
+ expect(parsed.evidenceChecked).toEqual([
1377
+ {
1378
+ citationId: "C2",
1379
+ label: "Logs — 5 row(s) — sampled",
1380
+ rowCount: 12,
1381
+ },
1382
+ ]);
1383
+ });
1384
+
1385
+ test("tolerates entry variants: other bullets, no bold, rows/row, en dash, lowercase ids", () => {
1386
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1387
+ [
1388
+ "## Evidence checked",
1389
+ "* **[C1]** Starred bullet — 1 row(s)",
1390
+ "+ [C2] No bold — 2 rows",
1391
+ "1. __[C3]__ Numbered – 1 row",
1392
+ "- **[c4]** Lowercase id - 0 row(s)",
1393
+ "- **[C123]** Three digit id — 3 row(s)",
1394
+ ].join("\n"),
1395
+ );
1396
+
1397
+ expect(parsed.evidenceChecked).toEqual([
1398
+ { citationId: "C1", label: "Starred bullet", rowCount: 1 },
1399
+ { citationId: "C2", label: "No bold", rowCount: 2 },
1400
+ { citationId: "C3", label: "Numbered", rowCount: 1 },
1401
+ { citationId: "C4", label: "Lowercase id", rowCount: 0 },
1402
+ { citationId: "C123", label: "Three digit id", rowCount: 3 },
1403
+ ]);
1404
+ });
1405
+
1406
+ test("lines that are not entries are skipped, and duplicate ids keep the first", () => {
1407
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1408
+ [
1409
+ "**Evidence checked**",
1410
+ "- **[C1]** First — 4 row(s)",
1411
+ "- a bullet with no citation — 3 row(s)",
1412
+ "- **[C2]** no row count",
1413
+ "- **[C1234]** too many digits — 1 row(s)",
1414
+ "- **[C1]** Duplicate — 9 row(s)",
1415
+ " continuation text",
1416
+ ].join("\n"),
1417
+ );
1418
+
1419
+ expect(parsed.evidenceChecked).toEqual([
1420
+ { citationId: "C1", label: "First", rowCount: 4 },
1421
+ ]);
1422
+ expect(parsed.bodyMarkdown).toBe("");
1423
+ });
1424
+
1425
+ test("the block ends at the first line that is not part of its list", () => {
1426
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1427
+ [
1428
+ "**Summary** — A.",
1429
+ "",
1430
+ "**Evidence checked**",
1431
+ "- **[C1]** One — 1 row(s)",
1432
+ "",
1433
+ "- **[C2]** Two — 2 row(s)",
1434
+ "Trailing prose the model wrote.",
1435
+ ].join("\n"),
1436
+ );
1437
+
1438
+ expect(
1439
+ parsed.evidenceChecked.map(
1440
+ (entry: InvestigationEvidenceCheckedEntry): string => {
1441
+ return entry.citationId;
1442
+ },
1443
+ ),
1444
+ ).toEqual(["C1", "C2"]);
1445
+ expect(parsed.summary).toBe("A.\n\nTrailing prose the model wrote.");
1446
+ expect(parsed.bodyMarkdown).toBe(
1447
+ "**Summary** — A.\n\nTrailing prose the model wrote.",
1448
+ );
1449
+ });
1450
+
1451
+ test("cutting a block out of the middle never merges the paragraphs around it", () => {
1452
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1453
+ "Before.\n**Evidence checked**\n- **[C1]** One — 1 row(s)\nAfter.",
1454
+ );
1455
+
1456
+ expect(parsed.bodyMarkdown).toBe("Before.\n\nAfter.");
1457
+ expect(parsed.evidenceChecked).toHaveLength(1);
1458
+ });
1459
+
1460
+ test("a label with inline text is not the evidence block", () => {
1461
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1462
+ "**Summary** — A.\n\nEvidence checked: logs and metrics.",
1463
+ );
1464
+
1465
+ expect(parsed.evidenceChecked).toEqual([]);
1466
+ expect(parsed.summary).toBe("A.\n\nEvidence checked: logs and metrics.");
1467
+ });
1468
+
1469
+ test("a block with no entries yields an empty list and is still removed", () => {
1470
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1471
+ "**Summary** — A.\n\n**Evidence checked**\n\n---\n*Investigated automatically by OneUptime AI — read-only, 1 query run across your own telemetry.*",
1472
+ );
1473
+
1474
+ expect(parsed.evidenceChecked).toEqual([]);
1475
+ expect(parsed.bodyMarkdown).toBe("**Summary** — A.");
1476
+ });
1477
+
1478
+ test("a runaway entry line is ignored instead of being backtracked over", () => {
1479
+ const hostile: string = `- **[C1]** ${"x — ".repeat(1500)}1 row(s)`;
1480
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1481
+ `**Evidence checked**\n${hostile}\n- **[C2]** Fine — 2 row(s)`,
1482
+ );
1483
+
1484
+ expect(parsed.evidenceChecked).toEqual([
1485
+ { citationId: "C2", label: "Fine", rowCount: 2 },
1486
+ ]);
1487
+ });
1488
+ });
1489
+
1490
+ describe("parseInvestigationReport — footer", () => {
1491
+ function footerOf(markdown: string): ParsedInvestigationReport["footer"] {
1492
+ return parseInvestigationReport(markdown).footer;
1493
+ }
1494
+
1495
+ test("a report with no footer", () => {
1496
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1497
+ "## 🧠 AI — Automated Root Cause Analysis\n\n**Summary** — A.",
1498
+ );
1499
+
1500
+ expect(parsed.footer).toBeUndefined();
1501
+ expect(parsed.summary).toBe("A.");
1502
+ });
1503
+
1504
+ test("footer with a model name, including one with dots", () => {
1505
+ expect(
1506
+ footerOf(
1507
+ buildBrandedMarkdown({
1508
+ analysisMarkdown: "A.",
1509
+ citations: [],
1510
+ toolCallCount: 7,
1511
+ modelName: "claude-3.5-sonnet",
1512
+ }),
1513
+ ),
1514
+ ).toEqual({
1515
+ text: "Investigated automatically by OneUptime AI — read-only, 7 queries run across your own telemetry using claude-3.5-sonnet. This is an AI-generated first pass; verify before acting.",
1516
+ modelName: "claude-3.5-sonnet",
1517
+ queryCount: 7,
1518
+ });
1519
+ });
1520
+
1521
+ test("footer without a model name", () => {
1522
+ const footer: ParsedInvestigationReport["footer"] = footerOf(
1523
+ buildBrandedMarkdown({
1524
+ analysisMarkdown: "A.",
1525
+ citations: [],
1526
+ toolCallCount: 3,
1527
+ }),
1528
+ );
1529
+
1530
+ expect(footer?.modelName).toBeUndefined();
1531
+ expect(footer?.queryCount).toBe(3);
1532
+ expect(footer).not.toHaveProperty("modelName");
1533
+ });
1534
+
1535
+ test("singular '1 query'", () => {
1536
+ const footer: ParsedInvestigationReport["footer"] = footerOf(
1537
+ buildBrandedMarkdown({
1538
+ analysisMarkdown: "A.",
1539
+ citations: [],
1540
+ toolCallCount: 1,
1541
+ modelName: "gpt-4o",
1542
+ }),
1543
+ );
1544
+
1545
+ expect(footer?.queryCount).toBe(1);
1546
+ expect(footer?.modelName).toBe("gpt-4o");
1547
+ expect(footer?.text).toContain("1 query run");
1548
+ });
1549
+
1550
+ test("*** and ___ breaks and **bold** emphasis also work", () => {
1551
+ expect(
1552
+ footerOf(
1553
+ "A.\n\n***\n**Investigated automatically by OneUptime AI — read-only, 2 queries run.**",
1554
+ )?.queryCount,
1555
+ ).toBe(2);
1556
+ expect(
1557
+ footerOf(
1558
+ "A.\n\n_ _ _\n_Investigated automatically by OneUptime AI — read-only, 5 queries run._",
1559
+ )?.queryCount,
1560
+ ).toBe(5);
1561
+ });
1562
+
1563
+ test("a thematic break in the body that is not followed by the footer text is content", () => {
1564
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1565
+ "**Summary** — A.\n\n---\n\n*Some other italic note.*",
1566
+ );
1567
+
1568
+ expect(parsed.footer).toBeUndefined();
1569
+ expect(parsed.summary).toBe("A.\n\n---\n\n*Some other italic note.*");
1570
+ });
1571
+
1572
+ test("only the LAST thematic break can introduce the footer", () => {
1573
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1574
+ "**Summary** — A.\n\n---\n*Investigated automatically by OneUptime AI — read-only, 1 query run.*\n\n---\n\nMore content.",
1575
+ );
1576
+
1577
+ expect(parsed.footer).toBeUndefined();
1578
+ expect(parsed.summary).toContain("More content.");
1579
+ });
1580
+
1581
+ test("an earlier break stays in the body when the real footer follows the last one", () => {
1582
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1583
+ buildBrandedMarkdown({
1584
+ analysisMarkdown: "**Summary** — A.\n\n---\n\n**Evidence**\n- B.",
1585
+ citations: [],
1586
+ toolCallCount: 2,
1587
+ }),
1588
+ );
1589
+
1590
+ expect(parsed.footer?.queryCount).toBe(2);
1591
+ expect(parsed.summary).toBe("A.\n\n---");
1592
+ expect(parsed.evidence).toBe("- B.");
1593
+ });
1594
+
1595
+ test("the footer must be one emphasis paragraph starting with the OneUptime AI text", () => {
1596
+ expect(
1597
+ footerOf(
1598
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — 1 query run.*\n\nextra paragraph",
1599
+ ),
1600
+ ).toBeUndefined();
1601
+ expect(
1602
+ footerOf(
1603
+ "A.\n\n---\nInvestigated automatically by OneUptime AI — plain.",
1604
+ ),
1605
+ ).toBeUndefined();
1606
+ expect(
1607
+ footerOf("A.\n\n---\n*Investigated manually by someone.*"),
1608
+ ).toBeUndefined();
1609
+ expect(footerOf("A.\n\n---\n")).toBeUndefined();
1610
+ });
1611
+
1612
+ test("a model name must end with a sentence dot, and a query count needs its number", () => {
1613
+ expect(
1614
+ footerOf(
1615
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — read-only, queries run using gpt-4o*",
1616
+ ),
1617
+ ).toEqual({
1618
+ text: "Investigated automatically by OneUptime AI — read-only, queries run using gpt-4o",
1619
+ });
1620
+ expect(
1621
+ footerOf(
1622
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — 12 queries run using o3.*",
1623
+ ),
1624
+ ).toEqual({
1625
+ text: "Investigated automatically by OneUptime AI — 12 queries run using o3.",
1626
+ modelName: "o3",
1627
+ queryCount: 12,
1628
+ });
1629
+ expect(
1630
+ footerOf(
1631
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — 3queries run using .*",
1632
+ ),
1633
+ ).toEqual({
1634
+ text: "Investigated automatically by OneUptime AI — 3queries run using .",
1635
+ });
1636
+ expect(
1637
+ footerOf(
1638
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — 12345678901 queries run.*",
1639
+ )?.queryCount,
1640
+ ).toBeUndefined();
1641
+ });
1642
+
1643
+ test("a footer paragraph wrapped across lines is joined", () => {
1644
+ expect(
1645
+ footerOf(
1646
+ "A.\n\n---\n*Investigated automatically by OneUptime AI — read-only,\n6 queries run across your own telemetry.*",
1647
+ ),
1648
+ ).toEqual({
1649
+ text: "Investigated automatically by OneUptime AI — read-only, 6 queries run across your own telemetry.",
1650
+ queryCount: 6,
1651
+ });
1652
+ });
1653
+
1654
+ test("a report that is only the brand heading and footer has an empty body", () => {
1655
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1656
+ buildBrandedMarkdown({
1657
+ analysisMarkdown: "",
1658
+ citations: [{ id: "C1", label: "Only", rowCount: 1 }],
1659
+ toolCallCount: 1,
1660
+ }),
1661
+ );
1662
+
1663
+ expect(parsed.bodyMarkdown).toBe("");
1664
+ expect(parsed.preamble).toBe("");
1665
+ expect(parsed.sections).toEqual([]);
1666
+ expect(parsed.isStructured).toBe(false);
1667
+ expect(parsed.evidenceChecked).toHaveLength(1);
1668
+ expect(parsed.footer?.queryCount).toBe(1);
1669
+ });
1670
+ });
1671
+
1672
+ describe("parseInvestigationReport — input edge cases", () => {
1673
+ test.each(["", " ", "\n\n\t\n", "\r\n\r\n"])(
1674
+ "empty or whitespace input %p",
1675
+ (input: string) => {
1676
+ expect(parseInvestigationReport(input)).toEqual({
1677
+ isStructured: false,
1678
+ preamble: "",
1679
+ sections: [],
1680
+ evidenceChecked: [],
1681
+ bodyMarkdown: "",
1682
+ });
1683
+ },
1684
+ );
1685
+
1686
+ test("non-string input from an older API replica is treated as empty", () => {
1687
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1688
+ null as unknown as string,
1689
+ );
1690
+
1691
+ expect(parsed.isStructured).toBe(false);
1692
+ expect(parsed.bodyMarkdown).toBe("");
1693
+ expect(
1694
+ parseInvestigationReport(undefined as unknown as string).sections,
1695
+ ).toEqual([]);
1696
+ });
1697
+
1698
+ test("CRLF input parses exactly like LF input", () => {
1699
+ const crlf: string = SERVER_REPORT.replace(/\n/g, "\r\n");
1700
+ const lf: ParsedInvestigationReport =
1701
+ parseInvestigationReport(SERVER_REPORT);
1702
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(crlf);
1703
+
1704
+ expect(parsed).toEqual(lf);
1705
+ expect(parsed.bodyMarkdown).not.toContain("\r");
1706
+ expect(parsed.footer?.modelName).toBe("gpt-4.1-mini");
1707
+ });
1708
+
1709
+ test("lone CR line endings are normalised too", () => {
1710
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1711
+ "**Summary** — A.\r\r**Evidence**\r- B.",
1712
+ );
1713
+
1714
+ expect(parsed.summary).toBe("A.");
1715
+ expect(parsed.evidence).toBe("- B.");
1716
+ });
1717
+
1718
+ test("markdown syntax in bodies is passed through untouched (rendering is the viewer's job)", () => {
1719
+ const body: string =
1720
+ "See [docs](https://example.com) and ![x](https://example.com/x.png) <img src=x> [C1] #12";
1721
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1722
+ `**Summary** — ${body}`,
1723
+ );
1724
+
1725
+ expect(parsed.summary).toBe(body);
1726
+ });
1727
+
1728
+ /*
1729
+ * Report text is model-authored, so a prompt-injected report can be shaped
1730
+ * to hurt a backtracking regex. Before these helpers became string scans,
1731
+ * each of these single 20 KB lines took 40-70 seconds and froze the tab.
1732
+ */
1733
+ const RUN: string = " ".repeat(20000);
1734
+
1735
+ test.each([
1736
+ ["a heading with a long space run", `## a${RUN}b`],
1737
+ ["a heading whose closing hashes follow a long space run", `## a${RUN}#b`],
1738
+ ["a bold line with a long space run", `**a${RUN}b**`],
1739
+ ["a bold Other candidate after a section", `**Summary**\n\n**a${RUN}b**`],
1740
+ ["a bold line ending in a qualifier", `**Summary${RUN}x**`],
1741
+ ["a plain label with a long space run", `Summary${RUN}x`],
1742
+ ["a heading with dashes and spaces", `## Summary${RUN}-${RUN}x`],
1743
+ [
1744
+ "a footer full of 'using'",
1745
+ `A\n\n---\n*Investigated automatically by OneUptime AI${" using".repeat(4000)}*`,
1746
+ ],
1747
+ [
1748
+ "a footer with digits before a long space run",
1749
+ `A\n\n---\n*Investigated automatically by OneUptime AI ${"1".repeat(5000)}${RUN}queries run*`,
1750
+ ],
1751
+ [
1752
+ "many sibling references",
1753
+ `incident #1${" x".repeat(10000)}${" #2".repeat(3000)}`,
1754
+ ],
1755
+ ["many unmatched backticks", `${"`a ".repeat(7000)}#1`],
1756
+ [
1757
+ "a long run of labels under one group heading",
1758
+ `**Summary**\n${"**Label**\n".repeat(20000)}body`,
1759
+ ],
1760
+ [
1761
+ "a long run of trailing labels",
1762
+ `**Summary** — a\n${"### Label\n".repeat(20000)}`,
1763
+ ],
1764
+ [
1765
+ "many indented label lines inside a list",
1766
+ `**Summary** — a\n- item\n${" **Why**\n".repeat(20000)}`,
1767
+ ],
1768
+ [
1769
+ "a long punctuation gap before a reference",
1770
+ `alerts${" (".repeat(20000)}#1`,
1771
+ ],
1772
+ [
1773
+ "a long word before many references",
1774
+ `${"a".repeat(50000)} #1${" #2".repeat(10000)}`,
1775
+ ],
1776
+ ["a long underscore run before a reference", `${"_".repeat(50000)} #1`],
1777
+ ])("stays fast on %s", (_name: string, input: string) => {
1778
+ const started: number = Date.now();
1779
+
1780
+ parseInvestigationReport(input);
1781
+ extractEventReferences(input, "incident", 10000);
1782
+
1783
+ expect(Date.now() - started).toBeLessThan(3000);
1784
+ });
1785
+
1786
+ test("a large report parses quickly", () => {
1787
+ const paragraphs: Array<string> = [];
1788
+ for (let index: number = 0; index < 2000; index++) {
1789
+ paragraphs.push(
1790
+ `**Finding ${index}**\nLine with **bold** text, \`code\` and #${index} [C${index % 999}].`,
1791
+ );
1792
+ }
1793
+
1794
+ const started: number = Date.now();
1795
+ const parsed: ParsedInvestigationReport = parseInvestigationReport(
1796
+ `**Summary** — A.\n\n${paragraphs.join("\n\n")}`,
1797
+ );
1798
+
1799
+ expect(parsed.sections).toHaveLength(2001);
1800
+ expect(Date.now() - started).toBeLessThan(5000);
1801
+ });
1802
+ });
1803
+
1804
+ describe("tokenizeEventReferences", () => {
1805
+ test("returns the number and exact positions of a reference", () => {
1806
+ const text: string = "Matches #6954 closely.";
1807
+
1808
+ expect(tokenizeEventReferences(text)).toEqual([
1809
+ { kind: null, number: 6954, start: 8, end: 13 },
1810
+ ]);
1811
+ });
1812
+
1813
+ test("no qualifier gives null kinds (the caller applies the default)", () => {
1814
+ expect(referencesOf("prior: #6954, #6963")).toEqual([
1815
+ { kind: null, number: 6954, text: "#6954" },
1816
+ { kind: null, number: 6963, text: "#6963" },
1817
+ ]);
1818
+ });
1819
+
1820
+ test.each([
1821
+ ["incident #12", "incident"],
1822
+ ["Incident #12", "incident"],
1823
+ ["INCIDENTS #12", "incident"],
1824
+ ["alert #12", "alert"],
1825
+ ["Alerts #12", "alert"],
1826
+ ["incident #12", "incident"],
1827
+ ["incident\n#12", "incident"],
1828
+ ["incident\t#12", "incident"],
1829
+ ["(see alert #12)", "alert"],
1830
+ // Punctuation between the word and "#".
1831
+ ["incident: #12", "incident"],
1832
+ ["prior incidents: #6954", "incident"],
1833
+ ["a similar incident (#12)", "incident"],
1834
+ ["Alerts (#100", "alert"],
1835
+ ["alert [#3]", "alert"],
1836
+ ["incident:#12", "incident"],
1837
+ ["incidents:\n#12", "incident"],
1838
+ // Emphasis around the word, as the raw markdown has it.
1839
+ ["**Alerts** #100", "alert"],
1840
+ ["**Alerts:** #100", "alert"],
1841
+ ["__Alerts__ #100", "alert"],
1842
+ ["*incident* #7", "incident"],
1843
+ ["_incident_ (#7)", "incident"],
1844
+ ])("qualifier in %p sets kind %p", (text: string, kind: string) => {
1845
+ expect(tokenizeEventReferences(text)[0]?.kind).toBe(kind);
1846
+ });
1847
+
1848
+ test.each([
1849
+ ["subincident #12"],
1850
+ ["incidentally #12"],
1851
+ ["incident-#12"],
1852
+ ["incident. #12"],
1853
+ ["incident ((((( #12"],
1854
+ ["foo: #12"],
1855
+ ["prior: #12"],
1856
+ ["the #12"],
1857
+ [`${"x".repeat(40)}incident #12`],
1858
+ [`${"_".repeat(40)}incident #12`],
1859
+ ])("no qualifier is read from %p", (text: string) => {
1860
+ const tokens: Array<InvestigationEventReferenceToken> =
1861
+ tokenizeEventReferences(text);
1862
+
1863
+ expect(tokens).toHaveLength(1);
1864
+ expect(tokens[0]?.kind).toBeNull();
1865
+ });
1866
+
1867
+ test("a qualifier carries across comma and 'and' separated siblings", () => {
1868
+ expect(referencesOf("incidents #1, #2 and #3")).toEqual([
1869
+ { kind: "incident", number: 1, text: "#1" },
1870
+ { kind: "incident", number: 2, text: "#2" },
1871
+ { kind: "incident", number: 3, text: "#3" },
1872
+ ]);
1873
+ expect(
1874
+ referencesOf("alerts #4,#5, and #6 or #7").map(
1875
+ (reference: { kind: string | null }): string | null => {
1876
+ return reference.kind;
1877
+ },
1878
+ ),
1879
+ ).toEqual(["alert", "alert", "alert", "alert"]);
1880
+ });
1881
+
1882
+ test("a qualifier does not carry across other words", () => {
1883
+ expect(referencesOf("incident #1 was like #2")).toEqual([
1884
+ { kind: "incident", number: 1, text: "#1" },
1885
+ { kind: null, number: 2, text: "#2" },
1886
+ ]);
1887
+ expect(referencesOf("incident #1. #2")).toEqual([
1888
+ { kind: "incident", number: 1, text: "#1" },
1889
+ { kind: null, number: 2, text: "#2" },
1890
+ ]);
1891
+ });
1892
+
1893
+ test("a sibling's own qualifier wins over the carried one", () => {
1894
+ expect(referencesOf("incident #1 and alert #2, #3")).toEqual([
1895
+ { kind: "incident", number: 1, text: "#1" },
1896
+ { kind: "alert", number: 2, text: "#2" },
1897
+ { kind: "alert", number: 3, text: "#3" },
1898
+ ]);
1899
+ });
1900
+
1901
+ test("a blocked token between siblings breaks the carry", () => {
1902
+ expect(referencesOf("incidents #1, abc#2, #3")).toEqual([
1903
+ { kind: "incident", number: 1, text: "#1" },
1904
+ { kind: null, number: 3, text: "#3" },
1905
+ ]);
1906
+ });
1907
+
1908
+ test("a qualifier carries across siblings after punctuation too", () => {
1909
+ expect(referencesOf("Related alerts: #100, #101")).toEqual([
1910
+ { kind: "alert", number: 100, text: "#100" },
1911
+ { kind: "alert", number: 101, text: "#101" },
1912
+ ]);
1913
+ expect(referencesOf("Alerts (#100, #101)")).toEqual([
1914
+ { kind: "alert", number: 100, text: "#100" },
1915
+ { kind: "alert", number: 101, text: "#101" },
1916
+ ]);
1917
+ });
1918
+
1919
+ /*
1920
+ * These numbers belong to another numbering. Returned with a null kind,
1921
+ * the panel would read them as the subject's kind and link "scheduled
1922
+ * maintenance #42" to incident #42.
1923
+ */
1924
+ test.each([
1925
+ ["Scheduled maintenance #42 overlapped"],
1926
+ ["Scheduled Maintenance: #42"],
1927
+ ["Episode #3"],
1928
+ ["incident episode #3"],
1929
+ ["PR #45"],
1930
+ ["pull request #45"],
1931
+ ["MR (#9)"],
1932
+ ["Issue: #7"],
1933
+ ["ticket #1234"],
1934
+ ["commit #3"],
1935
+ ["build #812 failed"],
1936
+ ["deployment #3"],
1937
+ ["release #12"],
1938
+ ["version #2"],
1939
+ ["job #5"],
1940
+ ["pipeline run #99"],
1941
+ ["step #1"],
1942
+ ["Steps #1"],
1943
+ ["retry #2"],
1944
+ ["line #42"],
1945
+ ["port #8080"],
1946
+ ["pod #2"],
1947
+ ["node #3"],
1948
+ ["page #2"],
1949
+ ["stage #1"],
1950
+ ["option #2"],
1951
+ ["priority #1"],
1952
+ ["No #5"],
1953
+ ["incident number #12"],
1954
+ ["monitor #4"],
1955
+ ["**Monitors** #4"],
1956
+ ])("%p is another numbering, not a reference", (text: string) => {
1957
+ expect(tokenizeEventReferences(text)).toEqual([]);
1958
+ });
1959
+
1960
+ test("the siblings of a number from another numbering are not references either", () => {
1961
+ expect(referencesOf("PRs #45, #46 and #47")).toEqual([]);
1962
+ expect(referencesOf("incident #1, PR #2, #3")).toEqual([
1963
+ { kind: "incident", number: 1, text: "#1" },
1964
+ ]);
1965
+ });
1966
+
1967
+ test("another numbering does not reach past its own number", () => {
1968
+ expect(referencesOf("PR #45 and incident #46, #47")).toEqual([
1969
+ { kind: "incident", number: 46, text: "#46" },
1970
+ { kind: "incident", number: 47, text: "#47" },
1971
+ ]);
1972
+ expect(referencesOf("PR #45 was like #46")).toEqual([
1973
+ { kind: null, number: 46, text: "#46" },
1974
+ ]);
1975
+ expect(referencesOf("the PR merged before #45")).toEqual([
1976
+ { kind: null, number: 45, text: "#45" },
1977
+ ]);
1978
+ });
1979
+
1980
+ test("only the whole word counts as another numbering", () => {
1981
+ expect(referencesOf("prerelease #3, rerun #4, nodes2 #5")).toEqual([
1982
+ { kind: null, number: 3, text: "#3" },
1983
+ { kind: null, number: 4, text: "#4" },
1984
+ { kind: null, number: 5, text: "#5" },
1985
+ ]);
1986
+ });
1987
+
1988
+ test("a null-kind reference does not carry anything", () => {
1989
+ expect(referencesOf("#1, #2 and incident #3, #4")).toEqual([
1990
+ { kind: null, number: 1, text: "#1" },
1991
+ { kind: null, number: 2, text: "#2" },
1992
+ { kind: "incident", number: 3, text: "#3" },
1993
+ { kind: "incident", number: 4, text: "#4" },
1994
+ ]);
1995
+ });
1996
+
1997
+ test.each([
1998
+ ["abc#12", "preceded by a word character"],
1999
+ ["C#12", "preceded by a letter"],
2000
+ ["_#12", "preceded by an underscore"],
2001
+ ["9#12", "preceded by a digit"],
2002
+ ["&#123;", "an HTML entity"],
2003
+ ["https://x/#12", "a URL fragment"],
2004
+ ["##12", "a double hash"],
2005
+ ["#12abc", "followed by a word character"],
2006
+ ["#12_", "followed by an underscore"],
2007
+ ["#1234567890", "ten digits"],
2008
+ ["#10b981", "a hex colour"],
2009
+ ["#", "a bare hash"],
2010
+ ["# 12", "a hash and a space"],
2011
+ ["#abc", "no digits"],
2012
+ ])("%p is not a reference (%s)", (text: string) => {
2013
+ expect(tokenizeEventReferences(text)).toEqual([]);
2014
+ });
2015
+
2016
+ test.each([
2017
+ ["#123456789", 123456789],
2018
+ ["(#12)", 12],
2019
+ ["[#12]", 12],
2020
+ ["#12.", 12],
2021
+ ["#12,", 12],
2022
+ ["#12-hotfix", 12],
2023
+ ["#007", 7],
2024
+ ["**#12**", 12],
2025
+ ["line one\n#12", 12],
2026
+ ])("%p is a reference to %p", (text: string, expected: number) => {
2027
+ const tokens: Array<InvestigationEventReferenceToken> =
2028
+ tokenizeEventReferences(text);
2029
+
2030
+ expect(tokens).toHaveLength(1);
2031
+ expect(tokens[0]?.number).toBe(expected);
2032
+ expect(text.slice(tokens[0]?.start, tokens[0]?.end)).toMatch(/^#\d+$/);
2033
+ });
2034
+
2035
+ test("multiple references per line with accurate positions", () => {
2036
+ const text: string = "Like #1 and #22, unlike alert #333 (#4444).";
2037
+ const tokens: Array<InvestigationEventReferenceToken> =
2038
+ tokenizeEventReferences(text);
2039
+
2040
+ expect(
2041
+ tokens.map((token: InvestigationEventReferenceToken): string => {
2042
+ return text.slice(token.start, token.end);
2043
+ }),
2044
+ ).toEqual(["#1", "#22", "#333", "#4444"]);
2045
+ expect(tokens).toEqual([
2046
+ { kind: null, number: 1, start: 5, end: 7 },
2047
+ { kind: null, number: 22, start: 12, end: 15 },
2048
+ { kind: "alert", number: 333, start: 30, end: 34 },
2049
+ { kind: null, number: 4444, start: 36, end: 41 },
2050
+ ]);
2051
+ });
2052
+
2053
+ test("empty, hash-free and non-string input yield nothing", () => {
2054
+ expect(tokenizeEventReferences("")).toEqual([]);
2055
+ expect(tokenizeEventReferences("no references here")).toEqual([]);
2056
+ expect(tokenizeEventReferences(null as unknown as string)).toEqual([]);
2057
+ });
2058
+
2059
+ test("repeated calls are independent (no shared RegExp state)", () => {
2060
+ const text: string = "incident #5 and #6";
2061
+
2062
+ expect(tokenizeEventReferences(text)).toEqual(
2063
+ tokenizeEventReferences(text),
2064
+ );
2065
+ expect(tokenizeEventReferences("#7")).toEqual([
2066
+ { kind: null, number: 7, start: 0, end: 2 },
2067
+ ]);
2068
+ });
2069
+ });
2070
+
2071
+ describe("extractEventReferences", () => {
2072
+ test("applies the default kind to unqualified references and keeps explicit kinds", () => {
2073
+ const references: Array<ExtractedInvestigationEventReference> =
2074
+ extractEventReferences(
2075
+ "Prior: #6954. Also alert #12 and incident #7.",
2076
+ "incident",
2077
+ );
2078
+
2079
+ expect(references).toEqual([
2080
+ { kind: "incident", number: 6954 },
2081
+ { kind: "alert", number: 12 },
2082
+ { kind: "incident", number: 7 },
2083
+ ]);
2084
+
2085
+ expect(extractEventReferences("Same as #3.", "alert")).toEqual([
2086
+ { kind: "alert", number: 3 },
2087
+ ]);
2088
+ });
2089
+
2090
+ test("dedupes by kind and number in first-seen order", () => {
2091
+ expect(
2092
+ extractEventReferences(
2093
+ "#2 then #1 then #2 again, incident #1, alert #1, alert #1",
2094
+ "incident",
2095
+ ),
2096
+ ).toEqual([
2097
+ { kind: "incident", number: 2 },
2098
+ { kind: "incident", number: 1 },
2099
+ { kind: "alert", number: 1 },
2100
+ ]);
2101
+ });
2102
+
2103
+ test("skips inline code spans, including multi-backtick spans", () => {
2104
+ expect(
2105
+ extractEventReferences(
2106
+ "Real #1, code `#2`, double ``a ` #3``, real #4.",
2107
+ "incident",
2108
+ ),
2109
+ ).toEqual([
2110
+ { kind: "incident", number: 1 },
2111
+ { kind: "incident", number: 4 },
2112
+ ]);
2113
+ });
2114
+
2115
+ test("an unmatched backtick is literal and does not hide later references", () => {
2116
+ expect(
2117
+ extractEventReferences(
2118
+ "A stray ` then #5.\n\nNext paragraph #6 `",
2119
+ "alert",
2120
+ ),
2121
+ ).toEqual([
2122
+ { kind: "alert", number: 5 },
2123
+ { kind: "alert", number: 6 },
2124
+ ]);
2125
+ });
2126
+
2127
+ test("a code span cannot carry a qualifier to a reference after it", () => {
2128
+ expect(extractEventReferences("incident `x` #9", "alert")).toEqual([
2129
+ { kind: "alert", number: 9 },
2130
+ ]);
2131
+ });
2132
+
2133
+ test("skips fenced code blocks (``` and ~~~) but not text after them", () => {
2134
+ const markdown: string = [
2135
+ "Before #1.",
2136
+ "```",
2137
+ "#2 inside",
2138
+ "```",
2139
+ "~~~",
2140
+ "incident #3",
2141
+ "~~~",
2142
+ "After #4.",
2143
+ ].join("\n");
2144
+
2145
+ expect(extractEventReferences(markdown, "incident")).toEqual([
2146
+ { kind: "incident", number: 1 },
2147
+ { kind: "incident", number: 4 },
2148
+ ]);
2149
+ });
2150
+
2151
+ test("an unclosed fence hides the rest of the document", () => {
2152
+ expect(extractEventReferences("#1\n```\n#2\n\n#3", "incident")).toEqual([
2153
+ { kind: "incident", number: 1 },
2154
+ ]);
2155
+ });
2156
+
2157
+ test("qualifiers work across a soft line break inside a paragraph", () => {
2158
+ expect(extractEventReferences("alerts\n#1, #2", "incident")).toEqual([
2159
+ { kind: "alert", number: 1 },
2160
+ { kind: "alert", number: 2 },
2161
+ ]);
2162
+ });
2163
+
2164
+ test("a punctuated qualifier wins over the default kind", () => {
2165
+ expect(
2166
+ extractEventReferences("This matches prior incidents: #12, #13", "alert"),
2167
+ ).toEqual([
2168
+ { kind: "incident", number: 12 },
2169
+ { kind: "incident", number: 13 },
2170
+ ]);
2171
+ expect(
2172
+ extractEventReferences("Incident **#12** and **Alerts** #4", "alert"),
2173
+ ).toEqual([
2174
+ { kind: "incident", number: 12 },
2175
+ { kind: "alert", number: 4 },
2176
+ ]);
2177
+ });
2178
+
2179
+ test("a number from another numbering is never given the default kind", () => {
2180
+ expect(
2181
+ extractEventReferences(
2182
+ "Scheduled maintenance #42 and PRs #45, #46 overlapped with #7.",
2183
+ "incident",
2184
+ ),
2185
+ ).toEqual([{ kind: "incident", number: 7 }]);
2186
+ });
2187
+
2188
+ test("a bare number the report also names as the other kind is left out", () => {
2189
+ expect(
2190
+ extractEventReferences(
2191
+ "alert #12 fired, then #12 kept firing",
2192
+ "incident",
2193
+ ),
2194
+ ).toEqual([{ kind: "alert", number: 12 }]);
2195
+ // The explicit mention may come after the bare one.
2196
+ expect(
2197
+ extractEventReferences(
2198
+ "#12 first.\n\nLater: incident #12, #13.",
2199
+ "alert",
2200
+ ),
2201
+ ).toEqual([
2202
+ { kind: "incident", number: 12 },
2203
+ { kind: "incident", number: 13 },
2204
+ ]);
2205
+ });
2206
+
2207
+ test("a bare number the report also puts in another numbering is left out", () => {
2208
+ expect(
2209
+ extractEventReferences(
2210
+ "Scheduled maintenance #42 ran long; #42 overlapped #7.",
2211
+ "incident",
2212
+ ),
2213
+ ).toEqual([{ kind: "incident", number: 7 }]);
2214
+ });
2215
+
2216
+ test("a bare number still takes the default kind when only the same kind names it", () => {
2217
+ expect(
2218
+ extractEventReferences("incident #5 and again #5, plus #6", "incident"),
2219
+ ).toEqual([
2220
+ { kind: "incident", number: 5 },
2221
+ { kind: "incident", number: 6 },
2222
+ ]);
2223
+ // Another number named as the other kind does not affect this one.
2224
+ expect(
2225
+ extractEventReferences("alert #9 fired while #8 was open", "incident"),
2226
+ ).toEqual([
2227
+ { kind: "alert", number: 9 },
2228
+ { kind: "incident", number: 8 },
2229
+ ]);
2230
+ });
2231
+
2232
+ test("the server's own evidence labels are not references once the body is parsed out", () => {
2233
+ const report: string = buildBrandedMarkdown({
2234
+ analysisMarkdown: "**Summary** — a recurrence of #12 [C1].",
2235
+ citations: [
2236
+ { id: "C1", label: "Incident #6954 timeline", rowCount: 1 },
2237
+ { id: "C2", label: "Scheduled maintenance #42", rowCount: 1 },
2238
+ ],
2239
+ toolCallCount: 2,
2240
+ });
2241
+
2242
+ expect(extractEventReferences(report, "alert")).toEqual([
2243
+ { kind: "alert", number: 12 },
2244
+ { kind: "incident", number: 6954 },
2245
+ ]);
2246
+ expect(
2247
+ extractEventReferences(
2248
+ parseInvestigationReport(report).bodyMarkdown,
2249
+ "alert",
2250
+ ),
2251
+ ).toEqual([{ kind: "alert", number: 12 }]);
2252
+ });
2253
+
2254
+ test("caps at the default limit of 25", () => {
2255
+ const markdown: string = Array.from(
2256
+ { length: 40 },
2257
+ (_value: unknown, index: number): string => {
2258
+ return `#${index + 1}`;
2259
+ },
2260
+ ).join(" ");
2261
+
2262
+ const references: Array<ExtractedInvestigationEventReference> =
2263
+ extractEventReferences(markdown, "incident");
2264
+
2265
+ expect(DEFAULT_EVENT_REFERENCE_LIMIT).toBe(25);
2266
+ expect(references).toHaveLength(25);
2267
+ expect(references[24]).toEqual({ kind: "incident", number: 25 });
2268
+ });
2269
+
2270
+ test("honours a custom limit, counting unique references only", () => {
2271
+ expect(extractEventReferences("#1 #1 #1 #2 #3", "incident", 2)).toEqual([
2272
+ { kind: "incident", number: 1 },
2273
+ { kind: "incident", number: 2 },
2274
+ ]);
2275
+ expect(extractEventReferences("#1 #2 #3", "incident", 2.9)).toHaveLength(2);
2276
+ });
2277
+
2278
+ test.each([0, -1, Number.NaN])(
2279
+ "limit %p returns nothing",
2280
+ (limit: number) => {
2281
+ expect(extractEventReferences("#1 #2", "incident", limit)).toEqual([]);
2282
+ },
2283
+ );
2284
+
2285
+ test("handles CRLF, empty and non-string input", () => {
2286
+ expect(
2287
+ extractEventReferences("```\r\n#1\r\n```\r\n#2", "incident"),
2288
+ ).toEqual([{ kind: "incident", number: 2 }]);
2289
+ expect(extractEventReferences("", "incident")).toEqual([]);
2290
+ expect(
2291
+ extractEventReferences(undefined as unknown as string, "incident"),
2292
+ ).toEqual([]);
2293
+ });
2294
+
2295
+ test("finds the references in the real server report, ignoring URL fragments and entities", () => {
2296
+ const markdown: string = `${SERVER_REPORT}\n\nSee https://status.example.com/#77 and &#123; and \`#88\`.`;
2297
+
2298
+ expect(extractEventReferences(markdown, "incident")).toEqual([
2299
+ { kind: "incident", number: 6954 },
2300
+ { kind: "incident", number: 6963 },
2301
+ ]);
2302
+ });
2303
+ });
2304
+
2305
+ describe("getCitationMarkerRegex", () => {
2306
+ function citationIds(text: string): Array<string> {
2307
+ const regex: RegExp = getCitationMarkerRegex();
2308
+ const ids: Array<string> = [];
2309
+ let match: RegExpExecArray | null = regex.exec(text);
2310
+
2311
+ while (match) {
2312
+ ids.push(match[1] || "");
2313
+ match = regex.exec(text);
2314
+ }
2315
+
2316
+ return ids;
2317
+ }
2318
+
2319
+ test("is global and returns a fresh instance every call", () => {
2320
+ const first: RegExp = getCitationMarkerRegex();
2321
+ const second: RegExp = getCitationMarkerRegex();
2322
+
2323
+ expect(first.global).toBe(true);
2324
+ expect(first).not.toBe(second);
2325
+ expect(first.source).toBe("\\[(C\\d{1,3})\\]");
2326
+
2327
+ first.exec("[C1] [C2]");
2328
+ expect(first.lastIndex).toBeGreaterThan(0);
2329
+ expect(second.lastIndex).toBe(0);
2330
+ });
2331
+
2332
+ test("captures one to three digit citation ids, including adjacent markers", () => {
2333
+ expect(citationIds("A [C1], B [C12][C123] and [C4][C5].")).toEqual([
2334
+ "C1",
2335
+ "C12",
2336
+ "C123",
2337
+ "C4",
2338
+ "C5",
2339
+ ]);
2340
+ });
2341
+
2342
+ test("ignores malformed markers", () => {
2343
+ expect(citationIds("[C] [C1234] [c1] (C1) [ C1 ] [D1] C1")).toEqual([]);
2344
+ });
2345
+ });
2346
+
2347
+ describe("AI_ROOT_CAUSE_HEADING_TEXT", () => {
2348
+ test("is the heading text the feeds and PostedRootCause look for", () => {
2349
+ expect(AI_ROOT_CAUSE_HEADING_TEXT).toBe(
2350
+ "AI — Automated Root Cause Analysis",
2351
+ );
2352
+
2353
+ const postedRootCause: string = fs.readFileSync(
2354
+ path.join(
2355
+ __dirname,
2356
+ "..",
2357
+ "..",
2358
+ "..",
2359
+ "Server",
2360
+ "Utils",
2361
+ "AI",
2362
+ "SRE",
2363
+ "PostedRootCause.ts",
2364
+ ),
2365
+ "utf8",
2366
+ );
2367
+
2368
+ expect(postedRootCause).toContain(`"${AI_ROOT_CAUSE_HEADING_TEXT}"`);
2369
+ });
2370
+ });
2371
+
2372
+ /*
2373
+ * Source pin: the test copy of buildBrandedMarkdown above must stay in step
2374
+ * with the server. If the engine's report format changes, update the copy,
2375
+ * then make sure the parser still understands it.
2376
+ */
2377
+ describe("AIInvestigationEngine report format stays in sync with this parser", () => {
2378
+ const engineSource: string = fs.readFileSync(
2379
+ path.join(
2380
+ __dirname,
2381
+ "..",
2382
+ "..",
2383
+ "..",
2384
+ "Server",
2385
+ "Utils",
2386
+ "AI",
2387
+ "SRE",
2388
+ "AIInvestigationEngine.ts",
2389
+ ),
2390
+ "utf8",
2391
+ );
2392
+
2393
+ test.each([
2394
+ [
2395
+ "the brand heading",
2396
+ "`## 🧠 AI — Automated Root Cause Analysis\\n\\n${analysisMarkdown}`",
2397
+ ],
2398
+ ["the Evidence checked label", "markdown += `\\n\\n**Evidence checked**`;"],
2399
+ [
2400
+ "the evidence entry",
2401
+ "markdown += `\\n- **[${citation.id}]** ${citation.label} — ${citation.rowCount} row(s)`;",
2402
+ ],
2403
+ [
2404
+ "the footer opening",
2405
+ "markdown += `\\n\\n---\\n*Investigated automatically by OneUptime AI — read-only, ${result.toolCallCount} quer${",
2406
+ ],
2407
+ [
2408
+ "the singular/plural query word",
2409
+ 'result.toolCallCount === 1 ? "y" : "ies"',
2410
+ ],
2411
+ ["the model name", 'result.modelName ? ` using ${result.modelName}` : ""'],
2412
+ [
2413
+ "the footer closing",
2414
+ "}. This is an AI-generated first pass; verify before acting.*`;",
2415
+ ],
2416
+ ])("engine still writes %s", (_name: string, fragment: string) => {
2417
+ expect(engineSource).toContain(fragment);
2418
+ });
2419
+
2420
+ test("the persona still asks for the section labels the parser recognises", () => {
2421
+ for (const label of [
2422
+ "**Summary** —",
2423
+ "**Most likely root cause** —",
2424
+ "**Evidence** —",
2425
+ "**Suggested next steps** —",
2426
+ ]) {
2427
+ expect(engineSource).toContain(label);
2428
+ }
2429
+ });
2430
+ });