@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/src/index.ts CHANGED
@@ -11,6 +11,9 @@ import { setupSQLServerClient, SQLServerDataProvider, SQLServerProviderConfigDat
11
11
  import { extendConnectionPoolWithQuery } from './util.js';
12
12
  import { registerIntegrationCustomColumnPromoter, IntegrationCustomColumnPromoter } from './integration/CustomColumnPromoter.js';
13
13
  import { DisableUnselectedEntityMaps, ReenableFieldMapsForEntityMap, selectFieldsToMap } from './integration/EntityMapLifecycle.js';
14
+ import { RSUPostRestartProgressSession } from './integration/RSUPostRestartProgress.js';
15
+ import type { RSUPostRestartProgress } from './integration/RSUPostRestartProgress.js';
16
+ import { IntrospectInCatalogScope } from './integration/PostRestartIntrospect.js';
14
17
  import { default as BodyParser } from 'body-parser';
15
18
  import compression from 'compression'; // Add compression middleware
16
19
  import cors from 'cors';
@@ -31,7 +34,8 @@ import sql from 'mssql';
31
34
  import { WebSocketServer } from 'ws';
32
35
  import { RealtimeProxyServer } from './realtimeProxy/RealtimeProxyServer.js';
33
36
  import buildApolloServer from './apolloServer/index.js';
34
- import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage, RESTApiOptions } from './config.js';
37
+ import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage, RESTApiOptions, userEmailMap } from './config.js';
38
+ import { DescribeUserEmailMap } from './auth/loginEmailResolution.js';
35
39
  import { TranslateBracketsToPG } from './postgresqlCompat.js';
36
40
  import { BuildPostgreSQLConnectionConfig, DescribeReadOnlyLoginOverreach, PostgreSQLReadOnlyPool, ResolvePostgreSQLEndpoint, ResolvePostgreSQLReadOnlyCredentials, ToPGPoolConfig } from './postgresqlPoolSettings.js';
37
41
  import { default as jwt } from 'jsonwebtoken';
@@ -46,7 +50,7 @@ import createMSSQLConfig from './orm.js';
46
50
  import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
47
51
  import { CreateRealtimeRecordingRouter, REALTIME_RECORDING_MOUNT_PATH } from './rest/RealtimeRecordingHandler.js';
48
52
  import { LoadOwnedRealtimeSession } from './realtimeSessions/ownedRealtimeSession.js';
49
- import { AuthorizeAnonymousRoomSessions, LoadSessionConversationScope } from './realtimeSessions/sessionAccess.js';
53
+ import { AuthorizeAnonymousRoomSessions, AuthorizeLoadedSession } from './realtimeSessions/sessionAccess.js';
50
54
  import { RecordingAssemblyScheduler } from './realtimeSessions/RecordingAssemblyScheduler.js';
