@memberjunction/server 6.2.0-edge.6 → 6.2.0-edge.7

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 (407) hide show
  1. package/README.md +69 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
  5. package/dist/agentSessions/BridgeHostInstance.js +14 -4
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
  7. package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
  8. package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
  9. package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
  10. package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
  11. package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
  12. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  13. package/dist/agentSessions/SessionJanitor.d.ts +31 -8
  14. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  15. package/dist/agentSessions/SessionJanitor.js +85 -41
  16. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  17. package/dist/agentSessions/SessionManager.d.ts +14 -4
  18. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  19. package/dist/agentSessions/SessionManager.js +28 -4
  20. package/dist/agentSessions/SessionManager.js.map +1 -1
  21. package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
  22. package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
  23. package/dist/agentSessions/conversationBrowsers.js +118 -0
  24. package/dist/agentSessions/conversationBrowsers.js.map +1 -0
  25. package/dist/agentSessions/sessionDeadline.d.ts +43 -0
  26. package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
  27. package/dist/agentSessions/sessionDeadline.js +68 -0
  28. package/dist/agentSessions/sessionDeadline.js.map +1 -0
  29. package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
  30. package/dist/auth/APIKeyScopeAuth.js +5 -4
  31. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  32. package/dist/auth/loginEmailResolution.d.ts +41 -0
  33. package/dist/auth/loginEmailResolution.d.ts.map +1 -0
  34. package/dist/auth/loginEmailResolution.js +47 -0
  35. package/dist/auth/loginEmailResolution.js.map +1 -0
  36. package/dist/auth/magicLink/MagicLinkKeys.d.ts +50 -2
  37. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  38. package/dist/auth/magicLink/MagicLinkKeys.js +129 -12
  39. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  40. package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
  41. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  42. package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
  43. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  44. package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
  45. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  46. package/dist/auth/magicLink/MagicLinkService.js +221 -9
  47. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  48. package/dist/auth/magicLink/index.d.ts +1 -1
  49. package/dist/auth/magicLink/index.d.ts.map +1 -1
  50. package/dist/auth/magicLink/index.js +1 -1
  51. package/dist/auth/magicLink/index.js.map +1 -1
  52. package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
  53. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  54. package/dist/auth/magicLink/redeemLanding.js +7 -4
  55. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  56. package/dist/auth/magicLink/types.d.ts +27 -3
  57. package/dist/auth/magicLink/types.d.ts.map +1 -1
  58. package/dist/auth/magicLink/types.js +0 -4
  59. package/dist/auth/magicLink/types.js.map +1 -1
  60. package/dist/auth/newUsers.d.ts.map +1 -1
  61. package/dist/auth/newUsers.js +1 -0
  62. package/dist/auth/newUsers.js.map +1 -1
  63. package/dist/backgroundSweepConfigUnits.d.ts +231 -0
  64. package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
  65. package/dist/backgroundSweepConfigUnits.js +180 -0
  66. package/dist/backgroundSweepConfigUnits.js.map +1 -0
  67. package/dist/config.d.ts +906 -8
  68. package/dist/config.d.ts.map +1 -1
  69. package/dist/config.js +59 -0
  70. package/dist/config.js.map +1 -1
  71. package/dist/context.d.ts +2 -0
  72. package/dist/context.d.ts.map +1 -1
  73. package/dist/context.js +35 -4
  74. package/dist/context.js.map +1 -1
  75. package/dist/coreRoutes.d.ts +3 -1
  76. package/dist/coreRoutes.d.ts.map +1 -1
  77. package/dist/coreRoutes.js +6 -4
  78. package/dist/coreRoutes.js.map +1 -1
  79. package/dist/generated/graphql-schemas/__mj.d.ts +228 -0
  80. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  81. package/dist/generated/graphql-schemas/__mj.js +1163 -6
  82. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  83. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
  84. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  85. package/dist/generic/OrphanedConversationDetailReconciler.js +27 -1
  86. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  87. package/dist/generic/ResolverBase.d.ts +50 -5
  88. package/dist/generic/ResolverBase.d.ts.map +1 -1
  89. package/dist/generic/ResolverBase.js +321 -132
  90. package/dist/generic/ResolverBase.js.map +1 -1
  91. package/dist/generic/RunViewResolver.d.ts +4 -0
  92. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  93. package/dist/generic/RunViewResolver.js +47 -7
  94. package/dist/generic/RunViewResolver.js.map +1 -1
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +157 -35
  98. package/dist/index.js.map +1 -1
  99. package/dist/integration/ConnectionPause.d.ts +121 -0
  100. package/dist/integration/ConnectionPause.d.ts.map +1 -0
  101. package/dist/integration/ConnectionPause.js +183 -0
  102. package/dist/integration/ConnectionPause.js.map +1 -0
  103. package/dist/integration/CustomColumnPromoter.d.ts +72 -6
  104. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  105. package/dist/integration/CustomColumnPromoter.js +87 -46
  106. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  107. package/dist/integration/EntityMapLifecycle.d.ts +78 -4
  108. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  109. package/dist/integration/EntityMapLifecycle.js +199 -5
  110. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  111. package/dist/integration/InactiveRowWarnings.d.ts +31 -0
  112. package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
  113. package/dist/integration/InactiveRowWarnings.js +29 -0
  114. package/dist/integration/InactiveRowWarnings.js.map +1 -1
  115. package/dist/integration/ObjectNamesByID.d.ts +28 -0
  116. package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
  117. package/dist/integration/ObjectNamesByID.js +87 -0
  118. package/dist/integration/ObjectNamesByID.js.map +1 -0
  119. package/dist/integration/PostRestartIntrospect.d.ts +26 -0
  120. package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
  121. package/dist/integration/PostRestartIntrospect.js +27 -0
  122. package/dist/integration/PostRestartIntrospect.js.map +1 -0
  123. package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
  124. package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
  125. package/dist/integration/RSUPostRestartProgress.js +323 -0
  126. package/dist/integration/RSUPostRestartProgress.js.map +1 -0
  127. package/dist/integration/RSUProgressBridge.d.ts +41 -2
  128. package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
  129. package/dist/integration/RSUProgressBridge.js +84 -1
  130. package/dist/integration/RSUProgressBridge.js.map +1 -1
  131. package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
  132. package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
  133. package/dist/integration/RunArtifactAuthorization.js +45 -0
  134. package/dist/integration/RunArtifactAuthorization.js.map +1 -0
  135. package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
  136. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
  137. package/dist/integration/SchemaRefreshLaunch.js +3 -2
  138. package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
  139. package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
  140. package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
  141. package/dist/integration/ScopedFieldsForBuild.js +91 -0
  142. package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
  143. package/dist/integration/TargetConfigGuard.d.ts +40 -0
  144. package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
  145. package/dist/integration/TargetConfigGuard.js +40 -0
  146. package/dist/integration/TargetConfigGuard.js.map +1 -0
  147. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
  148. package/dist/realtimeSessions/ownedRealtimeSession.js +2 -3
  149. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
  150. package/dist/realtimeSessions/sessionAccess.d.ts +15 -0
  151. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  152. package/dist/realtimeSessions/sessionAccess.js +22 -0
  153. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  154. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  155. package/dist/realtimeWidget/WidgetSessionService.js +2 -0
  156. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  157. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  158. package/dist/realtimeWidget/visitorIdentity.js +1 -0
  159. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  160. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  161. package/dist/realtimeWidget/widgetCore.js +4 -7
  162. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  163. package/dist/realtimeWidget/widgetGuestElevation.js +1 -0
  164. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  165. package/dist/requestOrigin.d.ts +22 -0
  166. package/dist/requestOrigin.d.ts.map +1 -0
  167. package/dist/requestOrigin.js +60 -0
  168. package/dist/requestOrigin.js.map +1 -0
  169. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  170. package/dist/resolvers/AgentSessionResolver.js +6 -2
  171. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  172. package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
  173. package/dist/resolvers/AutotagPipelineResolver.js +2 -1
  174. package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
  175. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  176. package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
  177. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  178. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
  179. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
  180. package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
  181. package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
  182. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  183. package/dist/resolvers/GetDataResolver.js +34 -13
  184. package/dist/resolvers/GetDataResolver.js.map +1 -1
  185. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
  186. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  187. package/dist/resolvers/IntegrationDiscoveryResolver.js +2690 -1305
  188. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  189. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  190. package/dist/resolvers/MCPResolver.js +13 -2
  191. package/dist/resolvers/MCPResolver.js.map +1 -1
  192. package/dist/resolvers/QuerySystemUserResolver.d.ts +36 -0
  193. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  194. package/dist/resolvers/QuerySystemUserResolver.js +174 -87
  195. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  196. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  197. package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
  198. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  199. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +6 -0
  200. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  201. package/dist/resolvers/RealtimeClientSessionResolver.js +36 -5
  202. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  203. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
  204. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  205. package/dist/resolvers/RemoteBrowserActionResolver.js +217 -34
  206. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  207. package/dist/resolvers/RunAIAgentResolver.d.ts +24 -8
  208. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  209. package/dist/resolvers/RunAIAgentResolver.js +185 -67
  210. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  211. package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
  212. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  213. package/dist/resolvers/RunAIPromptResolver.js +19 -18
  214. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  215. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  216. package/dist/resolvers/RunTemplateResolver.js +3 -1
  217. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  218. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  219. package/dist/resolvers/meetingRecordingRegistration.js +2 -0
  220. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  221. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  222. package/dist/rest/MediaAccessKeys.js +6 -2
  223. package/dist/rest/MediaAccessKeys.js.map +1 -1
  224. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  225. package/dist/rest/OAuthCallbackHandler.js +11 -5
  226. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  227. package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
  228. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
  229. package/dist/rest/RealtimeRecordingHandler.js +2 -4
  230. package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
  231. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  232. package/dist/rest/ViewOperationsHandler.js +2 -1
  233. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  234. package/dist/rest/setupRESTEndpoints.d.ts +3 -1
  235. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  236. package/dist/rest/setupRESTEndpoints.js +11 -2
  237. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  238. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
  239. package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
  240. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
  241. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  242. package/dist/services/TaskGraphActionRunner.js +2 -26
  243. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  244. package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
  245. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  246. package/dist/services/TaskGraphAgentRunner.js +38 -0
  247. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  248. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  249. package/dist/services/TaskGraphContinuationDeliverer.js +1 -0
  250. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  251. package/dist/services/WorkQueueHostService.d.ts +2 -1
  252. package/dist/services/WorkQueueHostService.d.ts.map +1 -1
  253. package/dist/services/WorkQueueHostService.js +19 -4
  254. package/dist/services/WorkQueueHostService.js.map +1 -1
  255. package/dist/services/workQueueConfig.d.ts +2 -2
  256. package/dist/services/workQueueConfig.js +5 -5
  257. package/dist/services/workQueueConfig.js.map +1 -1
  258. package/dist/sharedCache.js +1 -1
  259. package/dist/sharedCache.js.map +1 -1
  260. package/dist/types.d.ts +17 -0
  261. package/dist/types.d.ts.map +1 -1
  262. package/dist/types.js.map +1 -1
  263. package/package.json +98 -98
  264. package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
  265. package/src/__tests__/ActiveOperations.test.ts +68 -0
  266. package/src/__tests__/AgentSessionResolver.ownership.test.ts +13 -0
  267. package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
  268. package/src/__tests__/BatchApplyParity.test.ts +109 -0
  269. package/src/__tests__/BridgeHostInstance.test.ts +42 -0
  270. package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
  271. package/src/__tests__/ConnectionPause.test.ts +192 -0
  272. package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
  273. package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
  274. package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
  275. package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
  276. package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
  277. package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
  278. package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
  279. package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
  280. package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
  281. package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
  282. package/src/__tests__/MagicLinkKeys.test.ts +102 -0
  283. package/src/__tests__/MediaAccessKeys.test.ts +57 -10
  284. package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
  285. package/src/__tests__/ObjectNamesByID.test.ts +176 -0
  286. package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
  287. package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
  288. package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
  289. package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
  290. package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
  291. package/src/__tests__/RSUProgressBridge.test.ts +188 -5
  292. package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
  293. package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
  294. package/src/__tests__/RealtimeClientSessionResolver.test.ts +22 -0
  295. package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
  296. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
  297. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
  298. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +6 -4
  299. package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
  300. package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
  301. package/src/__tests__/ResolverBase.clientOldValues.test.ts +323 -26
  302. package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
  303. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +53 -2
  304. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +60 -0
  305. package/src/__tests__/RunAIAgentResolver.branch.test.ts +4 -0
  306. package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
  307. package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
  308. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +2 -0
  309. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +2 -0
  310. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +87 -12
  311. package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
  312. package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
  313. package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
  314. package/src/__tests__/SessionJanitor.test.ts +195 -4
  315. package/src/__tests__/SessionManager.test.ts +69 -0
  316. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
  317. package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
  318. package/src/__tests__/ViewOperationsHandler.test.ts +2 -5
  319. package/src/__tests__/WorkQueueHostService.test.ts +25 -7
  320. package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
  321. package/src/__tests__/contextRequestOrigin.test.ts +105 -0
  322. package/src/__tests__/conversationBrowsers.test.ts +62 -0
  323. package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
  324. package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
  325. package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
  326. package/src/__tests__/realtimeRecordingHandler.test.ts +7 -2
  327. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +79 -1
  328. package/src/__tests__/requestOrigin.test.ts +104 -0
  329. package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
  330. package/src/__tests__/sessionDeadline.test.ts +51 -0
  331. package/src/__tests__/sharedCache.test.ts +11 -0
  332. package/src/__tests__/unifiedAuth.test.ts +73 -1
  333. package/src/agentSessions/BridgeHostInstance.ts +20 -5
  334. package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
  335. package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
  336. package/src/agentSessions/SessionJanitor.ts +92 -42
  337. package/src/agentSessions/SessionManager.ts +38 -8
  338. package/src/agentSessions/conversationBrowsers.ts +143 -0
  339. package/src/agentSessions/sessionDeadline.ts +81 -0
  340. package/src/auth/APIKeyScopeAuth.ts +5 -4
  341. package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
  342. package/src/auth/loginEmailResolution.ts +67 -0
  343. package/src/auth/magicLink/MagicLinkKeys.ts +146 -14
  344. package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
  345. package/src/auth/magicLink/MagicLinkService.ts +250 -10
  346. package/src/auth/magicLink/index.ts +1 -1
  347. package/src/auth/magicLink/redeemLanding.ts +7 -4
  348. package/src/auth/magicLink/types.ts +28 -3
  349. package/src/auth/newUsers.ts +1 -0
  350. package/src/backgroundSweepConfigUnits.ts +213 -0
  351. package/src/config.ts +69 -0
  352. package/src/context.ts +39 -6
  353. package/src/coreRoutes.ts +14 -7
  354. package/src/generated/graphql-schemas/__mj.ts +822 -7
  355. package/src/generic/OrphanedConversationDetailReconciler.ts +32 -1
  356. package/src/generic/ResolverBase.ts +414 -143
  357. package/src/generic/RunViewResolver.ts +96 -49
  358. package/src/index.ts +201 -35
  359. package/src/integration/ConnectionPause.ts +222 -0
  360. package/src/integration/CustomColumnPromoter.ts +123 -53
  361. package/src/integration/EntityMapLifecycle.ts +229 -6
  362. package/src/integration/InactiveRowWarnings.ts +50 -0
  363. package/src/integration/ObjectNamesByID.ts +97 -0
  364. package/src/integration/PostRestartIntrospect.ts +49 -0
  365. package/src/integration/RSUPostRestartProgress.ts +359 -0
  366. package/src/integration/RSUProgressBridge.ts +85 -2
  367. package/src/integration/RunArtifactAuthorization.ts +65 -0
  368. package/src/integration/SchemaRefreshLaunch.ts +12 -2
  369. package/src/integration/ScopedFieldsForBuild.ts +113 -0
  370. package/src/integration/TargetConfigGuard.ts +71 -0
  371. package/src/realtimeSessions/ownedRealtimeSession.ts +2 -6
  372. package/src/realtimeSessions/sessionAccess.ts +30 -0
  373. package/src/realtimeWidget/WidgetSessionService.ts +2 -0
  374. package/src/realtimeWidget/visitorIdentity.ts +1 -0
  375. package/src/realtimeWidget/widgetCore.ts +4 -8
  376. package/src/realtimeWidget/widgetGuestElevation.ts +1 -0
  377. package/src/requestOrigin.ts +64 -0
  378. package/src/resolvers/AgentSessionResolver.ts +6 -2
  379. package/src/resolvers/AutotagPipelineResolver.ts +2 -1
  380. package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
  381. package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
  382. package/src/resolvers/GetDataResolver.ts +35 -13
  383. package/src/resolvers/IntegrationDiscoveryResolver.ts +1522 -203
  384. package/src/resolvers/MCPResolver.ts +15 -2
  385. package/src/resolvers/QuerySystemUserResolver.ts +197 -98
  386. package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
  387. package/src/resolvers/RealtimeClientSessionResolver.ts +40 -7
  388. package/src/resolvers/RemoteBrowserActionResolver.ts +242 -32
  389. package/src/resolvers/RunAIAgentResolver.ts +265 -86
  390. package/src/resolvers/RunAIPromptResolver.ts +18 -18
  391. package/src/resolvers/RunTemplateResolver.ts +3 -1
  392. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
  393. package/src/resolvers/meetingRecordingRegistration.ts +2 -0
  394. package/src/rest/MediaAccessKeys.ts +6 -2
  395. package/src/rest/OAuthCallbackHandler.ts +13 -5
  396. package/src/rest/RealtimeRecordingHandler.ts +5 -9
  397. package/src/rest/ViewOperationsHandler.ts +2 -1
  398. package/src/rest/setupRESTEndpoints.ts +11 -2
  399. package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
  400. package/src/services/TaskGraphActionRunner.ts +2 -23
  401. package/src/services/TaskGraphAgentRunner.ts +43 -0
  402. package/src/services/TaskGraphContinuationDeliverer.ts +1 -0
  403. package/src/services/WorkQueueHostService.ts +26 -4
  404. package/src/services/workQueueConfig.ts +5 -5
  405. package/src/sharedCache.ts +1 -1
  406. package/src/types.ts +18 -0
  407. package/src/services/TaskOrchestration-Integration.md +0 -188
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@ import { setupSQLServerClient, SQLServerDataProvider, SQLServerProviderConfigDat
9
9
  import { extendConnectionPoolWithQuery } from './util.js';
10
10
  import { registerIntegrationCustomColumnPromoter, IntegrationCustomColumnPromoter } from './integration/CustomColumnPromoter.js';
11
11
  import { DisableUnselectedEntityMaps, ReenableFieldMapsForEntityMap, selectFieldsToMap } from './integration/EntityMapLifecycle.js';
12
+ import { RSUPostRestartProgressSession } from './integration/RSUPostRestartProgress.js';
13
+ import { IntrospectInCatalogScope } from './integration/PostRestartIntrospect.js';
12
14
  import { default as BodyParser } from 'body-parser';
13
15
  import compression from 'compression'; // Add compression middleware
14
16
  import cors from 'cors';
@@ -29,7 +31,8 @@ import sql from 'mssql';
29
31
  import { WebSocketServer } from 'ws';
30
32
  import { RealtimeProxyServer } from './realtimeProxy/RealtimeProxyServer.js';
31
33
  import buildApolloServer from './apolloServer/index.js';
32
- import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage } from './config.js';
34
+ import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage, userEmailMap } from './config.js';
35
+ import { DescribeUserEmailMap } from './auth/loginEmailResolution.js';
33
36
  import { TranslateBracketsToPG } from './postgresqlCompat.js';
