@oneuptime/common 14.0.9 → 14.0.10

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 (383) hide show
  1. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
  2. package/Models/DatabaseModels/CephCluster.ts +213 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +213 -0
  4. package/Models/DatabaseModels/DockerHost.ts +213 -0
  5. package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
  6. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  7. package/Models/DatabaseModels/Host.ts +213 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/PodmanHost.ts +213 -0
  10. package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
  11. package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
  12. package/Models/DatabaseModels/RunnerJob.ts +144 -0
  13. package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
  14. package/Server/API/AutoRemediationAPI.ts +392 -1
  15. package/Server/API/ResourceAiAccessAPI.ts +1669 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  18. package/Server/Infrastructure/Semaphore.ts +22 -0
  19. package/Server/Middleware/TelemetryIngest.ts +15 -5
  20. package/Server/Services/AnalyticsDatabaseService.ts +45 -1
  21. package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
  22. package/Server/Services/CephClusterService.ts +109 -1
  23. package/Server/Services/DatabaseServerService.ts +116 -1
  24. package/Server/Services/DockerHostService.ts +109 -1
  25. package/Server/Services/DockerSwarmClusterService.ts +113 -1
  26. package/Server/Services/HostService.ts +126 -4
  27. package/Server/Services/MetricRecordingRuleService.ts +47 -0
  28. package/Server/Services/PodmanHostService.ts +109 -1
  29. package/Server/Services/ProxmoxClusterService.ts +110 -1
  30. package/Server/Services/ResourceAiAccessService.ts +1439 -0
  31. package/Server/Services/ResourceAiAgentJobService.ts +202 -0
  32. package/Server/Services/ResourceAiAgentService.ts +2432 -0
  33. package/Server/Services/RunnerJobService.ts +611 -4
  34. package/Server/Services/TelemetryUsageBillingService.ts +28 -0
  35. package/Server/Services/TraceRecordingRuleService.ts +33 -0
  36. package/Server/Services/VMwareVCenterService.ts +110 -1
  37. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1434 -32
  38. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
  39. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
  40. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
  41. package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
  42. package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
  43. package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
  44. package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
  45. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
  46. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +72 -2
  47. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
  48. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
  49. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
  50. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
  51. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
  52. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
  53. package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
  54. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
  55. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
  56. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
  57. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
  60. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +366 -143
  61. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
  63. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
  64. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
  65. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
  66. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
  67. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +93 -0
  68. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
  69. package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
  70. package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
  71. package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
  72. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
  73. package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
  74. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
  75. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
  76. package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
  77. package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
  78. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
  79. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
  80. package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
  81. package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
  82. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
  83. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
  84. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
  85. package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
  86. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
  87. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
  88. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
  89. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
  90. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
  91. package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
  92. package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
  93. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
  94. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
  95. package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
  96. package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
  97. package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
  98. package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
  99. package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
  100. package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
  101. package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
  102. package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
  103. package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
  104. package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
  105. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
  106. package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
  107. package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
  108. package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
  109. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
  110. package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
  111. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
  112. package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
  113. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
  114. package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
  115. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
  116. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
  117. package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
  118. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
  119. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
  120. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
  121. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
  122. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
  123. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
  124. package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
  125. package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
  126. package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
  127. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
  128. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
  129. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
  130. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
  131. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
  132. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
  133. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
  134. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
  135. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
  137. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
  138. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
  139. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
  140. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
  141. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
  142. package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
  143. package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
  144. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
  145. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
  146. package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
  147. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
  148. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
  149. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
  150. package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
  151. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
  152. package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
  153. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
  154. package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
  155. package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
  156. package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
  157. package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
  158. package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
  159. package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
  160. package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
  161. package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
  162. package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
  163. package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
  164. package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
  165. package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
  166. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
  167. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
  168. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
  169. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
  170. package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
  171. package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
  172. package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
  173. package/Types/AI/ResourceAiAccessApi.ts +140 -0
  174. package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
  175. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
  176. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
  177. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
  178. package/Types/Monitor/RumAlertTemplates.ts +351 -4
  179. package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
  180. package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
  181. package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
  182. package/Types/Runbook/RunbookStepType.ts +29 -0
  183. package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
  184. package/Utils/AI/InvestigationReport.ts +121 -15
  185. package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
  186. package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
  187. package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
  188. package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
  189. package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
  190. package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
  191. package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
  192. package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
  193. package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
  194. package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
  195. package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
  196. package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
  197. package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
  198. package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
  199. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  200. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
  202. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
  204. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
  206. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
  208. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  210. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  211. package/build/dist/Models/DatabaseModels/Host.js +219 -0
  212. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  214. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
  216. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
  218. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  219. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
  220. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
  221. package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
  222. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
  224. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  225. package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
  226. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  227. package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
  228. package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
  234. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  235. package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
  236. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  237. package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  239. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
  240. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  241. package/build/dist/Server/Services/CephClusterService.js +104 -0
  242. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  243. package/build/dist/Server/Services/DatabaseServerService.js +99 -0
  244. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  245. package/build/dist/Server/Services/DockerHostService.js +104 -0
  246. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  247. package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
  248. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  249. package/build/dist/Server/Services/HostService.js +114 -2
  250. package/build/dist/Server/Services/HostService.js.map +1 -1
  251. package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
  252. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
  253. package/build/dist/Server/Services/PodmanHostService.js +104 -0
  254. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  255. package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
  256. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  257. package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
  258. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
  259. package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
  260. package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
  261. package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
  262. package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
  263. package/build/dist/Server/Services/RunnerJobService.js +344 -5
  264. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  265. package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
  266. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  267. package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
  268. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
  269. package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
  270. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1029 -30
  272. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
  274. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
  276. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
  278. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
  279. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
  280. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
  281. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
  282. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
  283. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
  284. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
  285. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
  286. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
  287. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
  288. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +50 -4
  290. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
  292. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  293. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
  294. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  295. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
  296. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  297. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
  298. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  299. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
  300. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  301. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
  302. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
  303. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
  304. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
  314. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  315. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
  316. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  317. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +263 -110
  318. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  319. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
  320. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
  321. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
  322. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
  323. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
  324. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
  325. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
  326. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
  327. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
  328. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
  329. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
  330. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
  331. package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
  332. package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
  333. package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
  334. package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
  335. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
  336. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  337. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
  338. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  339. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
  340. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  341. package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
  342. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  343. package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
  344. package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
  345. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
  346. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
  347. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
  348. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
  349. package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
  350. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  351. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
  352. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  353. package/build/dist/Utils/AI/InvestigationReport.js +71 -11
  354. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  355. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
  356. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
  357. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
  358. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
  359. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
  360. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
  361. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
  362. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
  363. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
  364. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
  365. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
  366. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
  367. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
  368. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
  369. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
  370. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
  371. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
  372. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
  373. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
  374. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
  375. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
  376. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
  377. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
  378. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
  379. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
  380. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
  381. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
  382. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
  383. package/package.json +1 -1