51
55
  import {
52
56
  RealtimeSessionEventService,
@@ -66,7 +70,7 @@ import { ActionEngineServer } from '@memberjunction/actions';
66
70
  import { CreateAdhocSQLAuthorizer } from './resolvers/AdhocQueryResolver.js';
67
71
  import { CacheManagerConfigFromSettings, CreateSharedCacheFromEnvironment, StartEngineSweeper, StartMetadataSweep, StartUserCacheChecks, WarmupLeaseMsFromSettings, WirePushStatusFanOut, WireSharedCacheEvents } from './sharedCache.js';
68
72
  import { PubSubManager } from './generic/PubSubManager.js';
69
- import { ReconcileOrphanedConversationDetails } from './generic/OrphanedConversationDetailReconciler.js';
73
+ import { StartOrphanedConversationDetailReconciler } from './generic/OrphanedConversationDetailReconciler.js';
70
74
  import {
71
75
  HANDOFF_OFFER_FANOUT_CHANNEL,
72
76
  HANDOFF_OFFER_TOPIC,
@@ -82,6 +86,7 @@ import { PublishIntegrationProgress } from './resolvers/IntegrationProgressResol
82
86
  import { RegisterRSUProgressBridge } from './integration/RSUProgressBridge.js';
83
87
  import { ClientToolRequestManager, AgentRunWatchdog, SqlRealtimeRecordingLedger } from '@memberjunction/ai-agents';
84
88
  import { BindBridgeEngineHostInstance, SessionJanitor, SetHostInstancePort, StartBridgeOrphanReconciliation } from './agentSessions/index.js';
89
+ import { ApplyHandoffOfferExpirySettings } from './agentSessions/HandoffOfferExpiry.js';
85
90
  import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js';
86
91
  import { MJServerWorkQueueProviderSource, StartWorkQueueHost } from './services/WorkQueueHostService.js';
87
92
  import { GetAttachmentService } from '@memberjunction/aiengine';
@@ -96,7 +101,20 @@ import {
96
101
  MJCompanyIntegrationFieldMapEntity,
97
102
  MJScheduledJobEntity,
98
103
  } from '@memberjunction/core-entities';
99
- import { ServerExtensionLoader, ServerExtensionConfig, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath, GetCorsOwningServerExtensionRoots } from '@memberjunction/server-extensions-core';
104
+ import {
105
+ ServerExtensionLoader,
106
+ ServerExtensionConfig,
107
+ SERVER_EXTENSION_CORE_SERVICE_KEYS,
108
+ type IServerExtensionHostRuntimeService,
109
+ mergeServerExtensionConfigs,
110
+ prepareServerExtensionConfigs,
111
+ describeServerExtensionMount,
112
+ InstallMediaUpgradeDispatcher,
113
+ IsGraphQLWsPath,
114
+ GetCorsOwningServerExtensionRoots,
115
+ } from '@memberjunction/server-extensions-core';
116
+ import { CreateIsolatedProvider } from './isolatedProvider.js';
117
+ import { ResolveConfiguredPrincipal } from './auth/principals.js';
100
118
  import { CreateExtensionOwnedPreflightFallback, CreateGlobalCorsMiddleware } from './globalCors.js';
101
119
  import { CoreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
102
120
  import { ApiRoute, ApiRootPath, ConfiguredPublicUrl } from './apiRoot.js';
@@ -158,6 +176,7 @@ export * from './directives/index.js';
158
176
  export { NoLog, hasNoLogParameter, getNoLogFields } from './logging/NoLog.js';
159
177
  export * from './entitySubclasses/MJEntityPermissionEntityServer.server.js';
160
178
  export * from './types.js';
179
+ export * from './requestOrigin.js';
161
180
  export {
162
181
  getSystemUser,
163
182
  getSigningKeys,
@@ -338,8 +357,6 @@ function resolveServerVersion(): string | undefined {
338
357
  }
339
358
  }
340
359
 
341
- /** How often to re-check for conversation details left behind by finished runs. */
342
- const ORPHAN_DETAIL_SWEEP_INTERVAL_MS = 5 * 60_000;
343
360
 
344
361
  /**
345
362
  * Replicate handoff-offer updates across server instances over Redis.
@@ -611,10 +628,19 @@ const setupComplete$ = new ReplaySubject(1);
611
628
  codegenTestClient.release();
612
629
 
613
630
  const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
631
+ // Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
632
+ // so boot does not pay a second full metadata load. The refresh interval stays non-zero on
633
+ // PostgreSQL on purpose: PostgreSQLDataProvider.AllowRefresh is `CheckRefreshIntervalSeconds > 0`,
634
+ // so an interval of 0 would make every later codegenPgProvider.Refresh() — the one RSU CodeGen
635
+ // issues after DDL — return without reloading, leaving this provider frozen at the boot catalog.
636
+ // (SQL Server's AllowRefresh is independent of the interval, so its codegen provider can use 0.)
614
637
  const codegenPgConfigData = new PostgreSQLProviderConfigData(
615
638
  codegenPgConnectionConfig,
616
639
  mj_core_schema,
617
640
  cacheRefreshInterval / 1000, // ms → seconds
641
+ undefined,
642
+ undefined,
643
+ false,
618
644
  );
619
645
  const codegenPgProvider = new PostgreSQLDataProvider();
620
646
  await codegenPgProvider.Config(codegenPgConfigData); // separate pool (per-instance manager); does NOT touch the global API provider
@@ -762,8 +788,18 @@ const setupComplete$ = new ReplaySubject(1);
762
788
  await codegenPool.connect();
763
789
 
764
790
  const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
765
- // Same ms→seconds seam as the main provider config above — see providerConfigUnits.ts
766
- const codegenConfig = new SQLServerProviderConfigData(codegenPool, mj_core_schema, MetadataCacheRefreshIntervalSeconds(cacheRefreshInterval));
791
+ // Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
792
+ // and disable a duplicate background refresh timer (0): avoids a second full metadata load
793
+ // on boot while explicit codegenProvider.Refresh() after DDL still reloads from the DB
794
+ // (SQLServerDataProvider.AllowRefresh does not depend on the interval; PostgreSQL's does — see above).
795
+ const codegenConfig = new SQLServerProviderConfigData(
796
+ codegenPool,
797
+ mj_core_schema,
798
+ 0,
799
+ undefined,
800
+ undefined,
801
+ false,
802
+ );
767
803
  const codegenProvider = new SQLServerDataProvider();
768
804
  await codegenProvider.Config(codegenConfig);
769
805
  RuntimeSchemaManager.Instance.SetDDLProvider(codegenProvider);
@@ -1270,6 +1306,7 @@ const setupComplete$ = new ReplaySubject(1);
1270
1306
  },
1271
1307
  // context() now just reads the already-validated payload — no I/O, no logging
1272
1308
  context: async (ctx) => {
1309
+ // No RequestOrigin here: the upgrade request's Origin is not carried onto subscription contexts.
1273
1310
  return { userPayload: ctx.extra.userPayload as UserPayload };
1274
1311
  },
1275
1312
  onClose: (ctx) => {
@@ -1319,7 +1356,7 @@ const setupComplete$ = new ReplaySubject(1);
1319
1356
  },
1320
1357
  // High compression level (good balance between CPU and compression ratio)
1321
1358
  level: 6
1322
- }));
1359
+ }) as object as express.RequestHandler);
1323
1360
 
1324
1361
  // Health check — before every middleware contribution and the auth middleware, so cloud platform
1325
1362
  // probes never generate auth noise. Every core route mounts under MJAPI_BASE_PATH (see apiRoot.ts).
@@ -1343,6 +1380,19 @@ const setupComplete$ = new ReplaySubject(1);
1343
1380
  const extensionLoader = new ServerExtensionLoader();
1344
1381
  _currentExtensionLoader = extensionLoader;
1345
1382
 
1383
+ const hostRuntimeService: IServerExtensionHostRuntimeService = {
1384
+ CreateIsolatedProvider,
1385
+ GetSystemUser: () => getSystemUser(),
1386
+ ResolvePrincipal: (configuredEmailOrId, subsystemLabel) => ResolveConfiguredPrincipal(configuredEmailOrId, subsystemLabel),
1387
+ };
1388
+ extensionLoader.Services.RegisterService(SERVER_EXTENSION_CORE_SERVICE_KEYS.HostRuntime, hostRuntimeService);
1389
+ if (coreAuthenticatedRouters.MagicLinkService) {
1390
+ extensionLoader.Services.RegisterService(
1391
+ SERVER_EXTENSION_CORE_SERVICE_KEYS.MagicLink,
1392
+ coreAuthenticatedRouters.MagicLinkService,
1393
+ );
1394
+ }
1395
+
1346
1396
  // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1347
1397
  // Backwards-compatibility shim: synthesize ServerExtensionConfig entries from legacy configInfo.telephony
1348
1398
  const telephonyExtensionConfigs: ServerExtensionConfig[] = [];
@@ -1457,6 +1507,11 @@ const setupComplete$ = new ReplaySubject(1);
1457
1507
  MountAuthCatalogRoute(app, startupLog);
1458
1508
 
1459
1509
  // ─── Unified auth middleware (replaces both REST authMiddleware and contextFunction auth) ─────
1510
+ // Always shown, whatever the log level: a configured map makes logins run as other people's records
1511
+ const userEmailMapWarning = DescribeUserEmailMap(userEmailMap);
1512
+ if (userEmailMapWarning) {
1513
+ console.warn(userEmailMapWarning);
1514
+ }
1460
1515
  app.use(CreateUnifiedAuthMiddleware(dataSources));
1461
1516
 
1462
1517
  // ─── Post-auth middleware from BaseServerMiddleware plugins ─────
@@ -1593,6 +1648,11 @@ const setupComplete$ = new ReplaySubject(1);
1593
1648
  LogStatus(`[ServerRole] Running in '${serverRole}' mode — background worker services are disabled on this replica.`);
1594
1649
  }
1595
1650
 
1651
+ // Every role runs agents, so every role's watchdog takes the configured intervals (before any run starts).
1652
+ AgentRunWatchdog.Instance.Configure(configInfo.agentRunWatchdog);
1653
+ // The handoff offer registry starts its own expiry sweep when it loads, on every role; apply the host's setting.
1654
+ ApplyHandoffOfferExpirySettings(configInfo.agentSessions.handoffOfferExpiry);
1655
+
1596
1656
  // Close out run artifacts a dead process left open, BEFORE anything below can start a new run.
1597
1657
  //
1598
1658
  // A killed process (OOM killer, SIGKILL, host reboot) never writes its run's terminal result, so
@@ -1602,7 +1662,17 @@ const setupComplete$ = new ReplaySubject(1);
1602
1662
  // to a process that no longer exists. That is why it runs here, ahead of the scheduler, the
1603
1663
  // integration sync worker (its Start() polls immediately), the HTTP listener (a request can
1604
1664
  // start a discovery) and pending RSU work, and why it is awaited. It needs none of them.
1605
- await SweepInterruptedRuns(undefined, msg => console.warn(msg));
1665
+ //
1666
+ // One exception: an RSU run killed inside its own RestartMJAPI step is not dead — THIS process is
1667
+ // its continuation, and processRSUPendingWork below re-attaches to it. Those are left in flight
1668
+ // (and named in `Skipped`); whichever of them nothing re-attaches to is closed out afterwards by
1669
+ // RSUPostRestartProgressSession.SweepUnattached. On a replica that runs no background workers
1670
+ // nothing would ever resume them, so there they are swept like any other.
1671
+ const bootSweep = await SweepInterruptedRuns(
1672
+ undefined,
1673
+ msg => console.warn(msg),
1674
+ runBackgroundWorkers ? RSUPostRestartProgressSession.WasKilledAtRestart : undefined
1675
+ );
1606
1676
 
1607
1677
  // Initialize and start scheduled jobs service if enabled
1608
1678
  let scheduledJobsService: ScheduledJobsService | null = null;
@@ -1662,7 +1732,12 @@ const setupComplete$ = new ReplaySubject(1);
1662
1732
 
1663
1733
  if (runBackgroundWorkers) {
1664
1734
  // Process pending RSU work from pre-restart (entity maps, field maps, sync)
1665
- processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`));
1735
+ processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`))
1736
+ .finally(() =>
1737
+ RSUPostRestartProgressSession.SweepUnattached(bootSweep.Skipped, undefined, msg => console.warn(msg)).catch(err =>
1738
+ console.warn(`RSU leftover run sweep failed: ${err}`)
1739
+ )
1740
+ );
1666
1741
 
1667
1742
  // Resume any integration syncs that were orphaned by the previous process restart
1668
1743
  if (resumeUser) {
@@ -1677,23 +1752,15 @@ const setupComplete$ = new ReplaySubject(1);
1677
1752
  if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
1678
1753
  const sweepUser = resumeUser;
1679
1754
  const sweepProvider = Metadata.Provider; // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
1680
- AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser)
1755
+ AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser, configInfo.agentRunWatchdog)
1681
1756
  .catch(err => console.warn(`[AgentRunWatchdog] Startup sweep failed: ${err}`));
1682
1757
 
1683
1758
  // The watchdog repairs the RUN; nothing repaired the conversation detail, which is the row the
1684
1759
  // chat actually renders from (MJ #4222). A process that dies mid-run leaves a terminal run
1685
1760
  // beside a message that still claims to be generating, and it spins forever for anyone who
1686
- // opens it. Runs at boot (closes restart orphans) and on a timer (closes mid-life orphans),
1687
- // mirroring the watchdog's own two-phase shape.
1688
- const reconcileOrphans = () =>
1689
- ReconcileOrphanedConversationDetails(sweepProvider, sweepUser)
1690
- .catch(err => console.warn(`[OrphanDetailReconciler] Pass failed: ${err}`));
1691
- void reconcileOrphans();
1692
- const orphanDetailTimer = setInterval(() => void reconcileOrphans(), ORPHAN_DETAIL_SWEEP_INTERVAL_MS);
1693
- ShutdownRegistry.Instance.Register({
1694
- ShutdownName: 'OrphanDetailReconciler',
1695
- Shutdown: () => { clearInterval(orphanDetailTimer); },
1696
- });
1761
+ // opens it. Runs at boot (closes restart orphans) and, unless `conversationDetailReconciler.enabled`
1762
+ // is false, on a timer (closes mid-life orphans), mirroring the watchdog's own two-phase shape.
1763
+ StartOrphanedConversationDetailReconciler(sweepProvider, sweepUser, configInfo.conversationDetailReconciler);
1697
1764
  }
1698
1765
 
1699
1766
  // Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then a periodic tick
@@ -1701,11 +1768,12 @@ const setupComplete$ = new ReplaySubject(1);
1701
1768
  // crash-recovery shards (storage reads and writes). Self-registers with ShutdownRegistry, so its timer
1702
1769
  // is cleared by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
1703
1770
  if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — boot-time session janitor uses the server's own provider
1704
- SessionJanitor.Instance.Start(Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1771
+ // `agentSessions.janitor.enabled: false` keeps the boot recovery and shutdown drain but schedules no tick.
1772
+ SessionJanitor.Instance.StartWithSettings(configInfo.agentSessions.janitor, Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1705
1773
  .catch(err => console.warn(`[SessionJanitor] Startup failed: ${err}`));
1706
1774
  // The bridge engine's orphan reconcile likewise starts only now that this process holds its port, so it can't
1707
1775
  // take the live bridges of another MJAPI still serving that port for its own orphans (#5310).
1708
- StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1776
+ StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser, configInfo.agentSessions.bridgeReconciler); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1709
1777
  }
1710
1778
  }
1711
1779
 
@@ -1908,9 +1976,18 @@ async function processRSUPendingWork(): Promise<void> {
1908
1976
  // Wait a moment for metadata to be fully loaded
1909
1977
  await new Promise(resolve => setTimeout(resolve, 3000));
1910
1978
 
1979
+ // The RSU run these items belong to is still open: the pre-restart process was killed inside its
1980
+ // own RestartMJAPI step, so it never wrote a terminal result. This session re-attaches to that run
1981
+ // and reports the two steps that only ever happen here — CreateEntityMaps and StartSync — into the
1982
+ // SAME event stream, so a client that has been tailing since before the restart keeps its cursor
1983
+ // and finally learns whether the connector went live. Purely observational: every failure below is
1984
+ // swallowed, and the work proceeds whether or not a run was found to report into.
1985
+ const progressSession = new RSUPostRestartProgressSession();
1986
+
1911
1987
  for (const pending of pendingItems) {
1912
1988
  const pendingWorkID = pending.ID;
1913
1989
  const item = pending.Work;
1990
+ let progress: RSUPostRestartProgress | null = null;
1914
1991
  // Declared outside the try so the catch can narrow a retry to what is still outstanding: what
1915
1992
  // actually got mapped this attempt. Each retry is then strictly smaller, and one poison object
1916
1993
  // cannot keep re-running its healthy siblings.
@@ -1932,6 +2009,10 @@ async function processRSUPendingWork(): Promise<void> {
1932
2009
  continue;
1933
2010
  }
1934
2011
 
2012
+ // Attached only for apply-objects work: promote-columns is a follow-up to a DIFFERENT run
2013
+ // shape that has no CreateEntityMaps/StartSync steps to report.
2014
+ progress = await progressSession.For(item.CompanyIntegrationID);
2015
+
1935
2016
  // Resolve connector
1936
2017
  const rv = new RunView();
1937
2018
  const ciResult = await rv.RunView<MJCompanyIntegrationEntity>({
@@ -1941,8 +2022,10 @@ async function processRSUPendingWork(): Promise<void> {
1941
2022
  }, systemUser);
1942
2023
  const companyIntegration = ciResult.Results[0];
1943
2024
  if (!companyIntegration) {
1944
- await rsm.FailPendingWork(pendingWorkID, `CompanyIntegration ${item.CompanyIntegrationID} not found`, systemUser);
1945
- console.warn(`[RSU] CompanyIntegration ${item.CompanyIntegrationID} not found`);
2025
+ const missingCI = `CompanyIntegration ${item.CompanyIntegrationID} not found`;
2026
+ progress?.FailEntityMaps(missingCI, item.SourceObjectNames ?? []);
2027
+ await rsm.FailPendingWork(pendingWorkID, missingCI, systemUser);
2028
+ console.warn(`[RSU] ${missingCI}`);
1946
2029
  continue;
1947
2030
  }
1948
2031
 
@@ -1954,14 +2037,18 @@ async function processRSUPendingWork(): Promise<void> {
1954
2037
  }, systemUser);
1955
2038
  const integrationEntity = integrationResult.Results[0];
1956
2039
  if (!integrationEntity) {
1957
- await rsm.FailPendingWork(pendingWorkID, `Integration entity for ${integrationName} not found`, systemUser);
1958
- console.warn(`[RSU] Integration entity for ${integrationName} not found`);
2040
+ const missingIntegration = `Integration entity for ${integrationName} not found`;
2041
+ progress?.FailEntityMaps(missingIntegration, item.SourceObjectNames ?? []);
2042
+ await rsm.FailPendingWork(pendingWorkID, missingIntegration, systemUser);
2043
+ console.warn(`[RSU] ${missingIntegration}`);
1959
2044
  continue;
1960
2045
  }
1961
2046
  const connector = ConnectorFactory.Resolve(integrationEntity);
1962
2047
  if (!connector) {
1963
- await rsm.FailPendingWork(pendingWorkID, `Connector for ${integrationName} not found`, systemUser);
1964
- console.warn(`[RSU] Connector for ${integrationName} not found`);
2048
+ const missingConnector = `Connector for ${integrationName} not found`;
2049
+ progress?.FailEntityMaps(missingConnector, item.SourceObjectNames ?? []);
2050
+ await rsm.FailPendingWork(pendingWorkID, missingConnector, systemUser);
2051
+ console.warn(`[RSU] ${missingConnector}`);
1965
2052
  continue;
1966
2053
  }
1967
2054
 
@@ -1970,10 +2057,28 @@ async function processRSUPendingWork(): Promise<void> {
1970
2057
  const rvPending = new RunView();
1971
2058
  const sourceObjectFields: Record<string, string[] | null> = item.SourceObjectFields ?? {};
1972
2059
 
1973
- // Introspect schema ONCE for the entire connector, then reuse per object
2060
+ // Introspect schema ONCE for the entire connector, then reuse per object.
2061
+ //
2062
+ // IN THE CONNECTION'S CATALOG SCOPE. This runs at process start, outside any request, so
2063
+ // nothing upstream has entered a scope for it — and an unscoped catalog read falls back to
2064
+ // the SHARED catalog by design. That would build these field maps from the connector's
2065
+ // declared fields alone: every column this connection's own discovery sampled would get a
2066
+ // table column from the RSU (built in scope, from the per-connection rows) but no field map,
2067
+ // and its values would land in the overflow JSON instead of the column. Observed on the
2068
+ // sandbox 2026-09-11: 487 declared fields, 556 per-connection — 69 columns that this read
2069
+ // would have silently left unmapped. Entering the scope is not enough on a fresh process:
2070
+ // IntrospectInCatalogScope loads the catalog and warms each object's fields first.
1974
2071
  const introspect = connector.IntrospectSchema.bind(connector) as
1975
2072
  (ci: unknown, u: unknown) => Promise<{ Objects: Array<{ ExternalName: string; Fields: Array<{ Name: string; IsPrimaryKey?: boolean; IsRequired?: boolean }> }> }>;
1976
- const schema = await introspect(companyIntegration, systemUser);
2073
+ const schema = await IntrospectInCatalogScope(
2074
+ item.CompanyIntegrationID,
2075
+ item.SourceObjectNames,
2076
+ () => introspect(companyIntegration, systemUser),
2077
+ systemUser,
2078
+ );
2079
+
2080
+ const objectsToMap = item.SourceObjectNames.length;
2081
+ progress?.BeginEntityMaps(objectsToMap);
1977
2082
 
1978
2083
  for (const objName of item.SourceObjectNames) {
1979
2084
  const tableName = objName.replace(/[^A-Za-z0-9_]/g, '_').toLowerCase();
@@ -2079,8 +2184,15 @@ async function processRSUPendingWork(): Promise<void> {
2079
2184
  } catch (fieldErr) {
2080
2185
  console.warn(`[RSU] Field map creation failed for ${objName}: ${fieldErr}`);
2081
2186
  }
2187
+
2188
+ progress?.ObjectMapped(objName, mappedObjectNames.size, objectsToMap);
2082
2189
  }
2083
2190
 
2191
+ // The applied rollup for this half of the run, in OBJECTS. `mappedObjectNames` is the same set
2192
+ // the retry path narrows against, so what is reported succeeded here is exactly what a retry
2193
+ // would NOT redo.
2194
+ progress?.CompleteEntityMaps(objectsToMap, mappedObjectNames.size, objectsToMap - mappedObjectNames.size);
2195
+
2084
2196
  // Remove-as-disable: entity maps whose object is NOT in this apply's selection
2085
2197
  // are disabled (data kept; re-selection re-enables). 'ignore' opts out for subset applies.
2086
2198
  if ((item.UnselectedAction ?? 'disable') !== 'ignore') {
@@ -2096,8 +2208,11 @@ async function processRSUPendingWork(): Promise<void> {
2096
2208
  }
2097
2209
  }
2098
2210
 
2099
- // Start sync if requested
2211
+ // Start sync if requested. This is the step the setup journey is actually waiting on — the
2212
+ // connector is not live until it begins — so it is a stage of its own rather than a footnote
2213
+ // on entity-map creation.
2100
2214
  if (item.StartSync !== false) {
2215
+ progress?.BeginStartSync();
2101
2216
  try {
2102
2217
  await IntegrationEngine.Instance.Config(false, systemUser);
2103
2218
  const syncOptions: IntegrationSyncOptions = {};
@@ -2107,11 +2222,18 @@ async function processRSUPendingWork(): Promise<void> {
2107
2222
  const opts = Object.keys(syncOptions).length > 0 ? syncOptions : undefined;
2108
2223
  IntegrationEngine.Instance.RunSync(item.CompanyIntegrationID, systemUser, 'Manual', undefined, undefined, opts);
2109
2224
  console.log(`[RSU] Sync started for ${item.CompanyIntegrationID} (EntityMaps: ${createdEntityMapIDs.length}, FullSync: ${!!item.FullSync}, SyncDirection: ${item.SyncDirection ?? 'entity-map default'})`);
2225
+ // Looked up rather than returned: RunSync resolves only when the whole sync finishes, and
2226
+ // this stage closes when the sync STARTS. A null id closes the stage anyway — the sync did
2227
+ // start; only the hand-off to its own stream is missing.
2228
+ progress?.CompleteStartSync(await FindStartedSyncRunID(item.CompanyIntegrationID, systemUser));
2110
2229
  } catch (syncErr) {
2111
2230
  console.warn(`[RSU] Sync start failed: ${syncErr}`);
2231
+ progress?.FailStartSync(`Sync start failed: ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`);
2112
2232
  }
2113
2233
  } else {
2114
2234
  console.log(`[RSU] Sync skipped for ${item.CompanyIntegrationID} (StartSync=false)`);
2235
+ progress?.BeginStartSync();
2236
+ progress?.SkipStartSync('the caller asked for no initial sync (StartSync=false)');
2115
2237
  }
2116
2238
 
2117
2239
  // Create or update schedule if CronExpression provided
@@ -2150,6 +2272,7 @@ async function processRSUPendingWork(): Promise<void> {
2150
2272
  EntityName: 'MJ: Scheduled Job Types',
2151
2273
  ExtraFilter: `DriverClass='IntegrationSyncScheduledJobDriver'`,
2152
2274
  MaxRows: 1,
2275
+ SkipTotalRowCount: true,
2153
2276
  ResultType: 'simple',
2154
2277
  Fields: ['ID']
2155
2278
  }, systemUser);
@@ -2198,6 +2321,16 @@ async function processRSUPendingWork(): Promise<void> {
2198
2321
  // Failing terminally on the first error means the objects this item would have mapped are
2199
2322
  // silently never mapped, and the only recovery is someone noticing and re-applying by hand.
2200
2323
  const remaining = (item.SourceObjectNames ?? []).filter(n => !mappedObjectNames.has(n));
2324
+ // Same list the retry narrows to, reported into the run stream: when this half fails, those
2325
+ // objects have tables and no way to sync into them, and this is the client's only signal.
2326
+ //
2327
+ // Reported under CreateEntityMaps because that is where the overwhelming majority of this
2328
+ // block's work — and so its failures — lives. A throw from further down (schedule creation,
2329
+ // say) lands here too, with an empty `remaining`; the stage attribution is then approximate
2330
+ // but the message is the real error and the run is correctly marked failed, which is what the
2331
+ // operator needs. The alternative — inventing a stage that is not in the pipeline's step list
2332
+ // — would break the determinate stepper for the sake of a nicer label.
2333
+ progress?.FailEntityMaps(message, remaining);
2201
2334
  const requeued = await rsm.RetryPendingWork(pendingWorkID, item, remaining, systemUser);
2202
2335
  if (!requeued) {
2203
2336
  // Budget spent, or nothing left to retry. This message is the operator's only signal, so
@@ -2208,9 +2341,42 @@ async function processRSUPendingWork(): Promise<void> {
2208
2341
  }
2209
2342
  }
2210
2343
 
2344
+ // Terminates every RSU run this pass re-attached to. Until this lands, those runs have been
2345
+ // flagged in-flight since before the restart — which is exactly the state this whole mechanism
2346
+ // exists to end.
2347
+ await progressSession.FinishAll();
2348
+
2211
2349
  console.log(`[RSU] Pending work processing complete`);
2212
2350
  }
2213
2351
 
2352
+ /**
2353
+ * The ID of the sync run a just-launched sync created, or null if it is not readable yet.
2354
+ *
2355
+ * `RunSync` resolves only when the entire sync FINISHES, so it cannot be awaited for this — the
2356
+ * StartSync stage closes when the sync begins, not when it ends. The run row is written early in
2357
+ * the sync's own startup, so a short settle plus a newest-first lookup finds it. Null is a normal
2358
+ * outcome under load and is reported as such; it never fails anything.
2359
+ */
2360
+ async function FindStartedSyncRunID(companyIntegrationID: string, systemUser: UserInfo): Promise<string | null> {
2361
+ try {
2362
+ await new Promise(resolve => setTimeout(resolve, 200));
2363
+ const rv = new RunView();
2364
+ const runResult = await rv.RunView<{ ID: string }>({
2365
+ EntityName: 'MJ: Company Integration Runs',
2366
+ ExtraFilter: `CompanyIntegrationID='${companyIntegrationID.replace(/'/g, "''")}' AND Status='In Progress'`,
2367
+ OrderBy: '__mj_CreatedAt DESC',
2368
+ MaxRows: 1,
2369
+ SkipTotalRowCount: true,
2370
+ ResultType: 'simple',
2371
+ Fields: ['ID'],
2372
+ }, systemUser);
2373
+ return runResult.Success && runResult.Results.length > 0 ? runResult.Results[0].ID : null;
2374
+ } catch (e) {
2375
+ console.warn(`[RSU] Could not resolve the started sync run id for ${companyIntegrationID}: ${e}`);
2376
+ return null;
2377
+ }
2378
+ }
2379
+
2214
2380
  /**
2215
2381
  * Creates a MSSQL ConnectionPool-compatible wrapper around a pg.Pool.
2216
2382
  * This allows existing code that references DataSourceInfo.dataSource (typed as sql.ConnectionPool)
@@ -2263,7 +2429,7 @@ function mountRealtimeRecordingRoutes(app: Application): boolean {
2263
2429
  return user ? { ContextUser: user, Provider: provider } : null;
2264
2430
  },
2265
2431
  LoadOwnedSession: LoadOwnedRealtimeSession,
2266
- LoadConversationScope: LoadSessionConversationScope,
2432
+ AuthorizeSession: AuthorizeLoadedSession,
2267
2433
  CreateLedger: (ledgerProvider, contextUser) => new SqlRealtimeRecordingLedger(ledgerProvider, contextUser),
2268
2434
  Scheduler: RecordingAssemblyScheduler.Instance,
2269
2435
  GraceMs: graceMs,