@mastra/factory 0.24.0-alpha.1 → 0.24.0-alpha.3

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 (190) hide show
  1. package/README.md +103 -4
  2. package/dist/auth.d.ts +14 -0
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +45 -9
  5. package/dist/auth.js.map +1 -1
  6. package/dist/boards/work-transition-policy.d.ts.map +1 -1
  7. package/dist/boards/work-transition-policy.js +10 -0
  8. package/dist/boards/work-transition-policy.js.map +1 -1
  9. package/dist/boards/work.d.ts +14 -0
  10. package/dist/boards/work.d.ts.map +1 -1
  11. package/dist/boards/work.js +70 -7
  12. package/dist/boards/work.js.map +1 -1
  13. package/dist/capabilities/version-control.d.ts +26 -0
  14. package/dist/capabilities/version-control.d.ts.map +1 -1
  15. package/dist/factory.d.ts +8 -0
  16. package/dist/factory.d.ts.map +1 -1
  17. package/dist/factory.js +191 -16
  18. package/dist/factory.js.map +1 -1
  19. package/dist/integrations/github/integration.d.ts.map +1 -1
  20. package/dist/integrations/github/integration.js +37 -1
  21. package/dist/integrations/github/integration.js.map +1 -1
  22. package/dist/integrations/gitlab/api.d.ts +15 -0
  23. package/dist/integrations/gitlab/api.d.ts.map +1 -1
  24. package/dist/integrations/gitlab/api.js +9 -0
  25. package/dist/integrations/gitlab/api.js.map +1 -1
  26. package/dist/integrations/gitlab/version-control.d.ts.map +1 -1
  27. package/dist/integrations/gitlab/version-control.js +37 -3
  28. package/dist/integrations/gitlab/version-control.js.map +1 -1
  29. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  30. package/dist/integrations/platform/github/integration.js +27 -1
  31. package/dist/integrations/platform/github/integration.js.map +1 -1
  32. package/dist/integrations/subscription-session.d.ts +15 -0
  33. package/dist/integrations/subscription-session.d.ts.map +1 -1
  34. package/dist/integrations/subscription-session.js +30 -13
  35. package/dist/integrations/subscription-session.js.map +1 -1
  36. package/dist/mcp/disconnect.d.ts +10 -0
  37. package/dist/mcp/disconnect.d.ts.map +1 -0
  38. package/dist/mcp/disconnect.js +44 -0
  39. package/dist/mcp/disconnect.js.map +1 -0
  40. package/dist/mcp/routes.d.ts +46 -0
  41. package/dist/mcp/routes.d.ts.map +1 -0
  42. package/dist/mcp/routes.js +243 -0
  43. package/dist/mcp/routes.js.map +1 -0
  44. package/dist/provider-display-name.d.ts +2 -0
  45. package/dist/provider-display-name.d.ts.map +1 -0
  46. package/dist/provider-display-name.js +16 -0
  47. package/dist/provider-display-name.js.map +1 -0
  48. package/dist/routes/config.js +2 -2
  49. package/dist/routes/config.js.map +1 -1
  50. package/dist/routes/contracts.d.ts +4 -0
  51. package/dist/routes/contracts.d.ts.map +1 -1
  52. package/dist/routes/contracts.js +3 -1
  53. package/dist/routes/contracts.js.map +1 -1
  54. package/dist/routes/oauth.js +1 -1
  55. package/dist/routes/oauth.js.map +1 -1
  56. package/dist/routes/provider-credentials.d.ts +6 -2
  57. package/dist/routes/provider-credentials.d.ts.map +1 -1
  58. package/dist/routes/provider-credentials.js +20 -7
  59. package/dist/routes/provider-credentials.js.map +1 -1
  60. package/dist/routes/source-control-sessions.d.ts +1 -0
  61. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  62. package/dist/routes/source-control-sessions.js +1 -1
  63. package/dist/routes/source-control-sessions.js.map +1 -1
  64. package/dist/routes/surface.d.ts +1 -0
  65. package/dist/routes/surface.d.ts.map +1 -1
  66. package/dist/routes/surface.js +4 -3
  67. package/dist/routes/surface.js.map +1 -1
  68. package/dist/routes/work-items.d.ts.map +1 -1
  69. package/dist/routes/work-items.js +61 -121
  70. package/dist/routes/work-items.js.map +1 -1
  71. package/dist/rules/dispatcher.d.ts +7 -0
  72. package/dist/rules/dispatcher.d.ts.map +1 -1
  73. package/dist/rules/dispatcher.js +62 -5
  74. package/dist/rules/dispatcher.js.map +1 -1
  75. package/dist/rules/processor.d.ts.map +1 -1
  76. package/dist/rules/processor.js +2 -1
  77. package/dist/rules/processor.js.map +1 -1
  78. package/dist/rules/tools.d.ts.map +1 -1
  79. package/dist/rules/tools.js +82 -3
  80. package/dist/rules/tools.js.map +1 -1
  81. package/dist/rules/transition-service.d.ts +17 -0
  82. package/dist/rules/transition-service.d.ts.map +1 -1
  83. package/dist/rules/transition-service.js +25 -0
  84. package/dist/rules/transition-service.js.map +1 -1
  85. package/dist/rules/types.d.ts +2 -4
  86. package/dist/rules/types.d.ts.map +1 -1
  87. package/dist/rules/types.js +1 -4
  88. package/dist/rules/types.js.map +1 -1
  89. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -1
  90. package/dist/sandbox/local-factory-sandbox.js +1 -0
  91. package/dist/sandbox/local-factory-sandbox.js.map +1 -1
  92. package/dist/session/factory-session.d.ts +15 -1
  93. package/dist/session/factory-session.d.ts.map +1 -1
  94. package/dist/session/factory-session.js +4 -2
  95. package/dist/session/factory-session.js.map +1 -1
  96. package/dist/session/reply-credential-processor.d.ts +15 -0
  97. package/dist/session/reply-credential-processor.d.ts.map +1 -0
  98. package/dist/session/reply-credential-processor.js +40 -0
  99. package/dist/session/reply-credential-processor.js.map +1 -0
  100. package/dist/session/source-control-tools.d.ts +19 -1
  101. package/dist/session/source-control-tools.d.ts.map +1 -1
  102. package/dist/session/source-control-tools.js +70 -3
  103. package/dist/session/source-control-tools.js.map +1 -1
  104. package/dist/storage/domains/audit/domain.js +1 -1
  105. package/dist/storage/domains/projects/base.d.ts +6 -0
  106. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  107. package/dist/storage/domains/projects/base.js +12 -0
  108. package/dist/storage/domains/projects/base.js.map +1 -1
  109. package/dist/storage/domains/source-control/base.d.ts +17 -0
  110. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  111. package/dist/storage/domains/source-control/base.js +23 -0
  112. package/dist/storage/domains/source-control/base.js.map +1 -1
  113. package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
  114. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  115. package/dist/storage/domains/source-control/inmemory.js +5 -1
  116. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  117. package/dist/storage/domains/work-items/base.d.ts +56 -0
  118. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  119. package/dist/storage/domains/work-items/base.js +139 -25
  120. package/dist/storage/domains/work-items/base.js.map +1 -1
  121. package/dist/tools/annotations.d.ts +7 -0
  122. package/dist/tools/annotations.d.ts.map +1 -0
  123. package/dist/tools/annotations.js +102 -0
  124. package/dist/tools/annotations.js.map +1 -0
  125. package/dist/tools/approval-tools.d.ts +15 -0
  126. package/dist/tools/approval-tools.d.ts.map +1 -0
  127. package/dist/tools/approval-tools.js +77 -0
  128. package/dist/tools/approval-tools.js.map +1 -0
  129. package/dist/tools/deliver.d.ts +54 -0
  130. package/dist/tools/deliver.d.ts.map +1 -0
  131. package/dist/tools/deliver.js +105 -0
  132. package/dist/tools/deliver.js.map +1 -0
  133. package/dist/tools/index.d.ts +29 -0
  134. package/dist/tools/index.d.ts.map +1 -0
  135. package/dist/tools/index.js +39 -0
  136. package/dist/tools/index.js.map +1 -0
  137. package/dist/tools/messaging-tools.d.ts +28 -0
  138. package/dist/tools/messaging-tools.d.ts.map +1 -0
  139. package/dist/tools/messaging-tools.js +312 -0
  140. package/dist/tools/messaging-tools.js.map +1 -0
  141. package/dist/tools/permissions.d.ts +31 -0
  142. package/dist/tools/permissions.d.ts.map +1 -0
  143. package/dist/tools/permissions.js +44 -0
  144. package/dist/tools/permissions.js.map +1 -0
  145. package/dist/tools/read-tools.d.ts +27 -0
  146. package/dist/tools/read-tools.d.ts.map +1 -0
  147. package/dist/tools/read-tools.js +285 -0
  148. package/dist/tools/read-tools.js.map +1 -0
  149. package/dist/tools/reports.d.ts +163 -0
  150. package/dist/tools/reports.d.ts.map +1 -0
  151. package/dist/tools/reports.js +352 -0
  152. package/dist/tools/reports.js.map +1 -0
  153. package/dist/tools/run-watch.d.ts +46 -0
  154. package/dist/tools/run-watch.d.ts.map +1 -0
  155. package/dist/tools/run-watch.js +102 -0
  156. package/dist/tools/run-watch.js.map +1 -0
  157. package/dist/tools/scope.d.ts +45 -0
  158. package/dist/tools/scope.d.ts.map +1 -0
  159. package/dist/tools/scope.js +73 -0
  160. package/dist/tools/scope.js.map +1 -0
  161. package/dist/tools/session-tools.d.ts +31 -0
  162. package/dist/tools/session-tools.d.ts.map +1 -0
  163. package/dist/tools/session-tools.js +312 -0
  164. package/dist/tools/session-tools.js.map +1 -0
  165. package/dist/tools/sessions-state-processor.d.ts +37 -0
  166. package/dist/tools/sessions-state-processor.d.ts.map +1 -0
  167. package/dist/tools/sessions-state-processor.js +206 -0
  168. package/dist/tools/sessions-state-processor.js.map +1 -0
  169. package/dist/tools/work-item-tools.d.ts +28 -0
  170. package/dist/tools/work-item-tools.d.ts.map +1 -0
  171. package/dist/tools/work-item-tools.js +322 -0
  172. package/dist/tools/work-item-tools.js.map +1 -0
  173. package/dist/work-items/create-work-item.d.ts +55 -0
  174. package/dist/work-items/create-work-item.d.ts.map +1 -0
  175. package/dist/work-items/create-work-item.js +101 -0
  176. package/dist/work-items/create-work-item.js.map +1 -0
  177. package/dist/work-items/decision-actions.d.ts +42 -0
  178. package/dist/work-items/decision-actions.d.ts.map +1 -0
  179. package/dist/work-items/decision-actions.js +70 -0
  180. package/dist/work-items/decision-actions.js.map +1 -0
  181. package/dist/workspace.d.ts.map +1 -1
  182. package/dist/workspace.js +3 -1
  183. package/dist/workspace.js.map +1 -1
  184. package/factory-skills/factory-gitlab-rereview/SKILL.md +1 -1
  185. package/factory-skills/factory-gitlab-review/SKILL.md +1 -1
  186. package/factory-skills/factory-plan/SKILL.md +4 -4
  187. package/factory-skills/factory-rereview/SKILL.md +3 -1
  188. package/factory-skills/factory-review/SKILL.md +3 -1
  189. package/factory-skills/factory-self-review/SKILL.md +46 -0
  190. package/package.json +13 -11