@@ -0,0 +1,585 @@
1
+ import {
2
+ ALLOWLIST_WILDCARD_TOKEN,
3
+ MAX_RESOURCE_COMMAND_TOKENS,
4
+ RESOURCE_SHELL_SYNTAX_RULE,
5
+ ResourceAutoExecutionVerdict,
6
+ ResourceCommandPolicyResult,
7
+ ResourceTokenizeResult,
8
+ allowlistPatternMatches,
9
+ applyAutoExecutionLadder,
10
+ deniedResult,
11
+ getPrivilegeEscalationRefusal,
12
+ globMatchesTarget,
13
+ renderResourceDisplayCommand,
14
+ tokenizeResourceCommand,
15
+ } from "../../../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
16
+ import {
17
+ AiRemediationCommandPolicyVerdict,
18
+ MAX_COMMAND_LENGTH_CHARS,
19
+ } from "../../../../Types/AutoRemediation/AiRemediationCommandPolicyVerdict";
20
+ import { ResourceCommandTier } from "../../../../Types/ResourceAiAgent/ResourceAiAccess";
21
+ import CommandPolicy from "../../../../Utils/AiRemediation/CommandPolicy";
22
+ import { describe, expect, test } from "@jest/globals";
23
+
24
+ /*
25
+ * Contract under test — the tool-agnostic half of the resource command
26
+ * policy.
27
+ *
28
+ * - The tokenizer reads quoting ONLY (single, double, backslash) and refuses
29
+ * everything a shell would have given a meaning the agent never will:
30
+ * unquoted | ; & > < ` and $(, backticks and $( inside double quotes,
31
+ * newlines and NUL, sudo and friends. Its refusal of shell syntax always
32
+ * says "pipes and redirects are not supported; run one command".
33
+ * - Rendering round-trips through the tokenizer, whatever the words hold.
34
+ * - Target globs: `*` within one target, anchored, case-sensitive, linear.
35
+ * - Allowlist entries: a whole-word `*` matches one word, every other word
36
+ * is compared exactly, and the lengths must be equal.
37
+ * - The auto-execution ladder: Denied, Read, requiresHuman, SafeWrite,
38
+ * bypass, allowlist, ask — in that order.
39
+ */
40
+
41
+ function tokens(command: string): Array<string> | undefined {
42
+ return tokenizeResourceCommand(command).argv;
43
+ }
44
+
45
+ function tokenError(command: string): string {
46
+ const result: ResourceTokenizeResult = tokenizeResourceCommand(command);
47
+
48
+ expect(result.argv).toBeUndefined();
49
+
50
+ return result.errorMessage || "";
51
+ }
52
+
53
+ function result(
54
+ overrides: Partial<ResourceCommandPolicyResult> = {},
55
+ ): ResourceCommandPolicyResult {
56
+ return {
57
+ tier: ResourceCommandTier.RiskyWrite,
58
+ reason: "stops one container",
59
+ program: "docker",
60
+ args: ["stop", "web"],
61
+ verb: "stop",
62
+ displayCommand: "docker stop web",
63
+ targets: ["web"],
64
+ ...overrides,
65
+ };
66
+ }
67
+
68
+ describe("tokenizeResourceCommand — words", () => {
69
+ test.each([
70
+ ["docker ps -a", ["docker", "ps", "-a"]],
71
+ [" docker ps\t-a ", ["docker", "ps", "-a"]],
72
+ ["uptime", ["uptime"]],
73
+ [
74
+ `docker logs 'my app' --tail 50`,
75
+ ["docker", "logs", "my app", "--tail", "50"],
76
+ ],
77
+ [`docker logs "my app"`, ["docker", "logs", "my app"]],
78
+ [`docker logs my\\ app`, ["docker", "logs", "my app"]],
79
+ [
80
+ `pvesh get "/nodes/pve1/tasks?errors=1&limit=5"`,
81
+ ["pvesh", "get", "/nodes/pve1/tasks?errors=1&limit=5"],
82
+ ],
83
+ [`journalctl -u 'a|b'`, ["journalctl", "-u", "a|b"]],
84
+ [
85
+ `echo 'semi;colon' "gt>lt<" amp\\&`,
86
+ ["echo", "semi;colon", "gt>lt<", "amp&"],
87
+ ],
88
+ [`db x 'it'\\''s'`, ["db", "x", "it's"]],
89
+ [`db x "say \\"hi\\""`, ["db", "x", 'say "hi"']],
90
+ [`db x "back\\\\slash"`, ["db", "x", "back\\slash"]],
91
+ [
92
+ `db x "dollar \\$(not) and \\\`tick\\\`"`,
93
+ ["db", "x", "dollar $(not) and `tick`"],
94
+ ],
95
+ [`db x "keep \\n literal"`, ["db", "x", "keep \\n literal"]],
96
+ [`db x '$(literal)' '\`literal\`'`, ["db", "x", "$(literal)", "`literal`"]],
97
+ [`db x ''`, ["db", "x", ""]],
98
+ [`db x ""`, ["db", "x", ""]],
99
+ [`db x a""b`, ["db", "x", "ab"]],
100
+ [`db x $HOME \${X}`, ["db", "x", "$HOME", "${X}"]],
101
+ [`ps -eo pid,comm --sort=-%cpu`, ["ps", "-eo", "pid,comm", "--sort=-%cpu"]],
102
+ [`db trailing\\`, ["db", "trailing\\"]],
103
+ ])("%p -> %p", (command: string, expected: Array<string>) => {
104
+ expect(tokens(command)).toEqual(expected);
105
+ });
106
+
107
+ test("the program is argv[0], never stripped", () => {
108
+ expect(tokens("docker version")?.[0]).toBe("docker");
109
+ expect(tokens("DOCKER version")?.[0]).toBe("DOCKER");
110
+ });
111
+ });
112
+
113
+ describe("tokenizeResourceCommand — shell syntax is refused", () => {
114
+ test.each([
115
+ ["docker ps | grep web", "a pipe (|)"],
116
+ ["docker ps || true", "a pipe (|)"],
117
+ ["docker ps; docker info", "a command separator (;)"],
118
+ ["docker ps && docker info", "a background or chaining operator (&)"],
119
+ ["docker restart web &", "a background or chaining operator (&)"],
120
+ ["docker ps > /tmp/out", "an output redirect (>)"],
121
+ ["docker ps >> /tmp/out", "an output redirect (>)"],
122
+ ["docker ps 2>&1", "an output redirect (>)"],
123
+ ["db x < /etc/passwd", "an input redirect (<)"],
124
+ ["docker logs `docker ps -q`", "command substitution (`...`)"],
125
+ ["docker logs $(docker ps -q)", "command substitution ($(...))"],
126
+ ["docker logs web$(id)", "command substitution ($(...))"],
127
+ ["pvesh get /nodes?a=1&b=2", "a background or chaining operator (&)"],
128
+ ])("%p is refused as %s", (command: string, what: string) => {
129
+ const message: string = tokenError(command);
130
+
131
+ expect(message).toContain(what);
132
+ expect(message).toContain(RESOURCE_SHELL_SYNTAX_RULE);
133
+ expect(message).toContain("quote the character");
134
+ });
135
+
136
+ test.each([
137
+ [`docker logs "$(docker ps -q)"`, "command substitution ($(...))"],
138
+ ['docker logs "`id`"', "command substitution (`...`)"],
139
+ ])(
140
+ "%p is refused inside double quotes too, where a shell would expand it",
141
+ (command: string, what: string) => {
142
+ const message: string = tokenError(command);
143
+
144
+ expect(message).toContain(what);
145
+ expect(message).toContain("inside double quotes");
146
+ expect(message).toContain(RESOURCE_SHELL_SYNTAX_RULE);
147
+ },
148
+ );
149
+
150
+ test("the rule is the phrase the design names", () => {
151
+ expect(RESOURCE_SHELL_SYNTAX_RULE).toBe(
152
+ "pipes and redirects are not supported; run one command",
153
+ );
154
+ });
155
+
156
+ test.each([
157
+ ["docker ps\ndocker info"],
158
+ ["docker ps\r\ndocker info"],
159
+ ["docker ps\rdocker info"],
160
+ ["docker ps\0"],
161
+ ["docker logs 'multi\nline'"],
162
+ ['docker logs "multi\nline"'],
163
+ ])("%p is refused: one line only", (command: string) => {
164
+ expect(tokenError(command)).toContain("single line");
165
+ });
166
+ });
167
+
168
+ describe("tokenizeResourceCommand — privilege and shape", () => {
169
+ test.each([
170
+ ["sudo docker ps"],
171
+ ["SUDO docker ps"],
172
+ ["/usr/bin/sudo docker ps"],
173
+ ["doas systemctl restart nginx"],
174
+ ["su -c 'systemctl restart nginx'"],
175
+ ["pkexec systemctl restart nginx"],
176
+ ["sudo"],
177
+ ])("%p is refused, not stripped", (command: string) => {
178
+ const message: string = tokenError(command);
179
+
180
+ expect(message).toContain("own permissions");
181
+ expect(message).toMatch(/drop (sudo|doas|su|pkexec)/);
182
+ });
183
+
184
+ test("sudo later in the argv is only a word (the program decides)", () => {
185
+ expect(tokens("journalctl -t sudo")).toEqual(["journalctl", "-t", "sudo"]);
186
+ });
187
+
188
+ test.each([[""], [" "], ["\t"], ["''"], ['""']])(
189
+ "%p is empty",
190
+ (command: string) => {
191
+ const parsed: ResourceTokenizeResult = tokenizeResourceCommand(command);
192
+
193
+ if (parsed.argv) {
194
+ // A quoted empty word is a word: argv[0] "" is left to the dispatcher.
195
+ expect(parsed.argv).toEqual([""]);
196
+ } else {
197
+ expect(parsed.errorMessage).toBe("Empty command.");
198
+ }
199
+ },
200
+ );
201
+
202
+ test.each([[null], [undefined], [42], [{}]])(
203
+ "%p (not a string) is empty",
204
+ (command: unknown) => {
205
+ expect(tokenizeResourceCommand(command as string).errorMessage).toBe(
206
+ "Empty command.",
207
+ );
208
+ },
209
+ );
210
+
211
+ test.each([["docker 'ps"], ['docker "ps'], ["docker 'ps\"x"], ["db x \"a'"]])(
212
+ "%p has unbalanced quotes",
213
+ (command: string) => {
214
+ expect(tokenError(command)).toBe("Unbalanced quotes in the command.");
215
+ },
216
+ );
217
+
218
+ test("at most 64 words", () => {
219
+ const sixtyFour: string = [
220
+ "db",
221
+ ...Array.from({ length: 63 }, () => {
222
+ return "x";
223
+ }),
224
+ ].join(" ");
225
+ const sixtyFive: string = `${sixtyFour} x`;
226
+
227
+ expect(MAX_RESOURCE_COMMAND_TOKENS).toBe(64);
228
+ expect(tokens(sixtyFour)).toHaveLength(64);
229
+ expect(tokenError(sixtyFive)).toContain("at most 64 words");
230
+ });
231
+
232
+ test("at most MAX_COMMAND_LENGTH_CHARS characters", () => {
233
+ const longest: string = `db ${"x".repeat(MAX_COMMAND_LENGTH_CHARS - 3)}`;
234
+
235
+ expect(longest).toHaveLength(MAX_COMMAND_LENGTH_CHARS);
236
+ expect(tokens(longest)).toHaveLength(2);
237
+ expect(tokenError(`${longest}x`)).toContain(
238
+ `${MAX_COMMAND_LENGTH_CHARS}-character limit`,
239
+ );
240
+ });
241
+ });
242
+
243
+ describe("getPrivilegeEscalationRefusal", () => {
244
+ test.each([["docker"], ["systemctl"], ["sudoers"], ["pseudo"], [""]])(
245
+ "%p is not a privilege switch",
246
+ (program: string) => {
247
+ expect(getPrivilegeEscalationRefusal(program)).toBeNull();
248
+ },
249
+ );
250
+
251
+ test.each([["sudo"], ["Sudo"], ["/bin/su"], [" doas "], ["pkexec"]])(
252
+ "%p is",
253
+ (program: string) => {
254
+ expect(getPrivilegeEscalationRefusal(program)).toContain(
255
+ "own permissions",
256
+ );
257
+ },
258
+ );
259
+ });
260
+
261
+ describe("renderResourceDisplayCommand", () => {
262
+ test.each([
263
+ [["docker", "ps", "-a"], "docker ps -a"],
264
+ [["docker", "logs", "my app"], "docker logs 'my app'"],
265
+ [["db", "x", ""], "db x ''"],
266
+ [["db", "x", "it's"], "db x 'it'\\''s'"],
267
+ [["journalctl", "-u", "a|b"], "journalctl -u 'a|b'"],
268
+ [["ps", "--sort=-%cpu", "-eo", "pid,comm"], "ps --sort=-%cpu -eo pid,comm"],
269
+ [
270
+ ["pvesh", "get", "/nodes/pve1/qemu/101/status/current"],
271
+ "pvesh get /nodes/pve1/qemu/101/status/current",
272
+ ],
273
+ [[], ""],
274
+ ])("%p -> %p", (argv: Array<string>, expected: string) => {
275
+ expect(renderResourceDisplayCommand(argv)).toBe(expected);
276
+ });
277
+
278
+ test("drops anything that is not a word", () => {
279
+ expect(
280
+ renderResourceDisplayCommand([
281
+ "docker",
282
+ 7 as unknown as string,
283
+ "ps",
284
+ null as unknown as string,
285
+ ]),
286
+ ).toBe("docker ps");
287
+ expect(renderResourceDisplayCommand(null as unknown as Array<string>)).toBe(
288
+ "",
289
+ );
290
+ });
291
+
292
+ test.each([
293
+ [["db", "x", "a;b", "c|d", "e&f", "g>h", "i<j"]],
294
+ [["db", "x", "$(id)", "`id`", "${HOME}", "$HOME"]],
295
+ [["db", "x", "it's", '"quoted"', "back\\slash", "tab\there"]],
296
+ [["db", "x", "", " ", "*", "?", "~", "#comment"]],
297
+ [["db", "x", "'", "''", "\\", "\\'"]],
298
+ ])("round-trips %p through the tokenizer", (argv: Array<string>) => {
299
+ expect(tokens(renderResourceDisplayCommand(argv))).toEqual(argv);
300
+ });
301
+ });
302
+
303
+ describe("deniedResult", () => {
304
+ test("is Denied with the argv split into program and args", () => {
305
+ expect(deniedResult(["docker", "exec", "web", "sh"], "no exec")).toEqual({
306
+ tier: ResourceCommandTier.Denied,
307
+ reason: "no exec",
308
+ program: "docker",
309
+ args: ["exec", "web", "sh"],
310
+ verb: "",
311
+ displayCommand: "docker exec web sh",
312
+ targets: [],
313
+ });
314
+ });
315
+
316
+ test("is total on garbage", () => {
317
+ for (const argv of [[], null, undefined, "docker ps", [1, 2], [{}, "ps"]]) {
318
+ const denied: ResourceCommandPolicyResult = deniedResult(
319
+ argv as unknown as Array<string>,
320
+ "x",
321
+ );
322
+
323
+ expect(denied.tier).toBe(ResourceCommandTier.Denied);
324
+ expect(Array.isArray(denied.args)).toBe(true);
325
+ expect(denied.targets).toEqual([]);
326
+ }
327
+ });
328
+ });
329
+
330
+ describe("globMatchesTarget", () => {
331
+ test.each([
332
+ ["web", "web", true],
333
+ ["web", "web-1", false],
334
+ ["web-*", "web-1", true],
335
+ ["web-*", "web-", true],
336
+ ["web-*", "api-1", false],
337
+ ["*-web", "prod-web", true],
338
+ ["*", "anything", true],
339
+ ["*", "", true],
340
+ ["", "", true],
341
+ ["", "web", false],
342
+ ["w*b", "web", true],
343
+ ["w*b", "wb", true],
344
+ ["w*b", "webs", false],
345
+ ["Web", "web", false],
346
+ ["web", "Web", false],
347
+ ["node/*", "node/101", true],
348
+ ["pve1/1*", "pve1/101", true],
349
+ ["pve1/1*", "pve2/101", false],
350
+ ["a*b*c", "aXbYc", true],
351
+ ["a*b*c", "aXbY", false],
352
+ ["literal*", "literal*", true],
353
+ ])(
354
+ "%p matches %p: %p",
355
+ (pattern: string, target: string, expected: boolean) => {
356
+ expect(globMatchesTarget(pattern, target)).toBe(expected);
357
+ },
358
+ );
359
+
360
+ test("non-strings never match", () => {
361
+ expect(globMatchesTarget(null as unknown as string, "web")).toBe(false);
362
+ expect(globMatchesTarget("*", undefined as unknown as string)).toBe(false);
363
+ });
364
+
365
+ test("agrees with CommandPolicy.globMatches, which it mirrors", () => {
366
+ const pairs: Array<[string, string]> = [
367
+ ["web-*", "web-1"],
368
+ ["*a*a*a*b", "aaaaaaaaaa"],
369
+ ["x*", "y"],
370
+ ["*", ""],
371
+ ["a*", "a"],
372
+ ["**", "zz"],
373
+ ];
374
+
375
+ for (const [pattern, target] of pairs) {
376
+ expect(globMatchesTarget(pattern, target)).toBe(
377
+ CommandPolicy.globMatches(pattern, target),
378
+ );
379
+ }
380
+ });
381
+
382
+ test("stays linear on a pathological pattern", () => {
383
+ const started: number = Date.now();
384
+
385
+ expect(globMatchesTarget(`${"*a".repeat(40)}*b`, "a".repeat(20000))).toBe(
386
+ false,
387
+ );
388
+ expect(Date.now() - started).toBeLessThan(2000);
389
+ });
390
+ });
391
+
392
+ describe("allowlistPatternMatches", () => {
393
+ test.each([
394
+ [["docker", "stop", "web"], ["docker", "stop", "web"], true],
395
+ [["docker", "stop", "*"], ["docker", "stop", "web"], true],
396
+ [["docker", "stop", "*"], ["docker", "stop", "--time=5"], true],
397
+ [["docker", "*", "web"], ["docker", "kill", "web"], true],
398
+ [["docker", "stop", "*"], ["docker", "stop", "web", "api"], false],
399
+ [["docker", "stop", "*", "*"], ["docker", "stop", "web"], false],
400
+ [["docker", "stop", "web-*"], ["docker", "stop", "web-1"], false],
401
+ [["docker", "stop", "web-*"], ["docker", "stop", "web-*"], true],
402
+ [["docker", "stop", "Web"], ["docker", "stop", "web"], false],
403
+ [
404
+ ["docker", "stop", "--time", "*"],
405
+ ["docker", "stop", "--time", "5"],
406
+ true,
407
+ ],
408
+ [["docker", "stop", "--time", "*"], ["docker", "stop", "--time=5"], false],
409
+ [["*", "stop", "web"], ["podman", "stop", "web"], true],
410
+ [[], [], false],
411
+ ])(
412
+ "%p matches %p: %p",
413
+ (pattern: Array<string>, argv: Array<string>, expected: boolean) => {
414
+ expect(allowlistPatternMatches(pattern, argv)).toBe(expected);
415
+ },
416
+ );
417
+
418
+ test("the wildcard is exactly a whole-word *", () => {
419
+ expect(ALLOWLIST_WILDCARD_TOKEN).toBe("*");
420
+ });
421
+
422
+ test("garbage never matches", () => {
423
+ expect(
424
+ allowlistPatternMatches(null as unknown as Array<string>, ["docker"]),
425
+ ).toBe(false);
426
+ expect(
427
+ allowlistPatternMatches(
428
+ ["docker"],
429
+ undefined as unknown as Array<string>,
430
+ ),
431
+ ).toBe(false);
432
+ expect(
433
+ allowlistPatternMatches(
434
+ ["docker", 1 as unknown as string],
435
+ ["docker", "1"],
436
+ ),
437
+ ).toBe(false);
438
+ expect(
439
+ allowlistPatternMatches(
440
+ ["docker", "*"],
441
+ ["docker", null as unknown as string],
442
+ ),
443
+ ).toBe(false);
444
+ });
445
+ });
446
+
447
+ describe("applyAutoExecutionLadder", () => {
448
+ const off: { allowlistMatched: boolean; bypassApproval: boolean } = {
449
+ allowlistMatched: false,
450
+ bypassApproval: false,
451
+ };
452
+ const everything: { allowlistMatched: boolean; bypassApproval: boolean } = {
453
+ allowlistMatched: true,
454
+ bypassApproval: true,
455
+ };
456
+
457
+ test("Denied stays Denied whatever the operator set", () => {
458
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
459
+ result({ tier: ResourceCommandTier.Denied, reason: "exec is denied" }),
460
+ everything,
461
+ );
462
+
463
+ expect(verdict.verdict).toBe(AiRemediationCommandPolicyVerdict.Denied);
464
+ expect(verdict.tier).toBe(ResourceCommandTier.Denied);
465
+ expect(verdict.reason).toContain("exec is denied");
466
+ expect(verdict.reason).toContain("even with human approval");
467
+ });
468
+
469
+ test("an unknown tier is Denied", () => {
470
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
471
+ result({ tier: "Mystery" as ResourceCommandTier }),
472
+ everything,
473
+ );
474
+
475
+ expect(verdict.verdict).toBe(AiRemediationCommandPolicyVerdict.Denied);
476
+ expect(verdict.tier).toBe(ResourceCommandTier.Denied);
477
+ });
478
+
479
+ test("a missing result is Denied", () => {
480
+ expect(
481
+ applyAutoExecutionLadder(
482
+ null as unknown as ResourceCommandPolicyResult,
483
+ everything,
484
+ ).verdict,
485
+ ).toBe(AiRemediationCommandPolicyVerdict.Denied);
486
+ });
487
+
488
+ test("Read auto-approves (it changes nothing)", () => {
489
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
490
+ result({ tier: ResourceCommandTier.Read, reason: "lists containers" }),
491
+ off,
492
+ );
493
+
494
+ expect(verdict.verdict).toBe(
495
+ AiRemediationCommandPolicyVerdict.AutoApproved,
496
+ );
497
+ expect(verdict.tier).toBe(ResourceCommandTier.Read);
498
+ expect(verdict.reason).toBe("lists containers");
499
+ });
500
+
501
+ test.each([ResourceCommandTier.SafeWrite, ResourceCommandTier.RiskyWrite])(
502
+ "requiresHuman on a %s beats bypass and the allowlist",
503
+ (tier: ResourceCommandTier) => {
504
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
505
+ result({ tier, requiresHuman: true, reason: "kills a pid" }),
506
+ everything,
507
+ );
508
+
509
+ expect(verdict.verdict).toBe(
510
+ AiRemediationCommandPolicyVerdict.RequiresApproval,
511
+ );
512
+ expect(verdict.requiresHuman).toBe(true);
513
+ expect(verdict.tier).toBe(tier);
514
+ expect(verdict.reason).toContain("kills a pid");
515
+ expect(verdict.reason).toContain("Neither bypassing approvals");
516
+ },
517
+ );
518
+
519
+ test("SafeWrite auto-approves with nothing set", () => {
520
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
521
+ result({ tier: ResourceCommandTier.SafeWrite, reason: "restarts one" }),
522
+ off,
523
+ );
524
+
525
+ expect(verdict.verdict).toBe(
526
+ AiRemediationCommandPolicyVerdict.AutoApproved,
527
+ );
528
+ expect(verdict.reason).toBe("restarts one");
529
+ expect(verdict.requiresHuman).toBeUndefined();
530
+ });
531
+
532
+ test("RiskyWrite asks by default", () => {
533
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
534
+ result(),
535
+ off,
536
+ );
537
+
538
+ expect(verdict.verdict).toBe(
539
+ AiRemediationCommandPolicyVerdict.RequiresApproval,
540
+ );
541
+ expect(verdict.tier).toBe(ResourceCommandTier.RiskyWrite);
542
+ expect(verdict.reason).toBe(
543
+ "Requires human approval: stops one container.",
544
+ );
545
+ expect(verdict.requiresHuman).toBeUndefined();
546
+ });
547
+
548
+ test("RiskyWrite auto-approves when the resource bypasses approvals", () => {
549
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
550
+ result(),
551
+ { allowlistMatched: false, bypassApproval: true },
552
+ );
553
+
554
+ expect(verdict.verdict).toBe(
555
+ AiRemediationCommandPolicyVerdict.AutoApproved,
556
+ );
557
+ expect(verdict.reason).toContain("bypasses approvals");
558
+ });
559
+
560
+ test("RiskyWrite auto-approves when the allowlist matched", () => {
561
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
562
+ result(),
563
+ { allowlistMatched: true, bypassApproval: false },
564
+ );
565
+
566
+ expect(verdict.verdict).toBe(
567
+ AiRemediationCommandPolicyVerdict.AutoApproved,
568
+ );
569
+ expect(verdict.reason).toBe("Matched the resource's command allowlist.");
570
+ });
571
+
572
+ test("only a literal true counts for bypass and allowlist", () => {
573
+ const verdict: ResourceAutoExecutionVerdict = applyAutoExecutionLadder(
574
+ result(),
575
+ {
576
+ allowlistMatched: "true" as unknown as boolean,
577
+ bypassApproval: 1 as unknown as boolean,
578
+ },
579
+ );
580
+
581
+ expect(verdict.verdict).toBe(
582
+ AiRemediationCommandPolicyVerdict.RequiresApproval,
583
+ );
584
+ });
585
+ });