34
37
  import { BuildPostgreSQLConnectionConfig, DescribeReadOnlyLoginOverreach, PostgreSQLReadOnlyPool, ResolvePostgreSQLEndpoint, ResolvePostgreSQLReadOnlyCredentials, ToPGPoolConfig } from './postgresqlPoolSettings.js';
35
38
  import { default as jwt } from 'jsonwebtoken';
@@ -43,7 +46,7 @@ import createMSSQLConfig from './orm.js';
43
46
  import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
44
47
  import { CreateRealtimeRecordingRouter, REALTIME_RECORDING_MOUNT_PATH } from './rest/RealtimeRecordingHandler.js';
45
48
  import { LoadOwnedRealtimeSession } from './realtimeSessions/ownedRealtimeSession.js';
46
- import { AuthorizeAnonymousRoomSessions, LoadSessionConversationScope } from './realtimeSessions/sessionAccess.js';
49
+ import { AuthorizeAnonymousRoomSessions, AuthorizeLoadedSession } from './realtimeSessions/sessionAccess.js';
47
50
  import { RecordingAssemblyScheduler } from './realtimeSessions/RecordingAssemblyScheduler.js';
48
51
  import { RealtimeSessionEventService, ParseReplicatedRealtimeSessionEvent, } from './realtimeSessions/index.js';