package/dist/factory.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { timedPhase } from "./timing.js";
2
- import { buildAuthDisabledRoutes, buildAuthRoutes, createFactoryAuthGate, createFactoryRouteAuth, factoryUserOrgId, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
2
+ import { buildAuthDisabledRoutes, buildAuthRoutes, createFactoryAuthGate, createFactoryInteractiveMarker, createFactoryRouteAuth, factoryUserOrgId, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
3
3
  import { assertFactoryConfigVersion } from "./rules/validation.js";
4
- import { isTerminalWorkItem } from "./boards/semantics.js";
4
+ import { boardForWorkItem, isTerminalWorkItem } from "./boards/semantics.js";
5
5
  import { createBoardRegistry } from "./boards/registry.js";
6
6
  import "./boards/index.js";
7
7
  import { isValidGitRef } from "./sandbox/git-ref.js";
@@ -31,22 +31,29 @@ import { PlatformIncidentioIntegration } from "./integrations/platform/incidenti
31
31
  import { PlatformJiraIntegration } from "./integrations/platform/jira/integration.js";
32
32
  import { PlatformLinearIntegration } from "./integrations/platform/linear/integration.js";
33
33
  import { FactoryProjectsStorage } from "./storage/domains/projects/base.js";
34
+ import { SourceControlStorage } from "./storage/domains/source-control/base.js";
35
+ import { createSourceControlSessionLookup } from "./session/factory-session.js";
36
+ import { AuditStorage } from "./storage/domains/audit/base.js";
37
+ import { deliverFactorySessionNotification } from "./tools/deliver.js";
38
+ import { createSessionApprovalNotifier, createSessionRunEndReporter, createStageChangeNotifier, createWorkItemRunEndReporter } from "./tools/reports.js";
39
+ import { observeSessionRunEnd } from "./session/run-audit.js";
40
+ import { observeSessionRunReports } from "./tools/run-watch.js";
41
+ import { applyFactoryToolPermissions } from "./tools/permissions.js";
42
+ import { resolveFactoryToolScope } from "./tools/scope.js";
43
+ import { createFactoryTools } from "./tools/index.js";
44
+ import { buildFactoryMcpRoutes, resolveMcpAuthorizationServers } from "./mcp/routes.js";
34
45
  import { resolveFactoryCredentialTenant } from "./session/credential-policy.js";
35
46
  import { hydrateSessionMemorySettings, layerPersonalMemorySettings } from "./session/memory-settings-hydration.js";
36
47
  import { MemorySettingsStorage, factoryMemorySettingsUserId } from "./storage/domains/memory-settings/base.js";
37
48
  import { resolveDeploymentModelProviders } from "./routes/config.js";
38
49
  import { createCustomProvidersPrimer, registerCustomProvidersSource } from "./routes/custom-provider-source.js";
39
50
  import { ProjectRoutes } from "./routes/projects.js";
40
- import { SourceControlStorage } from "./storage/domains/source-control/base.js";
41
- import { createSourceControlSessionLookup } from "./session/factory-session.js";
42
51
  import { FactoryTransitionService } from "./rules/transition-service.js";
43
- import { AuditStorage } from "./storage/domains/audit/base.js";
44
52
  import { AuditDomain } from "./storage/domains/audit/domain.js";
45
53
  import { QueueHealthStorage } from "./storage/domains/queue-health/base.js";
46
54
  import { assembleFactoryApiRoutes, buildIntegrationContext } from "./routes/surface.js";
47
55
  import { TelemetryRoutes } from "./routes/telemetry.js";
48
56
  import { readFactorySessionScope, resolveFactorySessionAddress } from "./rules/binding-context.js";
49
- import { observeSessionRunEnd } from "./session/run-audit.js";
50
57
  import { FactoryFeedReader } from "./storage/domains/comments/feed-context.js";
51
58
  import { FactoryDecisionDispatcher } from "./rules/dispatcher.js";
52
59
  import { FactoryPhaseStateProcessor, reportMemorySettingsUnavailable } from "./rules/processor.js";
@@ -59,6 +66,7 @@ import { handleServerError } from "./server-error.js";
59
66
  import { hydrateSessionDefaultModel } from "./session/default-model-hydration.js";
60
67
  import { observeSessionFirstMessage } from "./session/first-message-capture.js";
61
68
  import { LiveSessions } from "./session/live-sessions.js";
69
+ import { FactoryReplyCredentialProcessor } from "./session/reply-credential-processor.js";
62
70
  import { createSourceControlTools } from "./session/source-control-tools.js";
63
71
  import { readFactoryThinkingLevel, resolveFactoryThinkingLevel } from "./session/thinking-default.js";
64
72
  import { observeSessionThreadTitle } from "./session/thread-title-mirror.js";
@@ -72,6 +80,7 @@ import { CustomProvidersStorage } from "./storage/domains/custom-providers/base.
72
80
  import { FilesystemStorage } from "./storage/domains/filesystem/base.js";
73
81
  import { IntegrationStorage } from "./storage/domains/integrations/base.js";
74
82
  import { ModelDefaultsStorage } from "./storage/domains/model-defaults/base.js";
83
+ import { FactorySessionsStateProcessor } from "./tools/sessions-state-processor.js";
75
84
  import { hasAuthInit, isUserProvider } from "@mastra/core/server";
76
85
  import { MastraAuthStudio } from "@mastra/auth-studio";
77
86
  import { prepareAgentControllerMount } from "@mastra/code-sdk";
@@ -199,6 +208,7 @@ var MastraFactory = class {
199
208
  #configVersion;
200
209
  #prepared;
201
210
  #dispatcher;
211
+ #startCoordinator;
202
212
  #factoryProcessor;
203
213
  /** Environment builds through the sandbox's `builds`; undefined when the sandbox has none. */
204
214
  #environmentBuilds;
@@ -243,6 +253,8 @@ var MastraFactory = class {
243
253
  const secretEncryption = this.#config.secretEncryption ?? createPlaintextFactorySecretEncryption();
244
254
  const deploymentModelProviders = resolveDeploymentModelProviders(this.#config.deploymentModelProviders);
245
255
  const routeAuth = createFactoryRouteAuth(auth);
256
+ const mcpConfig = this.#config.mcp;
257
+ const mcpAuthorizationServers = mcpConfig === false || mcpConfig?.enabled === false ? [] : resolveMcpAuthorizationServers(auth?.name, mcpConfig);
246
258
  const integrations = [...this.#config.integrations ?? []];
247
259
  const explicitGithub = integrations.some((integration) => integration.id === "github");
248
260
  let installedPlatformGithub = false;
@@ -349,7 +361,8 @@ var MastraFactory = class {
349
361
  });
350
362
  if (integration.versionControl && integrationSourceControl) integration.versionControl.initialize({ storage: integrationSourceControl });
351
363
  }
352
- const sourceControlSessions = createSourceControlSessionLookup([.../* @__PURE__ */ new Set(["github", ...integrations.filter((integration) => integration.versionControl).map(({ id }) => id)])].map((id) => sourceControlStorage.forIntegration(id)));
364
+ const sourceControlHandles = [.../* @__PURE__ */ new Set(["github", ...integrations.filter((integration) => integration.versionControl).map(({ id }) => id)])].map((id) => sourceControlStorage.forIntegration(id));
365
+ const sourceControlSessions = createSourceControlSessionLookup(sourceControlHandles);
353
366
  if (auth) registerTenantCredentialResolver(modelCredentialsStorage, deploymentModelProviders, (requestContext) => resolveFactoryCredentialTenant(requestContext, {
354
367
  projects: factoryProjectsStorage,
355
368
  sourceControl: sourceControlSessions,
@@ -407,6 +420,28 @@ var MastraFactory = class {
407
420
  },
408
421
  ...retireTerminalSessions ? { releaseSandboxes: retireTerminalSessions } : {}
409
422
  }) : void 0;
423
+ const factoryMessaging = async () => {
424
+ const controller = this.#prepared?.base.controller;
425
+ const notifications = await controller?.getMastra()?.getStorage()?.getStore("notifications");
426
+ return controller && notifications ? {
427
+ controller,
428
+ notifications
429
+ } : null;
430
+ };
431
+ const factoryReporting = async () => {
432
+ const messaging = await factoryMessaging();
433
+ if (!messaging) return null;
434
+ return {
435
+ notifications: messaging.notifications,
436
+ deliver: (target, notification, options) => deliverFactorySessionNotification({
437
+ controller: messaging.controller,
438
+ sessions: sourceControlSessions,
439
+ target,
440
+ notification,
441
+ ...options
442
+ })
443
+ };
444
+ };
410
445
  const onTerminalStage = terminalCleanup ? (args) => terminalCleanup({
411
446
  orgId: args.orgId,
412
447
  factoryProjectId: args.factoryProjectId,
@@ -426,9 +461,37 @@ var MastraFactory = class {
426
461
  id: factoryProjectId
427
462
  }))?.autoApprovePlans ?? false;
428
463
  },
464
+ selfReviewEnabled: async ({ orgId, factoryProjectId }) => {
465
+ await factoryProjectsStorage.ensureReady();
466
+ return (await factoryProjectsStorage.get({
467
+ orgId,
468
+ id: factoryProjectId
469
+ }))?.selfReviewEnabled ?? false;
470
+ },
429
471
  ...onTerminalStage ? { onTerminalStage } : {},
472
+ onTransitionCommitted: createStageChangeNotifier({
473
+ workItems: workItemsStorage,
474
+ reporting: factoryReporting
475
+ }),
430
476
  ...githubIntegration ? { onAccepted: (args) => reconcileGithubAcceptanceLabels(githubIntegration, sourceControlStorage.forIntegration(githubIntegration.id), args) } : {}
431
477
  }) : void 0;
478
+ const factoryToolDeps = {
479
+ workItems: workItemsStorage,
480
+ comments: workItemCommentsStorage,
481
+ feed: commentsDomain,
482
+ audit: auditStorage,
483
+ boards: this.#boards,
484
+ transitionService,
485
+ auditRecorder: auditDomain,
486
+ sessions: sourceControlSessions,
487
+ sessionModel: {
488
+ projects: factoryProjectsStorage,
489
+ modelDefaults: modelDefaultsStorage
490
+ },
491
+ intake: intakeStorage,
492
+ startCoordinator: () => this.#startCoordinator,
493
+ messaging: factoryMessaging
494
+ };
432
495
  this.#environmentBuilds = this.#sandbox?.builds ? new EnvironmentBuildRunner({
433
496
  sandbox: this.#sandbox,
434
497
  projects: factoryProjectsStorage,
@@ -622,9 +685,24 @@ var MastraFactory = class {
622
685
  ...this.#config.knowledge ? { knowledge: this.#config.knowledge } : {},
623
686
  inputProcessors: async ({ requestContext }) => {
624
687
  const environmentProcessor = new FactoryEnvironmentStateProcessor();
688
+ const sessionsProcessor = workItemsStorage && storage.isDomainReady("source-control") ? [new FactorySessionsStateProcessor({
689
+ authEnabled: routeAuth.enabled(),
690
+ sessions: sourceControlSessions,
691
+ projects: factoryProjectsStorage,
692
+ workItems: workItemsStorage,
693
+ boards: this.#boards,
694
+ isRunning: async (sessionId) => {
695
+ return (await this.#prepared?.base.controller.getSessionByResource(sessionId))?.stream.isActive() ?? false;
696
+ },
697
+ notifications: async () => (await factoryMessaging())?.notifications ?? null
698
+ })] : [];
625
699
  if (factoryProcessor) {
626
700
  await factoryProcessor.prepareMemorySettings(requestContext);
627
- return [environmentProcessor, factoryProcessor];
701
+ return [
702
+ environmentProcessor,
703
+ ...sessionsProcessor,
704
+ factoryProcessor
705
+ ];
628
706
  }
629
707
  try {
630
708
  await loadMemorySettings({
@@ -634,8 +712,9 @@ var MastraFactory = class {
634
712
  } catch (error) {
635
713
  reportMemorySettingsUnavailable(requestContext, error instanceof Error ? error.message : String(error));
636
714
  }
637
- return [environmentProcessor];
715
+ return [environmentProcessor, ...sessionsProcessor];
638
716
  },
717
+ outputProcessors: [new FactoryReplyCredentialProcessor()],
639
718
  ...vector ? { vector } : {},
640
719
  ...toolIntegrations.length > 0 || sourceControlToolProviders.length > 0 || workItemsStorage && transitionService ? { extraTools: async ({ requestContext }) => {
641
720
  const tools = {};
@@ -651,7 +730,55 @@ var MastraFactory = class {
651
730
  if (storage.isDomainReady("source-control")) mergeTools("source-control", await createSourceControlTools({
652
731
  requestContext,
653
732
  providers: sourceControlToolProviders,
654
- audit: auditDomain
733
+ audit: auditDomain,
734
+ testChecksEnabled: async ({ orgId, factoryProjectId }) => {
735
+ await factoryProjectsStorage.ensureReady();
736
+ return (await factoryProjectsStorage.get({
737
+ orgId,
738
+ id: factoryProjectId
739
+ }))?.reviewTestChecksEnabled ?? false;
740
+ },
741
+ ...workItemsStorage ? {
742
+ selfReviewApprovedHead: async () => {
743
+ const resolution = await resolveFactorySessionAddress({
744
+ requestContext,
745
+ storage: workItemsStorage
746
+ });
747
+ if (!resolution) return void 0;
748
+ const binding = resolution.binding ?? await workItemsStorage.findActiveRunBinding(resolution.address);
749
+ if (!binding) return void 0;
750
+ const item = await workItemsStorage.get({
751
+ orgId: binding.orgId,
752
+ id: binding.workItemId
753
+ });
754
+ if (!item || boardForWorkItem(item) !== "work") return void 0;
755
+ if (typeof item.metadata?.openPullRequestNumber === "number") return void 0;
756
+ if (item.metadata?.selfReviewVerdict === void 0) {
757
+ await factoryProjectsStorage.ensureReady();
758
+ if (!(await factoryProjectsStorage.get({
759
+ orgId: binding.orgId,
760
+ id: binding.factoryProjectId
761
+ }))?.selfReviewEnabled) return void 0;
762
+ }
763
+ const sha = item.metadata?.selfReviewedHeadSha;
764
+ return item.metadata?.selfReviewVerdict === "approve" && typeof sha === "string" ? sha : null;
765
+ },
766
+ boundChangeRequestId: async () => {
767
+ const resolution = await resolveFactorySessionAddress({
768
+ requestContext,
769
+ storage: workItemsStorage
770
+ });
771
+ if (!resolution) return void 0;
772
+ const binding = resolution.binding ?? await workItemsStorage.findActiveRunBinding(resolution.address);
773
+ if (binding?.role !== "review") return void 0;
774
+ const source = (await workItemsStorage.get({
775
+ orgId: binding.orgId,
776
+ id: binding.workItemId
777
+ }))?.externalSource;
778
+ if (!source || !/pull-request|merge-request/.test(source.type)) return void 0;
779
+ return /(\d+)$/.exec(source.externalId)?.[1];
780
+ }
781
+ } : {}
655
782
  }));
656
783
  if (workItemsStorage && transitionService) {
657
784
  mergeTools("factory", await createFactoryTransitionTools({
@@ -668,6 +795,19 @@ var MastraFactory = class {
668
795
  uiOrigin: reviewSourceUiOrigin,
669
796
  ...storage.isDomainReady("source-control") ? { sessions: sourceControlSessions } : {}
670
797
  }));
798
+ if (storage.isDomainReady("source-control")) {
799
+ const scope = await resolveFactoryToolScope({
800
+ requestContext,
801
+ authEnabled: routeAuth.enabled(),
802
+ sessions: sourceControlSessions,
803
+ projects: factoryProjectsStorage,
804
+ workItems: workItemsStorage
805
+ });
806
+ if (scope) mergeTools("factory-tools", createFactoryTools({
807
+ scope,
808
+ deps: factoryToolDeps
809
+ }));
810
+ }
671
811
  }
672
812
  for (const { integration, ready, ensureReady } of toolIntegrations) {
673
813
  if (!ready && ensureReady) try {
@@ -718,6 +858,14 @@ var MastraFactory = class {
718
858
  } : {},
719
859
  buildApiRoutes: ({ controller, authStorage }) => [
720
860
  ...auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : buildAuthDisabledRoutes(),
861
+ ...auth && mcpAuthorizationServers.length > 0 ? buildFactoryMcpRoutes({
862
+ auth: routeAuth,
863
+ publicOrigin,
864
+ authorizationServers: mcpAuthorizationServers,
865
+ projects: factoryProjectsStorage,
866
+ sourceControls: sourceControlHandles,
867
+ tools: factoryToolDeps
868
+ }) : [],
721
869
  ...new TelemetryRoutes({
722
870
  auth: routeAuth,
723
871
  providerName: auth?.name,
@@ -751,7 +899,8 @@ var MastraFactory = class {
751
899
  configVersion,
752
900
  boardRegistry: this.#boards,
753
901
  factoryTransitionService: transitionService,
754
- onFactoryRuntime: ({ transitionService: runtimeTransitionService, prepareBinding }) => {
902
+ onFactoryRuntime: ({ transitionService: runtimeTransitionService, startCoordinator, prepareBinding }) => {
903
+ this.#startCoordinator = startCoordinator;
755
904
  this.#dispatcher ??= new FactoryDecisionDispatcher({
756
905
  controller,
757
906
  transitionService: runtimeTransitionService,
@@ -787,6 +936,10 @@ var MastraFactory = class {
787
936
  tenant,
788
937
  credentials: modelCredentialsStorage
789
938
  }),
939
+ reportRunEnd: createWorkItemRunEndReporter({
940
+ workItems: storage.getDomain("work-items"),
941
+ reporting: factoryReporting
942
+ }),
790
943
  resolveLinkedWorkItemParentId: async ({ orgId, factoryProjectId, decision }) => {
791
944
  if (decision.source !== "github-pr") return null;
792
945
  const repositoryId = decision.metadata?.githubRepositoryId;
@@ -819,11 +972,15 @@ var MastraFactory = class {
819
972
  const uiDist = resolveUiDistDir();
820
973
  const spa = uiDist ? [createSpaStaticMiddleware(uiDist)] : [];
821
974
  if (!auth) return {
822
- middleware: [createCustomProvidersPrimer({
823
- auth: routeAuth,
824
- storage: customProvidersStorage,
825
- authEnabled: false
826
- }), ...spa],
975
+ middleware: [
976
+ createFactoryInteractiveMarker(),
977
+ createCustomProvidersPrimer({
978
+ auth: routeAuth,
979
+ storage: customProvidersStorage,
980
+ authEnabled: false
981
+ }),
982
+ ...spa
983
+ ],
827
984
  ...cors,
828
985
  ...onError
829
986
  };
@@ -847,6 +1004,13 @@ var MastraFactory = class {
847
1004
  };
848
1005
  }
849
1006
  }));
1007
+ const sessionReports = {
1008
+ sessions: sourceControlSessions,
1009
+ workItems: storage.getDomain("work-items"),
1010
+ reporting: factoryReporting
1011
+ };
1012
+ const reportSessionRunEnd = createSessionRunEndReporter(sessionReports);
1013
+ const notifyApprovalRequested = createSessionApprovalNotifier(sessionReports);
850
1014
  prepared.base.controller.onSessionCreated((session) => {
851
1015
  observeSessionFilesystem(session, {
852
1016
  filesystem: filesystemStorage,
@@ -856,6 +1020,16 @@ var MastraFactory = class {
856
1020
  observeSessionFirstExec(session, { sourceControl: { sessions: sourceControlSessions } });
857
1021
  observeSessionThreadTitle(session, { sourceControl: { sessions: sourceControlSessions } });
858
1022
  observeSessionRunEnd(session, { audit: auditDomain });
1023
+ observeSessionRunReports(session, (outcome, since) => reportSessionRunEnd({
1024
+ sessionId: session.identity.getResourceId(),
1025
+ threadId: session.thread.getId(),
1026
+ outcome,
1027
+ since
1028
+ }), { onApprovalRequested: (request) => notifyApprovalRequested({
1029
+ sessionId: session.identity.getResourceId(),
1030
+ threadId: session.thread.getId(),
1031
+ ...request
1032
+ }) });
859
1033
  });
860
1034
  prepared.base.controller.onSessionCreated((session) => hydrateSessionMemorySettings(session, { sourceControl: { sessions: sourceControlSessions } }), { blocking: true });
861
1035
  prepared.base.controller.onSessionCreated((session) => hydrateSessionDefaultModel(session, {
@@ -864,6 +1038,7 @@ var MastraFactory = class {
864
1038
  workItems: workItemsStorage,
865
1039
  modelDefaults: modelDefaultsStorage
866
1040
  }), { blocking: true });
1041
+ prepared.base.controller.onSessionCreated((session) => applyFactoryToolPermissions(session, { sessions: sourceControlSessions }), { blocking: true });
867
1042
  this.#prepared = prepared;
868
1043
  this.#factoryProcessor = factoryProcessor;
869
1044
  const channelRegistrations = integrationRegistrations.filter(({ integration, ready }) => ready && integration.channels);