49
52
  import { resolve } from 'node:path';
@@ -51,13 +54,13 @@ import { DataSourceInfo, raiseEvent } from './types.js';
51
54
  import { ScheduledJobsService } from './services/ScheduledJobsService.js';
52
55
  import { IntegrationSyncWorkerService } from './services/IntegrationSyncWorkerService.js';
53
56
  import { LocalCacheManager, TelemetryManager, LogStatus, LogError, SetVerboseLogging } from '@memberjunction/core';
54
- import { validateAuthProvidersRegistered } from './auth/index.js';
57
+ import { getSystemUser, validateAuthProvidersRegistered } from './auth/index.js';
55
58
  import { GetAPIKeyEngine } from '@memberjunction/api-keys';
56
59
  import { ActionEngineServer } from '@memberjunction/actions';
57
60
  import { CreateAdhocSQLAuthorizer } from './resolvers/AdhocQueryResolver.js';
58
61
  import { CacheManagerConfigFromSettings, CreateSharedCacheFromEnvironment, StartEngineSweeper, StartMetadataSweep, StartUserCacheChecks, WarmupLeaseMsFromSettings, WirePushStatusFanOut, WireSharedCacheEvents } from './sharedCache.js';
59
62
  import { PubSubManager } from './generic/PubSubManager.js';
60
- import { ReconcileOrphanedConversationDetails } from './generic/OrphanedConversationDetailReconciler.js';
63
+ import { StartOrphanedConversationDetailReconciler } from './generic/OrphanedConversationDetailReconciler.js';
61
64
  import { HANDOFF_OFFER_FANOUT_CHANNEL, HANDOFF_OFFER_TOPIC, SetHandoffOfferPublishHook, ParseReplicatedHandoffOfferUpdate, } from './resolvers/HumanHandoffResolver.js';
62
65
  import { RoomAuthorizationService, RoomHandoffEngine } from '@memberjunction/livekit-room-server';
63
66
  import { IntegrationProgressEmitter, SweepInterruptedRuns } from '@memberjunction/integration-progress-artifacts';
@@ -65,6 +68,7 @@ import { PublishIntegrationProgress } from './resolvers/IntegrationProgressResol
65
68
  import { RegisterRSUProgressBridge } from './integration/RSUProgressBridge.js';
66
69
  import { ClientToolRequestManager, AgentRunWatchdog, SqlRealtimeRecordingLedger } from '@memberjunction/ai-agents';
67
70
  import { BindBridgeEngineHostInstance, SessionJanitor, SetHostInstancePort, StartBridgeOrphanReconciliation } from './agentSessions/index.js';
71
+ import { ApplyHandoffOfferExpirySettings } from './agentSessions/HandoffOfferExpiry.js';
68
72
  import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js';
69
73
  import { MJServerWorkQueueProviderSource, StartWorkQueueHost } from './services/WorkQueueHostService.js';
70
74
  import { GetAttachmentService } from '@memberjunction/aiengine';
@@ -72,7 +76,9 @@ import { MJStorageBlobStore } from './services/MJStorageBlobStore.js';
72
76
  import { CACHE_INVALIDATION_TOPIC, MayBroadcastRecordData, ConfigureRecordDataBroadcast } from './generic/CacheInvalidationResolver.js';
73
77
  import { ConnectorFactory, IntegrationEngine } from '@memberjunction/integration-engine';
74
78
  import { CronExpressionHelper } from '@memberjunction/scheduling-engine';
75
- import { ServerExtensionLoader, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath, GetCorsOwningServerExtensionRoots } from '@memberjunction/server-extensions-core';
79
+ import { ServerExtensionLoader, SERVER_EXTENSION_CORE_SERVICE_KEYS, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath, GetCorsOwningServerExtensionRoots, } from '@memberjunction/server-extensions-core';
80
+ import { CreateIsolatedProvider } from './isolatedProvider.js';
81
+ import { ResolveConfiguredPrincipal } from './auth/principals.js';
76
82
  import { CreateExtensionOwnedPreflightFallback, CreateGlobalCorsMiddleware } from './globalCors.js';
77
83
  import { CoreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
78
84
  import { ApiRoute, ApiRootPath, ConfiguredPublicUrl } from './apiRoot.js';
@@ -120,6 +126,7 @@ export * from './directives/index.js';
120
126
  export { NoLog, hasNoLogParameter, getNoLogFields } from './logging/NoLog.js';
121
127
  export * from './entitySubclasses/MJEntityPermissionEntityServer.server.js';
122
128
  export * from './types.js';
129
+ export * from './requestOrigin.js';
123
130
  export { getSystemUser, getSigningKeys, extractUserInfoFromPayload, verifyUserRecord, } from './auth/index.js';
124
131
  export * from './auth/APIKeyScopeAuth.js';
125
132
  export * from './auth/actingContextResolver.js';
@@ -268,8 +275,6 @@ function resolveServerVersion() {
268
275
  return undefined;
269
276
  }
270
277
  }
271
- /** How often to re-check for conversation details left behind by finished runs. */
272
- const ORPHAN_DETAIL_SWEEP_INTERVAL_MS = 5 * 60_000;
273
278
  /**
274
279
  * Replicate handoff-offer updates across server instances over Redis.
275
280
  *
@@ -512,7 +517,14 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
512
517
  await codegenTestClient.query('SELECT 1');
513
518
  codegenTestClient.release();
514
519
  const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
515
- const codegenPgConfigData = new PostgreSQLProviderConfigData(codegenPgConnectionConfig, mj_core_schema, cacheRefreshInterval / 1000);
520
+ // Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
521
+ // so boot does not pay a second full metadata load. The refresh interval stays non-zero on
522
+ // PostgreSQL on purpose: PostgreSQLDataProvider.AllowRefresh is `CheckRefreshIntervalSeconds > 0`,
523
+ // so an interval of 0 would make every later codegenPgProvider.Refresh() — the one RSU CodeGen
524
+ // issues after DDL — return without reloading, leaving this provider frozen at the boot catalog.
525
+ // (SQL Server's AllowRefresh is independent of the interval, so its codegen provider can use 0.)
526
+ const codegenPgConfigData = new PostgreSQLProviderConfigData(codegenPgConnectionConfig, mj_core_schema, cacheRefreshInterval / 1000, // ms → seconds
527
+ undefined, undefined, false);
516
528
  const codegenPgProvider = new PostgreSQLDataProvider();
517
529
  await codegenPgProvider.Config(codegenPgConfigData); // separate pool (per-instance manager); does NOT touch the global API provider
518
530
  RuntimeSchemaManager.Instance.SetDDLProvider(codegenPgProvider);
@@ -642,8 +654,11 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
642
654
  });
643
655
  await codegenPool.connect();
644
656
  const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
645
- // Same ms→seconds seam as the main provider config above — see providerConfigUnits.ts
646
- const codegenConfig = new SQLServerProviderConfigData(codegenPool, mj_core_schema, MetadataCacheRefreshIntervalSeconds(cacheRefreshInterval));
657
+ // Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
658
+ // and disable a duplicate background refresh timer (0): avoids a second full metadata load
659
+ // on boot while explicit codegenProvider.Refresh() after DDL still reloads from the DB
660
+ // (SQLServerDataProvider.AllowRefresh does not depend on the interval; PostgreSQL's does — see above).
661
+ const codegenConfig = new SQLServerProviderConfigData(codegenPool, mj_core_schema, 0, undefined, undefined, false);
647
662
  const codegenProvider = new SQLServerDataProvider();
648
663
  await codegenProvider.Config(codegenConfig);
649
664
  RuntimeSchemaManager.Instance.SetDDLProvider(codegenProvider);
@@ -1086,6 +1101,7 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1086
1101
  },
1087
1102
  // context() now just reads the already-validated payload — no I/O, no logging
1088
1103
  context: async (ctx) => {
1104
+ // No RequestOrigin here: the upgrade request's Origin is not carried onto subscription contexts.
1089
1105
  return { userPayload: ctx.extra.userPayload };
1090
1106
  },
1091
1107
  onClose: (ctx) => {
@@ -1144,6 +1160,15 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1144
1160
  // ─── Server extensions loader & shared service registry ───────────────────
1145
1161
  const extensionLoader = new ServerExtensionLoader();
1146
1162
  _currentExtensionLoader = extensionLoader;
1163
+ const hostRuntimeService = {
1164
+ CreateIsolatedProvider,
1165
+ GetSystemUser: () => getSystemUser(),
1166
+ ResolvePrincipal: (configuredEmailOrId, subsystemLabel) => ResolveConfiguredPrincipal(configuredEmailOrId, subsystemLabel),
1167
+ };
1168
+ extensionLoader.Services.RegisterService(SERVER_EXTENSION_CORE_SERVICE_KEYS.HostRuntime, hostRuntimeService);
1169
+ if (coreAuthenticatedRouters.MagicLinkService) {
1170
+ extensionLoader.Services.RegisterService(SERVER_EXTENSION_CORE_SERVICE_KEYS.MagicLink, coreAuthenticatedRouters.MagicLinkService);
1171
+ }
1147
1172
  // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1148
1173
  // Backwards-compatibility shim: synthesize ServerExtensionConfig entries from legacy configInfo.telephony
1149
1174
  const telephonyExtensionConfigs = [];
@@ -1246,6 +1271,11 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1246
1271
  MountExtensionHealthRoute(app, extensionLoader);
1247
1272
  MountAuthCatalogRoute(app, startupLog);
1248
1273
  // ─── Unified auth middleware (replaces both REST authMiddleware and contextFunction auth) ─────
1274
+ // Always shown, whatever the log level: a configured map makes logins run as other people's records
1275
+ const userEmailMapWarning = DescribeUserEmailMap(userEmailMap);
1276
+ if (userEmailMapWarning) {
1277
+ console.warn(userEmailMapWarning);
1278
+ }
1249
1279
  app.use(CreateUnifiedAuthMiddleware(dataSources));
1250
1280
  // ─── Post-auth middleware from BaseServerMiddleware plugins ─────
1251
1281
  // Middleware here has access to the authenticated user via req.userPayload.
@@ -1361,6 +1391,10 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1361
1391
  if (!runBackgroundWorkers) {
1362
1392
  LogStatus(`[ServerRole] Running in '${serverRole}' mode — background worker services are disabled on this replica.`);
1363
1393
  }
1394
+ // Every role runs agents, so every role's watchdog takes the configured intervals (before any run starts).
1395
+ AgentRunWatchdog.Instance.Configure(configInfo.agentRunWatchdog);
1396
+ // The handoff offer registry starts its own expiry sweep when it loads, on every role; apply the host's setting.
1397
+ ApplyHandoffOfferExpirySettings(configInfo.agentSessions.handoffOfferExpiry);
1364
1398
  // Close out run artifacts a dead process left open, BEFORE anything below can start a new run.
1365
1399
  //
1366
1400
  // A killed process (OOM killer, SIGKILL, host reboot) never writes its run's terminal result, so
@@ -1370,7 +1404,13 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1370
1404
  // to a process that no longer exists. That is why it runs here, ahead of the scheduler, the
1371
1405
  // integration sync worker (its Start() polls immediately), the HTTP listener (a request can
1372
1406
  // start a discovery) and pending RSU work, and why it is awaited. It needs none of them.
1373
- await SweepInterruptedRuns(undefined, msg => console.warn(msg));
1407
+ //
1408
+ // One exception: an RSU run killed inside its own RestartMJAPI step is not dead — THIS process is
1409
+ // its continuation, and processRSUPendingWork below re-attaches to it. Those are left in flight
1410
+ // (and named in `Skipped`); whichever of them nothing re-attaches to is closed out afterwards by
1411
+ // RSUPostRestartProgressSession.SweepUnattached. On a replica that runs no background workers
1412
+ // nothing would ever resume them, so there they are swept like any other.
1413
+ const bootSweep = await SweepInterruptedRuns(undefined, msg => console.warn(msg), runBackgroundWorkers ? RSUPostRestartProgressSession.WasKilledAtRestart : undefined);
1374
1414
  // Initialize and start scheduled jobs service if enabled
1375
1415
  let scheduledJobsService = null;
1376
1416
  if (runBackgroundWorkers && configInfo.scheduledJobs?.enabled) {
@@ -1424,7 +1464,8 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1424
1464
  const resumeUser = UserCache.Instance.GetSystemUser();
1425
1465
  if (runBackgroundWorkers) {
1426
1466
  // Process pending RSU work from pre-restart (entity maps, field maps, sync)
1427
- processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`));
1467
+ processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`))
1468
+ .finally(() => RSUPostRestartProgressSession.SweepUnattached(bootSweep.Skipped, undefined, msg => console.warn(msg)).catch(err => console.warn(`RSU leftover run sweep failed: ${err}`)));
1428
1469
  // Resume any integration syncs that were orphaned by the previous process restart
1429
1470
  if (resumeUser) {
1430
1471
  IntegrationEngine.Instance.ResumeOrphanedSyncs(resumeUser)
@@ -1437,32 +1478,26 @@ export const Serve = async (resolverPaths, app = CreateApp(), options) => {
1437
1478
  if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
1438
1479
  const sweepUser = resumeUser;
1439
1480
  const sweepProvider = Metadata.Provider; // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
1440
- AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser)
1481
+ AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser, configInfo.agentRunWatchdog)
1441
1482
  .catch(err => console.warn(`[AgentRunWatchdog] Startup sweep failed: ${err}`));
1442
1483
  // The watchdog repairs the RUN; nothing repaired the conversation detail, which is the row the
1443
1484
  // chat actually renders from (MJ #4222). A process that dies mid-run leaves a terminal run
1444
1485
  // beside a message that still claims to be generating, and it spins forever for anyone who
1445
- // opens it. Runs at boot (closes restart orphans) and on a timer (closes mid-life orphans),
1446
- // mirroring the watchdog's own two-phase shape.
1447
- const reconcileOrphans = () => ReconcileOrphanedConversationDetails(sweepProvider, sweepUser)
1448
- .catch(err => console.warn(`[OrphanDetailReconciler] Pass failed: ${err}`));
1449
- void reconcileOrphans();
1450
- const orphanDetailTimer = setInterval(() => void reconcileOrphans(), ORPHAN_DETAIL_SWEEP_INTERVAL_MS);
1451
- ShutdownRegistry.Instance.Register({
1452
- ShutdownName: 'OrphanDetailReconciler',
1453
- Shutdown: () => { clearInterval(orphanDetailTimer); },
1454
- });
1486
+ // opens it. Runs at boot (closes restart orphans) and, unless `conversationDetailReconciler.enabled`
1487
+ // is false, on a timer (closes mid-life orphans), mirroring the watchdog's own two-phase shape.
1488
+ StartOrphanedConversationDetailReconciler(sweepProvider, sweepUser, configInfo.conversationDetailReconciler);
1455
1489
  }
1456
1490
  // Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then a periodic tick
1457
1491
  // that closes stale and over-deadline sessions and rebuilds lost realtime recordings from their
1458
1492
  // crash-recovery shards (storage reads and writes). Self-registers with ShutdownRegistry, so its timer
1459
1493
  // is cleared by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
1460
1494
  if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — boot-time session janitor uses the server's own provider
1461
- SessionJanitor.Instance.Start(Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1495
+ // `agentSessions.janitor.enabled: false` keeps the boot recovery and shutdown drain but schedules no tick.
1496
+ SessionJanitor.Instance.StartWithSettings(configInfo.agentSessions.janitor, Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1462
1497
  .catch(err => console.warn(`[SessionJanitor] Startup failed: ${err}`));
1463
1498
  // The bridge engine's orphan reconcile likewise starts only now that this process holds its port, so it can't
1464
1499
  // take the live bridges of another MJAPI still serving that port for its own orphans (#5310).
1465
- StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1500
+ StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser, configInfo.agentSessions.bridgeReconciler); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1466
1501
  }
1467
1502
  }
1468
1503
  // Launch the durable task-graph dispatcher: claim Pending tasks, execute them with a fresh
@@ -1644,9 +1679,17 @@ async function processRSUPendingWork() {
1644
1679
  console.log(`[RSU] Processing ${pendingItems.length} pending work item(s) from pre-restart...`);
1645
1680
  // Wait a moment for metadata to be fully loaded
1646
1681
  await new Promise(resolve => setTimeout(resolve, 3000));
1682
+ // The RSU run these items belong to is still open: the pre-restart process was killed inside its
1683
+ // own RestartMJAPI step, so it never wrote a terminal result. This session re-attaches to that run
1684
+ // and reports the two steps that only ever happen here — CreateEntityMaps and StartSync — into the
1685
+ // SAME event stream, so a client that has been tailing since before the restart keeps its cursor
1686
+ // and finally learns whether the connector went live. Purely observational: every failure below is
1687
+ // swallowed, and the work proceeds whether or not a run was found to report into.
1688
+ const progressSession = new RSUPostRestartProgressSession();
1647
1689
  for (const pending of pendingItems) {
1648
1690
  const pendingWorkID = pending.ID;
1649
1691
  const item = pending.Work;
1692
+ let progress = null;
1650
1693
  // Declared outside the try so the catch can narrow a retry to what is still outstanding: what
1651
1694
  // actually got mapped this attempt. Each retry is then strictly smaller, and one poison object
1652
1695
  // cannot keep re-running its healthy siblings.
@@ -1665,6 +1708,9 @@ async function processRSUPendingWork() {
1665
1708
  await ProcessPromoteColumnsPendingWork(item, pendingWorkID, rsm, systemUser);
1666
1709
  continue;
1667
1710
  }
1711
+ // Attached only for apply-objects work: promote-columns is a follow-up to a DIFFERENT run
1712
+ // shape that has no CreateEntityMaps/StartSync steps to report.
1713
+ progress = await progressSession.For(item.CompanyIntegrationID);
1668
1714
  // Resolve connector
1669
1715
  const rv = new RunView();
1670
1716
  const ciResult = await rv.RunView({
@@ -1674,8 +1720,10 @@ async function processRSUPendingWork() {
1674
1720
  }, systemUser);
1675
1721
  const companyIntegration = ciResult.Results[0];
1676
1722
  if (!companyIntegration) {
1677
- await rsm.FailPendingWork(pendingWorkID, `CompanyIntegration ${item.CompanyIntegrationID} not found`, systemUser);
1678
- console.warn(`[RSU] CompanyIntegration ${item.CompanyIntegrationID} not found`);
1723
+ const missingCI = `CompanyIntegration ${item.CompanyIntegrationID} not found`;
1724
+ progress?.FailEntityMaps(missingCI, item.SourceObjectNames ?? []);
1725
+ await rsm.FailPendingWork(pendingWorkID, missingCI, systemUser);
1726
+ console.warn(`[RSU] ${missingCI}`);
1679
1727
  continue;
1680
1728
  }
1681
1729
  const integrationName = companyIntegration.Integration;
@@ -1686,23 +1734,39 @@ async function processRSUPendingWork() {
1686
1734
  }, systemUser);
1687
1735
  const integrationEntity = integrationResult.Results[0];
1688
1736
  if (!integrationEntity) {
1689
- await rsm.FailPendingWork(pendingWorkID, `Integration entity for ${integrationName} not found`, systemUser);
1690
- console.warn(`[RSU] Integration entity for ${integrationName} not found`);
1737
+ const missingIntegration = `Integration entity for ${integrationName} not found`;
1738
+ progress?.FailEntityMaps(missingIntegration, item.SourceObjectNames ?? []);
1739
+ await rsm.FailPendingWork(pendingWorkID, missingIntegration, systemUser);
1740
+ console.warn(`[RSU] ${missingIntegration}`);
1691
1741
  continue;
1692
1742
  }
1693
1743
  const connector = ConnectorFactory.Resolve(integrationEntity);
1694
1744
  if (!connector) {
1695
- await rsm.FailPendingWork(pendingWorkID, `Connector for ${integrationName} not found`, systemUser);
1696
- console.warn(`[RSU] Connector for ${integrationName} not found`);
1745
+ const missingConnector = `Connector for ${integrationName} not found`;
1746
+ progress?.FailEntityMaps(missingConnector, item.SourceObjectNames ?? []);
1747
+ await rsm.FailPendingWork(pendingWorkID, missingConnector, systemUser);
1748
+ console.warn(`[RSU] ${missingConnector}`);
1697
1749
  continue;
1698
1750
  }
1699
1751
  // Create entity maps + field maps for each source object
1700
1752
  const createdEntityMapIDs = [];
1701
1753
  const rvPending = new RunView();
1702
1754
  const sourceObjectFields = item.SourceObjectFields ?? {};
1703
- // Introspect schema ONCE for the entire connector, then reuse per object
1755
+ // Introspect schema ONCE for the entire connector, then reuse per object.
1756
+ //
1757
+ // IN THE CONNECTION'S CATALOG SCOPE. This runs at process start, outside any request, so
1758
+ // nothing upstream has entered a scope for it — and an unscoped catalog read falls back to
1759
+ // the SHARED catalog by design. That would build these field maps from the connector's
1760
+ // declared fields alone: every column this connection's own discovery sampled would get a
1761
+ // table column from the RSU (built in scope, from the per-connection rows) but no field map,
1762
+ // and its values would land in the overflow JSON instead of the column. Observed on the
1763
+ // sandbox 2026-09-11: 487 declared fields, 556 per-connection — 69 columns that this read
1764
+ // would have silently left unmapped. Entering the scope is not enough on a fresh process:
1765
+ // IntrospectInCatalogScope loads the catalog and warms each object's fields first.
1704
1766
  const introspect = connector.IntrospectSchema.bind(connector);
1705
- const schema = await introspect(companyIntegration, systemUser);
1767
+ const schema = await IntrospectInCatalogScope(item.CompanyIntegrationID, item.SourceObjectNames, () => introspect(companyIntegration, systemUser), systemUser);
1768
+ const objectsToMap = item.SourceObjectNames.length;
1769
+ progress?.BeginEntityMaps(objectsToMap);
1706
1770
  for (const objName of item.SourceObjectNames) {
1707
1771
  const tableName = objName.replace(/[^A-Za-z0-9_]/g, '_').toLowerCase();
1708
1772
  const entity = md.Entities.find(e => e.SchemaName.toLowerCase() === item.SchemaName.toLowerCase() &&
@@ -1797,7 +1861,12 @@ async function processRSUPendingWork() {
1797
1861
  catch (fieldErr) {
1798
1862
  console.warn(`[RSU] Field map creation failed for ${objName}: ${fieldErr}`);
1799
1863
  }
1864
+ progress?.ObjectMapped(objName, mappedObjectNames.size, objectsToMap);
1800
1865
  }
1866
+ // The applied rollup for this half of the run, in OBJECTS. `mappedObjectNames` is the same set
1867
+ // the retry path narrows against, so what is reported succeeded here is exactly what a retry
1868
+ // would NOT redo.
1869
+ progress?.CompleteEntityMaps(objectsToMap, mappedObjectNames.size, objectsToMap - mappedObjectNames.size);
1801
1870
  // Remove-as-disable: entity maps whose object is NOT in this apply's selection
1802
1871
  // are disabled (data kept; re-selection re-enables). 'ignore' opts out for subset applies.
1803
1872
  if ((item.UnselectedAction ?? 'disable') !== 'ignore') {
@@ -1812,8 +1881,11 @@ async function processRSUPendingWork() {
1812
1881
  console.warn(`[RSU] Unselected-map disable failed: ${disableErr}`);
1813
1882
  }
1814
1883
  }
1815
- // Start sync if requested
1884
+ // Start sync if requested. This is the step the setup journey is actually waiting on — the
1885
+ // connector is not live until it begins — so it is a stage of its own rather than a footnote
1886
+ // on entity-map creation.
1816
1887
  if (item.StartSync !== false) {
1888
+ progress?.BeginStartSync();
1817
1889
  try {
1818
1890
  await IntegrationEngine.Instance.Config(false, systemUser);
1819
1891
  const syncOptions = {};
@@ -1826,13 +1898,20 @@ async function processRSUPendingWork() {
1826
1898
  const opts = Object.keys(syncOptions).length > 0 ? syncOptions : undefined;
1827
1899
  IntegrationEngine.Instance.RunSync(item.CompanyIntegrationID, systemUser, 'Manual', undefined, undefined, opts);
1828
1900
  console.log(`[RSU] Sync started for ${item.CompanyIntegrationID} (EntityMaps: ${createdEntityMapIDs.length}, FullSync: ${!!item.FullSync}, SyncDirection: ${item.SyncDirection ?? 'entity-map default'})`);
1901
+ // Looked up rather than returned: RunSync resolves only when the whole sync finishes, and
1902
+ // this stage closes when the sync STARTS. A null id closes the stage anyway — the sync did
1903
+ // start; only the hand-off to its own stream is missing.
1904
+ progress?.CompleteStartSync(await FindStartedSyncRunID(item.CompanyIntegrationID, systemUser));
1829
1905
  }
1830
1906
  catch (syncErr) {
1831
1907
  console.warn(`[RSU] Sync start failed: ${syncErr}`);
1908
+ progress?.FailStartSync(`Sync start failed: ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`);
1832
1909
  }
1833
1910
  }
1834
1911
  else {
1835
1912
  console.log(`[RSU] Sync skipped for ${item.CompanyIntegrationID} (StartSync=false)`);
1913
+ progress?.BeginStartSync();
1914
+ progress?.SkipStartSync('the caller asked for no initial sync (StartSync=false)');
1836
1915
  }
1837
1916
  // Create or update schedule if CronExpression provided
1838
1917
  if (item.CronExpression) {
@@ -1868,6 +1947,7 @@ async function processRSUPendingWork() {
1868
1947
  EntityName: 'MJ: Scheduled Job Types',
1869
1948
  ExtraFilter: `DriverClass='IntegrationSyncScheduledJobDriver'`,
1870
1949
  MaxRows: 1,
1950
+ SkipTotalRowCount: true,
1871
1951
  ResultType: 'simple',
1872
1952
  Fields: ['ID']
1873
1953
  }, systemUser);
@@ -1916,6 +1996,16 @@ async function processRSUPendingWork() {
1916
1996
  // Failing terminally on the first error means the objects this item would have mapped are
1917
1997
  // silently never mapped, and the only recovery is someone noticing and re-applying by hand.
1918
1998
  const remaining = (item.SourceObjectNames ?? []).filter(n => !mappedObjectNames.has(n));
1999
+ // Same list the retry narrows to, reported into the run stream: when this half fails, those
2000
+ // objects have tables and no way to sync into them, and this is the client's only signal.
2001
+ //
2002
+ // Reported under CreateEntityMaps because that is where the overwhelming majority of this
2003
+ // block's work — and so its failures — lives. A throw from further down (schedule creation,
2004
+ // say) lands here too, with an empty `remaining`; the stage attribution is then approximate
2005
+ // but the message is the real error and the run is correctly marked failed, which is what the
2006
+ // operator needs. The alternative — inventing a stage that is not in the pipeline's step list
2007
+ // — would break the determinate stepper for the sake of a nicer label.
2008
+ progress?.FailEntityMaps(message, remaining);
1919
2009
  const requeued = await rsm.RetryPendingWork(pendingWorkID, item, remaining, systemUser);
1920
2010
  if (!requeued) {
1921
2011
  // Budget spent, or nothing left to retry. This message is the operator's only signal, so
@@ -1925,8 +2015,40 @@ async function processRSUPendingWork() {
1925
2015
  }
1926
2016
  }
1927
2017
  }
2018
+ // Terminates every RSU run this pass re-attached to. Until this lands, those runs have been
2019
+ // flagged in-flight since before the restart — which is exactly the state this whole mechanism
2020
+ // exists to end.
2021
+ await progressSession.FinishAll();
1928
2022
  console.log(`[RSU] Pending work processing complete`);
1929
2023
  }
2024
+ /**
2025
+ * The ID of the sync run a just-launched sync created, or null if it is not readable yet.
2026
+ *
2027
+ * `RunSync` resolves only when the entire sync FINISHES, so it cannot be awaited for this — the
2028
+ * StartSync stage closes when the sync begins, not when it ends. The run row is written early in
2029
+ * the sync's own startup, so a short settle plus a newest-first lookup finds it. Null is a normal
2030
+ * outcome under load and is reported as such; it never fails anything.
2031
+ */
2032
+ async function FindStartedSyncRunID(companyIntegrationID, systemUser) {
2033
+ try {
2034
+ await new Promise(resolve => setTimeout(resolve, 200));
2035
+ const rv = new RunView();
2036
+ const runResult = await rv.RunView({
2037
+ EntityName: 'MJ: Company Integration Runs',
2038
+ ExtraFilter: `CompanyIntegrationID='${companyIntegrationID.replace(/'/g, "''")}' AND Status='In Progress'`,
2039
+ OrderBy: '__mj_CreatedAt DESC',
2040
+ MaxRows: 1,
2041
+ SkipTotalRowCount: true,
2042
+ ResultType: 'simple',
2043
+ Fields: ['ID'],
2044
+ }, systemUser);
2045
+ return runResult.Success && runResult.Results.length > 0 ? runResult.Results[0].ID : null;
2046
+ }
2047
+ catch (e) {
2048
+ console.warn(`[RSU] Could not resolve the started sync run id for ${companyIntegrationID}: ${e}`);
2049
+ return null;
2050
+ }
2051
+ }
1930
2052
  /**
1931
2053
  * Creates a MSSQL ConnectionPool-compatible wrapper around a pg.Pool.
1932
2054
  * This allows existing code that references DataSourceInfo.dataSource (typed as sql.ConnectionPool)
@@ -1979,7 +2101,7 @@ function mountRealtimeRecordingRoutes(app) {
1979
2101
  return user ? { ContextUser: user, Provider: provider } : null;
1980
2102
  },
1981
2103
  LoadOwnedSession: LoadOwnedRealtimeSession,
1982
- LoadConversationScope: LoadSessionConversationScope,
2104
+ AuthorizeSession: AuthorizeLoadedSession,
1983
2105
  CreateLedger: (ledgerProvider, contextUser) => new SqlRealtimeRecordingLedger(ledgerProvider, contextUser),
1984
2106
  Scheduler: RecordingAssemblyScheduler.Instance,
1985
2107
  GraceMs: graceMs,