@mastra/factory 0.25.0-alpha.7 → 0.25.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","names":[],"sources":["../src/factory.ts"],"sourcesContent":["/**\n * `MastraFactory` — the single entry point to the whole Mastra Software Factory.\n *\n * The consumer's deploy entry constructs deployment-specific config instances\n * (auth adapter, pubsub) and passes them here explicitly. The only provider\n * defaults constructed here are Platform GitHub, GitLab, Jira, incident.io, and\n * Linear integrations when Platform credentials exist and the caller did not\n * provide those integrations.\n *\n * `prepare()` resolves feature readiness, threads every dependency explicitly,\n * assembles the web routes/middleware, and returns the constructor args for\n * `new Mastra(...)`. The literal `export const mastra = new Mastra(...)` must\n * stay in the entry file — the deployer's `checkConfigExport` Babel plugin\n * only marks the config valid when it finds that literal in the entry AST —\n * so the factory produces args instead of the instance. `finalize()` runs the\n * post-construct boot (controller init + workers).\n *\n * Integration readiness is derived from each instance's declared capabilities\n * and the storage domains those capabilities require.\n */\n\nimport { MastraAuthStudio } from '@mastra/auth-studio';\nimport { prepareAgentControllerMount } from '@mastra/code-sdk';\nimport { getDynamicMemory } from '@mastra/code-sdk/agents/memory';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentControllerRequestContext, BuiltinToolId } from '@mastra/core/agent-controller';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport { AgentControllerChannels } from '@mastra/core/channels';\nimport { EventEmitterPubSub } from '@mastra/core/events';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Knowledge } from '@mastra/core/knowledge';\nimport type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { hasAuthInit, isUserProvider } from '@mastra/core/server';\nimport type { IMastraAuthProvider } from '@mastra/core/server';\nimport type { FactoryStorage } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { describeFactorySandbox, isFactorySandbox } from '@mastra/core/workspace';\nimport type { FactorySandbox, FactorySandboxDescription, WorkspaceSandbox } from '@mastra/core/workspace';\nimport {\n buildAuthDisabledRoutes,\n buildAuthRoutes,\n createFactoryAuthGate,\n createFactoryInteractiveMarker,\n createFactoryRouteAuth,\n getFactoryAuthOrgId,\n getFactoryAuthUserFromContext,\n getFactoryAuthUserId,\n} from './auth.js';\nimport { createBoardRegistry, isTerminalWorkItem } from './boards/index.js';\nimport type { BoardRegistry, InstalledBoard } from './boards/index.js';\nimport { boardForWorkItem } from './boards/semantics.js';\nimport { EnvironmentBuildRunner } from './environment/build-runner.js';\nimport { ENVIRONMENT_BUILD_WORKFLOW_ID } from './environment/build-workflow.js';\nimport { touchFeed } from './feed-events.js';\nimport type { FactoryIntegration, IntegrationPostToolContext, IntegrationTools } from './integrations/base.js';\nimport { reconcileGithubAcceptanceLabels } from './integrations/github/acceptance-labels.js';\nimport type { GithubRuleOverrides } from './integrations/github/default-rules.js';\nimport type { GithubIntegration } from './integrations/github/integration.js';\nimport {\n recordFactoryPullRequestProvenance,\n resolveFactoryPullRequestParentWorkItemId,\n} from './integrations/github/provenance.js';\nimport type { FactoryPullRequestProvenanceData } from './integrations/github/provenance.js';\nimport { isFactoryGithubLogin, trustedCollaborator } from './integrations/github/rules.js';\nimport { dismissStaleFactoryReviews } from './integrations/github/stale-reviews.js';\nimport type { GitLabIntegrationBase } from './integrations/gitlab/integration.js';\nimport { PlatformApiClient, platformApiClientConfigFromEnv } from './integrations/platform/api-client.js';\nimport { buildPlatformConnectRoutes } from './integrations/platform/connect/routes.js';\nimport { createSessionAsRowOwner, prepareSessionRunContext } from './integrations/subscription-session.js';\nimport { buildFactoryMcpRoutes, resolveMcpAuthorizationServers } from './mcp/routes.js';\nimport type { FactoryMcpConfig } from './mcp/routes.js';\nimport { resolveDeploymentModelProviders } from './routes/config.js';\nimport {\n createCustomProvidersPrimer,\n primeCustomProvidersForRequestContext,\n registerCustomProvidersSource,\n} from './routes/custom-provider-source.js';\nimport { ProjectRoutes } from './routes/projects.js';\nimport { tenantOrgId } from './routes/provider-credentials.js';\nimport { createSessionAccessGuard } from './routes/session-access.js';\nimport { assembleFactoryApiRoutes, buildIntegrationContext } from './routes/surface.js';\nimport type { FactoryApiRoutesDeps } from './routes/surface.js';\nimport { TelemetryRoutes } from './routes/telemetry.js';\nimport {\n createTenantCredentialPrimer,\n primeTenantCredentials,\n registerTenantCredentialResolver,\n} from './routes/tenant-credentials.js';\nimport { readFactorySessionScope, resolveFactorySessionAddress } from './rules/binding-context.js';\nimport { FactoryDecisionDispatcher } from './rules/dispatcher.js';\nimport type { FactoryRuleActor } from './rules/index.js';\nimport { FactoryPhaseStateProcessor, reportMemorySettingsUnavailable } from './rules/processor.js';\nimport { createReviewSourceTool, resolveReviewSourceUiOrigin } from './rules/review-source-tool.js';\nimport type { FactoryStartCoordinator } from './rules/start-coordinator.js';\nimport { createTerminalStageCleanup } from './rules/terminal-cleanup.js';\nimport { createFactoryTransitionTools } from './rules/tools.js';\nimport { FactoryTransitionService } from './rules/transition-service.js';\nimport { assertFactoryConfigVersion, DEFAULT_FACTORY_CONFIG_VERSION } from './rules/validation.js';\nimport { CallbackFactorySandbox } from './sandbox/callback-factory-sandbox.js';\nimport { isValidGitRef } from './sandbox/git-ref.js';\nimport { LocalFactorySandbox } from './sandbox/local-factory-sandbox.js';\nimport { SessionRetirementCoordinator } from './sandbox/session-retirement.js';\nimport type { MastraFactorySandboxOption } from './sandbox/session-sandbox.js';\nimport { createPlaintextFactorySecretEncryption } from './secret-encryption.js';\nimport type { FactorySecretEncryption } from './secret-encryption.js';\nimport { handleServerError } from './server-error.js';\nimport { resolveFactoryCredentialTenant, resolveFactoryModelPolicy } from './session/credential-policy.js';\nimport { hydrateSessionDefaultModel } from './session/default-model-hydration.js';\nimport { environmentSlugs, resolveSessionRepositories } from './session/environment-repositories.js';\nimport { FactoryEnvironmentStateProcessor } from './session/environment-state-processor.js';\nimport { createSourceControlSessionLookup } from './session/factory-session.js';\nimport { observeSessionFilesystem } from './session/filesystem-capture.js';\nimport { observeSessionFirstExec } from './session/first-exec-capture.js';\nimport { observeSessionFirstMessage } from './session/first-message-capture.js';\nimport { LiveSessions } from './session/live-sessions.js';\nimport { hydrateSessionMemorySettings } from './session/memory-settings-hydration.js';\nimport { hasResolvedOrg } from './session/org-seed.js';\nimport { FactoryReplyCredentialProcessor } from './session/reply-credential-processor.js';\nimport { migrateSessionResources, privatizeOwnerResourceSessions } from './session/resource-migration.js';\nimport { observeSessionRunEnd } from './session/run-audit.js';\nimport { sessionMemoryResourceId, sessionStampCounts } from './session/session-threads.js';\nimport { createSourceControlTools } from './session/source-control-tools.js';\nimport { resolveFactoryThinkingLevel } from './session/thinking-default.js';\nimport { observeSessionThreadStamp } from './session/thread-session-stamp.js';\nimport { observeSessionThreadTitle } from './session/thread-title-mirror.js';\nimport { createSpaStaticMiddleware, resolveUiDistDir } from './spa-static.js';\nimport { createStateSigner } from './state-signing.js';\nimport { observeAgentGitAction } from './storage/domains/audit/agent-audit.js';\nimport { AuditStorage } from './storage/domains/audit/base.js';\nimport { AuditDomain } from './storage/domains/audit/domain.js';\nimport { ChannelIdentityStorage } from './storage/domains/channel-identity/base.js';\nimport { WorkItemCommentsStorage } from './storage/domains/comments/base.js';\nimport { CommentsDomain } from './storage/domains/comments/domain.js';\nimport { FactoryFeedReader } from './storage/domains/comments/feed-context.js';\nimport type { WorkItemFeedPublisher } from './storage/domains/comments/feed-sync.js';\nimport { ModelCredentialsStorage } from './storage/domains/credentials/base.js';\nimport { CustomProvidersStorage } from './storage/domains/custom-providers/base.js';\nimport { FilesystemStorage } from './storage/domains/filesystem/base.js';\nimport { IntakeStorage } from './storage/domains/intake/base.js';\nimport { IntegrationStorage } from './storage/domains/integrations/base.js';\nimport { factoryMemorySettingsUserId, MemorySettingsStorage } from './storage/domains/memory-settings/base.js';\nimport { ModelDefaultsStorage } from './storage/domains/model-defaults/base.js';\nimport { FactoryProjectsStorage } from './storage/domains/projects/base.js';\nimport { QueueHealthStorage } from './storage/domains/queue-health/base.js';\nimport { SourceControlStorage } from './storage/domains/source-control/base.js';\nimport { WorkItemsStorage } from './storage/domains/work-items/base.js';\nimport type { FactoryRunBindingRecord, WorkItemRow } from './storage/domains/work-items/base.js';\nimport { createRequestTimingMiddleware, factoryTimingEnabled, instrumentAsyncMethods, timedPhase } from './timing.js';\nimport { deliverFactorySessionNotification } from './tools/deliver.js';\nimport { applyFactoryToolPermissions, createFactoryTools, resolveFactoryToolScope } from './tools/index.js';\nimport type { FactoryToolDependencies } from './tools/index.js';\nimport {\n createSessionApprovalNotifier,\n createSessionRunEndReporter,\n createStageChangeNotifier,\n createWorkItemRunEndReporter,\n} from './tools/reports.js';\nimport type { FactoryReporting } from './tools/reports.js';\nimport { observeSessionRunReports } from './tools/run-watch.js';\nimport { createFactorySandboxTools } from './tools/sandbox-tools.js';\nimport { FactorySessionsStateProcessor } from './tools/sessions-state-processor.js';\nimport { createWorkspaceFactory, FactoryWorkspaceRegistry } from './workspace.js';\nimport type { FactorySandboxStart } from './workspace.js';\n\ntype BuildApiRoutesDeps = Pick<FactoryApiRoutesDeps, 'controller' | 'authStorage'>;\n\n/** Constructor args for the `new Mastra(...)` literal in the deploy entry. */\nexport type MastraArgs = NonNullable<ConstructorParameters<typeof Mastra>[0]>;\n\nexport interface MastraFactoryConfig {\n /**\n * Auth provider instance — `MastraAuthStudio` (`@mastra/auth-studio`),\n * `MastraAuthWorkos` (`@mastra/auth-workos`), `MastraAuthBetterAuth`\n * (`@mastra/auth-better-auth`), or any custom `MastraAuthProvider`. Whatever\n * instance is passed is the active provider; a passed instance is always\n * honored as-is.\n *\n * Omitted → the factory defaults to `MastraAuthStudio`, proxying auth\n * through the shared Mastra platform API. `MastraAuthStudio` resolves its\n * own env (`MASTRA_SHARED_API_URL`, `MASTRA_ORGANIZATION_ID`,\n * `MASTRA_COOKIE_DOMAIN`).\n *\n * Pass `null` to disable auth entirely (open server, local-dev behavior)\n * without falling back to the default.\n */\n auth?: IMastraAuthProvider | null;\n /**\n * REQUIRED. Factory storage backend powering BOTH agent storage (threads,\n * messages, memory, OM — via `getMastraStorage()`) and the app tables\n * (projects/source-control/audit/intake — via the generic ops surface). Pass a\n * `PgFactoryStorage` (`@mastra/pg`) for deployments or a\n * `LibSQLFactoryStorage` (`@mastra/libsql`) for local dev — one backend,\n * one connection, every feature on.\n */\n storage: FactoryStorage;\n /**\n * Vector store instance for recall search — `PgVector` (`@mastra/pg`) on\n * the same database as `storage`. Omitted → the SDK mount's default vector\n * store resolution applies.\n */\n vector?: MastraVector;\n /**\n * Host-owned Knowledge runtime. Factory registers this exact instance under `key` and uses that\n * key for its read surfaces. Omitted leaves Mastra Code's experimental default wiring in place.\n */\n knowledge?: { key: string; instance: Knowledge };\n /**\n * Distributed event bus instance (e.g. `new RedisStreamsPubSub({ url })`).\n * When set, streams/workflows/signals ride it across processes and the\n * controller drops file-based thread locks in favor of pubsub-coordinated\n * leases. Omitted → in-process default.\n */\n pubsub?: PubSub;\n /**\n * Browser-facing origin used to build integration OAuth/install callback\n * URLs and to derive the auth redirect URI. On the platform the SPA is\n * hosted separately, so this MUST be the public API origin.\n * Default: `http://localhost:4111` (the local Factory server, which also\n * serves the UI).\n */\n publicUrl?: string;\n /**\n * The Factory MCP server at `/web/factory/projects/:projectId/mcp`, which lets\n * MCP clients such as ChatGPT use the Factory tools as the signed-in user.\n * On by default with Mastra Platform auth; other providers need\n * `authorizationServers` set. Pass `false` to turn it off.\n */\n mcp?: false | FactoryMcpConfig;\n /**\n * Allowed cross-origin SPA origins. The SPA may be served from a separate\n * static host, so credentialed requests must be explicitly allowed.\n */\n allowedOrigins?: string[];\n /**\n * The host's sandbox: a FactorySandbox instance such as\n * `new PlatformFactorySandbox({ ... })`, which owns the session sandbox\n * constructor, the repo template and the schema of environment settings.\n * A bare callback is also accepted and wrapped as a `provider: 'custom'`\n * sandbox with no settings. Omitted with Platform credentials → the factory\n * installs a `LocalFactorySandbox` under `mastra dev` and a\n * `PlatformFactorySandbox` in built deployments. Omitted without Platform\n * credentials → repository sandboxes are disabled.\n */\n sandbox?: MastraFactorySandboxOption;\n /** Browser automation provider for Factory agent sessions. */\n browser?: MastraBrowser;\n /**\n * When a session's sandbox boots: on the agent's first command (`'lazy'`,\n * the default) or as soon as the session's workspace is first resolved\n * (`'eager'`), so the boot overlaps the model's own latency.\n */\n sandboxStart?: FactorySandboxStart;\n /**\n * Agent controller built-in tools (e.g. `submit_plan`) removed from every\n * Factory session, along with their prompt guidance. Use this when a custom\n * board gates planning with its own phase transition, so the in-session plan\n * approval cannot bypass that gate.\n */\n disableBuiltinTools?: BuiltinToolId[];\n /** Background Factory dispatcher configuration. */\n dispatcher?: MastraFactoryDispatcherConfig;\n /**\n * Deployment-stable secret for signing integration OAuth `state` values.\n * Omitted → a per-process random secret, which is fine for single-process\n * local development but rejected for integrations that declare\n * `requiresStableStateSigner`.\n */\n stateSecret?: string;\n /**\n * Encryption boundary for persisted model credentials, custom-provider API\n * keys, integration connections, and integration settings. Strongly\n * recommended whenever auth is enabled — omitting it falls back to explicit\n * plaintext compatibility with a boot-time warning.\n */\n secretEncryption?: FactorySecretEncryption;\n /**\n * Model providers that authenticate with the server process's own\n * credentials instead of per-account credentials. With auth enabled, these\n * providers are only usable when listed here; the stored-key flow is never\n * offered for them. Supported: `'amazon-bedrock'` (AWS credential chain —\n * `AWS_BEARER_TOKEN_BEDROCK` or access keys/profile/role plus `AWS_REGION`).\n * Every signed-in account can then run these models on the deployment's\n * credentials. Default: none.\n */\n deploymentModelProviders?: readonly string[];\n /**\n * Registered capability providers. The factory registers the pieces each\n * `FactoryIntegration` instance provides — HTTP routes, storage domains,\n * agent/session tools, intake, source control, and diagnostics — into the\n * system. When Platform credentials are configured, missing `github`,\n * `gitlab`, and `linear` integrations default to their Platform-backed\n * implementations. Missing `jira` and `incidentio` integrations also default\n * to their Platform-backed implementations, which discover visible `jira` and\n * `incident-io` connections at runtime.\n */\n integrations?: FactoryIntegration[];\n /**\n * Operator-maintained provenance label stamped on transition audit rows,\n * deferred decisions, and session kickoff headers so a row can be traced\n * back to the deployment that produced it. Nothing branches on it.\n * Default: `factory-config-v1`.\n */\n configVersion?: string;\n /** Board definitions installed for this Factory instance. */\n boards?: readonly InstalledBoard[];\n /** Whether the built-in Work and Review boards are installed. Default: true. */\n includeDefaultBoards?: boolean;\n\n /**\n * Platform-specific overrides.\n */\n platform?: {\n /** Identifies Factory's own GitHub App writes so their webhook deliveries do not retrigger triage. */\n githubAppSlug?: string;\n /**\n * Overrides for the `PlatformGithubIntegration` the factory installs itself\n * when Platform credentials are present; these options are forwarded to its\n * constructor. An explicit integration with id `github` in `integrations`\n * takes precedence and makes this key a no-op, so the two are not meant to\n * be used together.\n */\n github?: {\n /** Replace an event handler, or disable it with null; omitted events keep defaults. */\n rules?: GithubRuleOverrides;\n /**\n * GitHub App slug used to recognize Factory's own webhook writes. Falls\n * back to `githubAppSlug` when omitted.\n */\n slug?: string;\n };\n };\n}\n\nexport type { MastraFactorySandboxConfig, MastraFactorySandboxOption } from './sandbox/session-sandbox.js';\nexport type { FactorySandboxStart } from './workspace.js';\n\n/**\n * Per-process cap on concurrent background Factory dispatches. Omitted means\n * the dispatcher default; this is a local replica budget, not a global queue\n * limit shared across deployments.\n */\nexport interface MastraFactoryDispatcherConfig {\n maxInFlight?: number;\n}\n\nconst CONTROLLER_ID = 'code';\n\n/**\n * Providers whose sandbox a session's agent may recreate itself. Each needs\n * its `destroy()` to leave the instance able to start a fresh VM, proven\n * against the real provider.\n */\nconst SELF_RECREATE_SANDBOX_PROVIDERS: ReadonlySet<string> = new Set(['platform']);\n\n/** Why a wake couldn't be run as its Factory session's owner. */\nconst WAKE_OWNER_UNRESOLVED = {\n 'session-not-found': 'no Factory session row names its owner',\n 'organization-unresolved': \"its owner's organization is unresolved\",\n 'organization-mismatch': \"its owner's organization doesn't match\",\n} as const;\n\nfunction hasPlatformCredentials(): boolean {\n // MASTRA_PLATFORM_ACCESS_TOKEN is the credential Mastra Platform injects\n // into deployed projects; MASTRA_PLATFORM_SECRET_KEY is the org secret key\n // written by project scaffolding. Either enables the platform integrations.\n return Boolean(process.env.MASTRA_PLATFORM_ACCESS_TOKEN?.trim() || process.env.MASTRA_PLATFORM_SECRET_KEY?.trim());\n}\n\n/**\n * The sandbox the factory installs when the host passes none and Platform\n * credentials are present: a local sandbox under `mastra dev` (or\n * NODE_ENV=development), so development never boots remote machines, and\n * a Platform sandbox in built deployments. Without credentials, sandboxes\n * stay disabled.\n */\nasync function platformDefaultSandbox(): Promise<FactorySandbox | undefined> {\n if (!hasPlatformCredentials()) return undefined;\n if (process.env.MASTRA_DEV === 'true' || process.env.NODE_ENV === 'development') {\n return new LocalFactorySandbox();\n }\n const missing = ['MASTRA_PROJECT_ID', 'MASTRA_ENVIRONMENT_ID'].filter(key => !process.env[key]?.trim());\n if (missing.length > 0) {\n console.warn(\n `MastraFactory: Platform credentials are set but ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} missing, so no Platform sandbox was installed and repository sandboxes are disabled.`,\n );\n return undefined;\n }\n const { PlatformFactorySandbox } = await import('@mastra/platform-workspace');\n return new PlatformFactorySandbox();\n}\n\n/**\n * Default auth provider — `MastraAuthStudio`, which proxies identity to the\n * shared Mastra platform API and resolves its own env (`MASTRA_SHARED_API_URL`,\n * `MASTRA_ORGANIZATION_ID`, ...).\n *\n * The session cookie is **host-only** (`__Host-wos-session` on secure\n * deployments). No parent `Domain` (e.g. `.mastra.cloud`) is derived from\n * `publicUrl`: a parent-scoped session cookie is sent by the browser to every\n * host under that parent, including other tenants' deployments. Callers that\n * really want a domain-scoped cookie pass their own `MastraAuthStudio` (with\n * `cookieDomain`) via `auth:`.\n */\nfunction buildDefaultStudioAuth(): IMastraAuthProvider {\n return new MastraAuthStudio();\n}\n\n/** A session parking or being answered is inbox news, so the registry bumps the project's feed. */\nfunction liveSessionsTouchingTheFeed(controller: BuildApiRoutesDeps['controller'], eventBus: PubSub): LiveSessions {\n const liveSessions = new LiveSessions(controller);\n liveSessions.onParkedChanged(session => {\n const { factoryOrgId, factoryProjectId } = session.state.get();\n if (factoryOrgId && factoryProjectId) touchFeed(eventBus, { orgId: factoryOrgId, factoryProjectId });\n });\n return liveSessions;\n}\n\n/**\n * The fleet-era `sandbox` options and what replaced each one. Only the keys\n * the host actually passed are explained, so a host that never used the fleet\n * gets the short message.\n */\nconst RETIRED_SANDBOX_OPTIONS: Record<string, string> = {\n machine:\n \"'machine' becomes the provider instance: one sandbox per session, constructed by the FactorySandbox, instead of one template machine cloned per repository\",\n workdir:\n \"'workdir' becomes the workingDirectory of the FactorySandboxContext, which every provider passes to its sandbox; when it is absent the provider uses its own default\",\n maxSandboxes: \"'maxSandboxes' is gone with the sandbox fleet: there is one sandbox per session and no pool to cap\",\n};\n\nfunction invalidSandboxOptionMessage(option: unknown): string {\n const lines = [\n `MastraFactory: 'sandbox' must be a FactorySandbox instance or a callback constructing a MastraSandbox from a FactorySandboxContext:`,\n ` sandbox: new PlatformFactorySandbox()`,\n ` sandbox: ctx => new PlatformSandbox({ id: ctx.sessionId, sandboxId: ctx.sandboxId })`,\n ];\n if (typeof option === 'object' && option !== null) {\n const retired = Object.keys(RETIRED_SANDBOX_OPTIONS).filter(key => key in option);\n if (retired.length > 0) {\n lines.push(`The object you passed is the retired alpha sandbox config. Its options map as follows:`);\n for (const key of retired) lines.push(` ${RETIRED_SANDBOX_OPTIONS[key]}.`);\n }\n }\n return lines.join('\\n');\n}\n\nexport class MastraFactory {\n readonly #config: MastraFactoryConfig;\n /** The normalized sandbox, set by `prepare()`. Undefined until then and when sandboxes are disabled. */\n #sandbox: FactorySandbox | undefined;\n #sandboxDescription: FactorySandboxDescription | undefined;\n readonly #boards: BoardRegistry;\n readonly #configVersion: string;\n #prepared: Awaited<ReturnType<typeof prepareAgentControllerMount>> | undefined;\n #dispatcher: FactoryDecisionDispatcher | undefined;\n #startCoordinator: FactoryStartCoordinator | undefined;\n #factoryProcessor: FactoryPhaseStateProcessor | undefined;\n /** Environment builds through the sandbox's `builds`; undefined when the sandbox has none. */\n #environmentBuilds: EnvironmentBuildRunner | undefined;\n /** The background session resource migration; resolves `true` when it moved run bindings. */\n #sessionResourceMigration: Promise<boolean> | undefined;\n #preparing = false;\n\n constructor(config: MastraFactoryConfig) {\n if (!config?.storage) {\n throw new Error(\n \"MastraFactory: 'storage' is required. Pass a FactoryStorage backend — e.g. \" +\n \"new PgFactoryStorage({ connectionString }) from '@mastra/pg' for deployments, or \" +\n \"new LibSQLFactoryStorage({ url }) from '@mastra/libsql' for local dev.\",\n );\n }\n this.#boards = createBoardRegistry({\n boards: config.boards,\n includeDefaultBoards: config.includeDefaultBoards,\n });\n if ('rules' in config) {\n throw new Error(\n \"MastraFactory: 'rules' was removed. Set 'configVersion' for the audit label and declare tool-result \" +\n 'rules on the owning board via defineBoard({ tools }).',\n );\n }\n this.#configVersion = assertFactoryConfigVersion(config.configVersion ?? DEFAULT_FACTORY_CONFIG_VERSION);\n this.#config = config;\n }\n\n /**\n * The host sandbox's provider, settings schema (JSON Schema) and\n * capabilities, as the environment route reports them. Undefined before\n * `prepare()` and when sandboxes are disabled.\n */\n get sandboxDescription(): FactorySandboxDescription | undefined {\n if (!this.#sandbox) return undefined;\n this.#sandboxDescription ??= describeFactorySandbox(this.#sandbox);\n return this.#sandboxDescription;\n }\n\n /**\n * Resolve feature readiness, wire every dependency explicitly, and assemble\n * everything needed to construct the server-owned Mastra. Returns the args\n * for the `new Mastra(...)` literal that must live in the entry file.\n */\n async prepare(): Promise<MastraArgs> {\n // Guard set synchronously (before the first await) so overlapping calls —\n // not just strictly sequential ones — can't double-seed the runtime\n // registry or double-run one-time adapter init.\n if (this.#preparing) throw new Error('MastraFactory.prepare() called twice');\n this.#preparing = true;\n\n const publicOrigin = (this.#config.publicUrl ?? 'http://localhost:4111').replace(/\\/+$/, '');\n const allowedOrigins = (this.#config.allowedOrigins ?? []).map(o => o.replace(/\\/+$/, '')).filter(Boolean);\n const storage = instrumentAsyncMethods(this.#config.storage, 'storage');\n const vector = this.#config.vector;\n const pubsub = this.#config.pubsub;\n // One bus for feed/attention events: a second fallback instance would leave\n // SSE subscribers and producers on different emitters in single-process runs.\n const eventBus = pubsub ?? new EventEmitterPubSub();\n // Default auth: honor an explicitly-passed provider (including `null` to\n // disable auth) as-is; otherwise fall back to `MastraAuthStudio`\n // (platform-proxied identity). The default derives its cookie domain\n // from `publicUrl` — deploys on `<sub>.mastra.cloud` mint parent-domain\n // cookies without the caller wiring `MASTRA_COOKIE_DOMAIN` explicitly.\n const configuredAuth = this.#config.auth;\n const auth: IMastraAuthProvider | undefined =\n configuredAuth === null ? undefined : (configuredAuth ?? buildDefaultStudioAuth());\n if (auth && !this.#config.secretEncryption) {\n console.warn(\n \"[factory] auth is enabled but 'secretEncryption' is not configured. Persisted model credentials, \" +\n 'custom-provider API keys, and integration secrets will be stored as plaintext. Provide ' +\n \"'secretEncryption' (e.g. via FACTORY_CREDENTIAL_ENCRYPTION_KEY) to encrypt them at rest.\",\n );\n }\n const secretEncryption = this.#config.secretEncryption ?? createPlaintextFactorySecretEncryption();\n const deploymentModelProviders = resolveDeploymentModelProviders(this.#config.deploymentModelProviders);\n // One RouteAuth seam per boot, closed over the resolved provider. Every\n // factory route module receives this handle — no service locator.\n const routeAuth = createFactoryRouteAuth(auth);\n const mcpConfig = this.#config.mcp;\n const mcpAuthorizationServers =\n mcpConfig === false || mcpConfig?.enabled === false ? [] : resolveMcpAuthorizationServers(auth?.name, mcpConfig);\n // The MCP endpoint authenticates callers itself, so it needs an auth\n // provider and somewhere for clients to get tokens.\n const mcpEnabled = Boolean(auth) && mcpAuthorizationServers.length > 0;\n\n // Explicit integrations win. Platform credentials fill only missing\n // provider slots so callers can override each integration independently.\n const integrations = [...(this.#config.integrations ?? [])];\n const explicitGithub = integrations.some(integration => integration.id === 'github');\n // Whether this boot constructed the GitHub integration on the caller's\n // behalf — `platform.github` is only meaningful in that case.\n let installedPlatformGithub = false;\n if (hasPlatformCredentials()) {\n if (!explicitGithub) {\n // Forward `platform.github` to the integration the factory installs\n // itself. `slug` falls back to the sibling `githubAppSlug` so existing\n // deploys keep working; the constructor validates and freezes `rules`,\n // so invalid ones fail boot.\n const { PlatformGithubIntegration } = await import('./integrations/platform/github/integration.js');\n integrations.push(\n new PlatformGithubIntegration({\n rules: this.#config.platform?.github?.rules,\n slug: this.#config.platform?.github?.slug ?? this.#config.platform?.githubAppSlug,\n }),\n );\n installedPlatformGithub = true;\n }\n if (!integrations.some(integration => integration.id === 'incidentio')) {\n const { PlatformIncidentioIntegration } = await import('./integrations/platform/incidentio/integration.js');\n integrations.push(new PlatformIncidentioIntegration());\n }\n if (!integrations.some(integration => integration.id === 'jira')) {\n const { PlatformJiraIntegration } = await import('./integrations/platform/jira/integration.js');\n integrations.push(new PlatformJiraIntegration());\n }\n if (!integrations.some(integration => integration.id === 'gitlab')) {\n const { PlatformGitLabIntegration } = await import('./integrations/platform/gitlab/integration.js');\n integrations.push(new PlatformGitLabIntegration());\n }\n if (!integrations.some(integration => integration.id === 'linear')) {\n const { PlatformLinearIntegration } = await import('./integrations/platform/linear/integration.js');\n integrations.push(new PlatformLinearIntegration());\n }\n }\n // Never let the key be a silent no-op: it only applies to the integration\n // the factory installs itself, so warn when it had nothing to apply to.\n if (this.#config.platform?.github && !installedPlatformGithub) {\n console.warn(\n \"[factory] 'platform.github' config was provided but the factory installed no GitHub integration of its \" +\n 'own ' +\n (explicitGithub\n ? \"(an explicit integration with id 'github' takes precedence, so these options were ignored).\"\n : '(no Platform credentials are configured and no explicit GitHub integration was passed).'),\n );\n }\n\n // Validate ids up front so a copy-paste duplicate fails loud instead of one\n // instance silently shadowing the other.\n const integrationIds = new Set<string>();\n for (const integration of integrations) {\n if (integrationIds.has(integration.id)) {\n throw new Error(`MastraFactory: duplicate integration id '${integration.id}' in 'integrations'.`);\n }\n integrationIds.add(integration.id);\n }\n const configVersion = this.#configVersion;\n\n // FactoryStorage owns every app-table domain and initializes them through\n // the same lifecycle as the backend connection.\n const intakeStorage = storage.registerDomain(new IntakeStorage());\n const auditStorage = storage.registerDomain(new AuditStorage());\n const workItemsStorage = storage.registerDomain(new WorkItemsStorage());\n workItemsStorage.onAttentionChanged(scope => touchFeed(eventBus, scope));\n workItemsStorage.useTerminalPhasePredicate(item => isTerminalWorkItem(this.#boards, item));\n const modelCredentialsStorage = storage.registerDomain(new ModelCredentialsStorage(secretEncryption));\n const modelDefaultsStorage = storage.registerDomain(new ModelDefaultsStorage());\n const memorySettingsStorage = storage.registerDomain(new MemorySettingsStorage());\n const customProvidersStorage = storage.registerDomain(new CustomProvidersStorage(secretEncryption));\n const queueHealthStorage = storage.registerDomain(new QueueHealthStorage());\n // Generic integration storage (connections/subscriptions/settings) — the\n // default persistence surface for integrations without a bespoke domain.\n const integrationStorage = storage.registerDomain(new IntegrationStorage(secretEncryption));\n const factoryProjectsStorage = storage.registerDomain(new FactoryProjectsStorage());\n const filesystemStorage = storage.registerDomain(new FilesystemStorage());\n const sourceControlStorage = storage.registerDomain(new SourceControlStorage());\n // Reverse index from a platform sender (Slack/Discord/...) to a Mastra\n // tenant, so inbound channel events can resolve the sender's model creds.\n const channelIdentityStorage = storage.registerDomain(new ChannelIdentityStorage());\n const workItemCommentsStorage = storage.registerDomain(new WorkItemCommentsStorage());\n // Every app-table domain handle the route builders and integrations need,\n // threaded explicitly (no service locator).\n const domains = {\n intake: intakeStorage,\n modelCredentials: modelCredentialsStorage,\n modelDefaults: modelDefaultsStorage,\n memorySettings: memorySettingsStorage,\n customProviders: customProvidersStorage,\n filesystem: filesystemStorage,\n projects: factoryProjectsStorage,\n queueHealth: queueHealthStorage,\n workItems: workItemsStorage,\n channelIdentity: channelIdentityStorage,\n comments: workItemCommentsStorage,\n };\n const auditDomain = new AuditDomain({\n auth: routeAuth,\n audit: auditStorage,\n projects: factoryProjectsStorage,\n users: auth && isUserProvider(auth) ? auth : undefined,\n sinks: integrations,\n agentTenant: requestContext => {\n const user = getFactoryAuthUserFromContext(requestContext);\n return { orgId: getFactoryAuthOrgId(user), userId: getFactoryAuthUserId(user) };\n },\n });\n // Held by reference: the channel attach below pushes into it, long after this.\n const feedPublishers: WorkItemFeedPublisher[] = [];\n const commentsDomain = new CommentsDomain({\n auth: routeAuth,\n comments: workItemCommentsStorage,\n workItems: workItemsStorage,\n projects: factoryProjectsStorage,\n channelIdentity: channelIdentityStorage,\n audit: auditDomain,\n publishers: feedPublishers,\n pubsub: eventBus,\n });\n\n const sandboxOption = this.#config.sandbox;\n let sandboxConfig: FactorySandbox | undefined;\n if (sandboxOption === undefined) {\n sandboxConfig = await platformDefaultSandbox();\n } else if (isFactorySandbox(sandboxOption)) {\n sandboxConfig = sandboxOption;\n } else if (typeof sandboxOption === 'function') {\n sandboxConfig = new CallbackFactorySandbox(sandboxOption);\n } else {\n throw new Error(invalidSandboxOptionMessage(sandboxOption));\n }\n this.#sandbox = sandboxConfig;\n\n const workspaceRegistry = new FactoryWorkspaceRegistry();\n\n // One shared OAuth state signer per boot. The deploy entry supplies a\n // replica-stable secret when needed; otherwise local development gets a\n // per-process random signer (`stable: false`).\n const stateSigner = createStateSigner(this.#config.stateSecret);\n\n // One-time provider initialization with factory-level context (e.g.\n // better-auth builds its default instance on the backend's auth\n // database, WorkOS derives its redirect URI from the public URL).\n // Failures surface here, at prepare() — a misconfigured provider must\n // not boot.\n if (auth && hasAuthInit(auth)) {\n await timedPhase('prepare.auth.init', () =>\n auth.init({ database: storage.authDatabase?.(), publicUrl: publicOrigin, allowedOrigins }),\n );\n }\n\n // Single init path: backend connection failure is a hard boot error;\n // registered app domains initialize fail-soft inside FactoryStorage.\n await timedPhase('prepare.storage.init', () => storage.init());\n\n // Per-tenant model credentials: once the credentials domain is up, model\n // resolution goes through the caller's own store and the SDK stops\n // mirroring stored API keys into process.env.\n //\n // Only register when a real auth adapter gates callers. In local /\n // auth-disabled mode there is no authenticated tenant, so registering would\n // force every model call through an empty tenant store (fail-closed, no env\n // fallback) and break chat with \"Not logged in\". Leaving it unregistered\n // lets the SDK fall back to the file-backed AuthStorage (auth.json) — the\n // same store the local /login and Settings pages read and write.\n // Custom providers: DB-backed in both modes (org rows in tenant mode, the\n // sentinel `local` org in no-auth mode). Once registered, model resolution\n // and the gateway catalog never read settings.json custom providers.\n registerCustomProvidersSource({ storage: customProvidersStorage, authEnabled: Boolean(auth) });\n\n for (const integration of integrations) {\n const integrationSourceControl = integration.versionControl\n ? sourceControlStorage.forIntegration(integration.id)\n : undefined;\n integration.initialize?.({\n storage: integrationStorage.forIntegration(integration.id),\n projects: factoryProjectsStorage,\n auth: routeAuth,\n intake: intakeStorage,\n ...(integrationSourceControl ? { sourceControl: integrationSourceControl } : {}),\n channels: () => this.#prepared?.base.controller.getChannels(),\n });\n if (integration.versionControl && integrationSourceControl) {\n integration.versionControl.initialize({ storage: integrationSourceControl });\n }\n }\n // Keep the legacy GitHub partition readable even when no GitHub\n // integration is registered; existing sessions may outlive a config change.\n const sourceControlIntegrationIds = [\n ...new Set(['github', ...integrations.filter(integration => integration.versionControl).map(({ id }) => id)]),\n ];\n const sourceControlHandles = sourceControlIntegrationIds.map(id => sourceControlStorage.forIntegration(id));\n const sourceControlSessions = createSourceControlSessionLookup(sourceControlHandles);\n const modelPolicyDependencies = {\n projects: factoryProjectsStorage,\n sourceControl: sourceControlSessions,\n workItems: workItemsStorage,\n };\n if (auth) {\n registerTenantCredentialResolver(modelCredentialsStorage, deploymentModelProviders, requestContext =>\n resolveFactoryCredentialTenant(requestContext, modelPolicyDependencies),\n );\n }\n\n // Every integration uses generic integration storage. Version-control\n // providers additionally require the source-control storage domain. Readiness\n // is derived solely from capability presence, never from provider ids.\n const integrationRegistrations = integrations.map(integration => {\n const requiredDomains = [\n 'integrations',\n ...(integration.versionControl ? ['source-control'] : []),\n // Channels resolve an inbound sender to a tenant through the reverse\n // index; without it every message would dispatch tenant-less.\n ...(integration.channels ? ['channel-identity'] : []),\n ];\n return {\n integration,\n ready: requiredDomains.every(domain => storage.isDomainReady(domain)),\n ensureReady: async () => {\n for (const domain of requiredDomains) await storage.ensureDomainReady(domain);\n },\n };\n });\n const intakeReady =\n integrations.some(integration => integration.intake !== undefined) && storage.isDomainReady('intake');\n const factoryReady = storage.isDomainReady('projects') && storage.isDomainReady('work-items');\n // Sessions from before shared resources ran under their own id. Move them\n // onto their Factory or owner in the background: it can take minutes on a\n // remote database, and an unmoved session keeps working under its own id\n // meanwhile. Run bindings decide which sessions belong to a Factory, so it\n // waits for work items.\n if (storage.isDomainReady('source-control') && storage.isDomainReady('work-items')) {\n this.#sessionResourceMigration = timedPhase('background.migrate.sessionResources', async () => {\n try {\n const mastraStorage = storage.getMastraStorage();\n const memory = await mastraStorage.getStore('memory');\n if (!memory) return false;\n // The sessions' own Memory, so a moved thread takes its observation vectors along.\n const sessionMemory = getDynamicMemory(mastraStorage, vector);\n const report = await migrateSessionResources({\n sessions: sourceControlStorage,\n workItems: workItemsStorage,\n ...(storage.isDomainReady('integrations') ? { integrations: integrationStorage } : {}),\n memory,\n threads: sessionMemory({ requestContext: new RequestContext() }),\n });\n await sessionMemory.settled();\n await privatizeOwnerResourceSessions({ sessions: sourceControlStorage, workItems: workItemsStorage, memory });\n return report.runBindings > 0;\n } catch (error) {\n // Unmoved sessions keep working under their own id; the next start retries.\n console.warn(\n `[factory] session resource migration stopped early: ${error instanceof Error ? error.message : error}`,\n );\n return false;\n }\n });\n }\n const knowledgeEnabled =\n this.#config.knowledge !== undefined || process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === '1';\n const githubIntegration = integrations.find(integration => integration.id === 'github') as\n | GithubIntegration\n | undefined;\n const gitlabIntegration = integrations.find(\n integration => integration.id === 'gitlab' && integration.intake && integration.versionControl,\n ) as GitLabIntegrationBase | undefined;\n const workItemsReady = storage.isDomainReady('work-items');\n const sessionRetirement =\n sandboxConfig && storage.isDomainReady('source-control')\n ? new SessionRetirementCoordinator({\n invalidateSession: sessionId => workspaceRegistry.invalidateSession(sessionId),\n sandbox: sandboxConfig,\n })\n : undefined;\n const retireTerminalSessions =\n sessionRetirement && workItemsReady\n ? async ({ orgId, workItemId }: { orgId: string; workItemId: string }) => {\n const item = await workItemsStorage.get({ orgId, id: workItemId });\n if (!item) return;\n const sessionIds = [...new Set(Object.values(item.sessions).map(session => session.sessionId))];\n await Promise.all(\n sessionIds.map(async sessionId => {\n const sourceControl = await sourceControlSessions.getSourceControlBySessionId(sessionId);\n if (!sourceControl) return;\n await sessionRetirement.retireSession({\n sourceControl,\n orgId,\n sessionId,\n deleteSession: false,\n });\n }),\n );\n }\n : undefined;\n // Terminal-stage cleanup: ingest any trailing tool results from the item's\n // bound threads, then revoke the bindings so completed items leave the\n // reconcile walk (the active-binding set otherwise grows forever), and\n // finally release the item's sandboxes. Each step is best-effort — a\n // committed transition never fails on cleanup.\n const terminalCleanup = workItemsReady\n ? createTerminalStageCleanup({\n workItems: workItemsStorage,\n // `factoryProcessor` is assigned below in this scope; the cleanup\n // only runs on transitions long after bootstrap completes.\n reconcileBinding: async (binding): Promise<void> => {\n await factoryProcessor?.reconcileBinding(binding);\n },\n // Abort the live run on a retired seat so the model cannot keep\n // executing unbound (or be resumed later) once its binding is revoked.\n // `this.#prepared` is assigned below; cleanup only runs long after.\n abortSession: async (binding): Promise<void> => {\n const controller = this.#prepared?.base.controller;\n if (!controller) return;\n const session = await controller.getSession(binding.sessionId);\n if (session?.stream.isActive()) session.abort();\n },\n // Session retirement supersedes the older direct sandbox release: it\n // invalidates the session and stops/destroys its sandbox.\n ...(retireTerminalSessions ? { releaseSandboxes: retireTerminalSessions } : {}),\n })\n : undefined;\n // Factory messaging needs the controller and its notifications store, which exist once the mount is up.\n const factoryMessaging = async () => {\n const controller = this.#prepared?.base.controller;\n const notifications = await controller?.getMastra()?.getStorage()?.getStore('notifications');\n return controller && notifications ? { controller, notifications } : null;\n };\n const factoryReporting = async (): Promise<FactoryReporting | null> => {\n const messaging = await factoryMessaging();\n if (!messaging) return null;\n return {\n notifications: messaging.notifications,\n deliver: (target, notification, options) =>\n deliverFactorySessionNotification({\n controller: messaging.controller,\n sessions: sourceControlSessions,\n runs: workItemsStorage,\n target,\n notification,\n ...options,\n }),\n };\n };\n const sessionReports = {\n sessions: sourceControlSessions,\n workItems: workItemsStorage,\n reporting: factoryReporting,\n };\n const reportSessionRunEnd = createSessionRunEndReporter(sessionReports);\n // Repeated attempts of one delivery send one report: identical failures to\n // the same follower are deduplicated.\n // A woken thread under a Factory or user resource names its session with its\n // stamp, or is the session's own thread; an unmigrated thread still runs\n // under its session id as its resource.\n const resolveWakeSession = async ({\n resourceId,\n threadId,\n thread,\n }: {\n resourceId: string;\n threadId: string;\n thread?: { metadata?: Record<string, unknown> } | null;\n }) => {\n const stored =\n thread === undefined ? await this.#prepared?.base.controller.queryThreadById({ threadId }) : thread;\n const stamp = stored?.metadata?.factorySessionId;\n const candidates = [...new Set([typeof stamp === 'string' ? stamp : '', threadId, resourceId])].filter(Boolean);\n for (const sessionId of candidates) {\n const row = await sourceControlSessions.getBySessionId(sessionId);\n // The stamp is client-writable metadata: a session only claims a\n // thread that runs under its own memory resource, or under its own id\n // as the resource from before resources were shared.\n // A stamp (neither the thread's own id nor its legacy resource) only\n // counts where the session's stamps are trusted.\n const viaStamp = sessionId !== threadId && sessionId !== resourceId;\n if (\n row &&\n (!viaStamp || sessionStampCounts(row, resourceId)) &&\n (resourceId === sessionId ||\n resourceId === (await sessionMemoryResourceId(this.#prepared?.base.controller, row, workItemsStorage)))\n ) {\n return { sessionId, row };\n }\n }\n // Unresolved: report on the woken thread, never on a session a stamp merely names.\n return { sessionId: threadId, row: null };\n };\n const failWake = async ({ sessionId, threadId }: { sessionId: string; threadId: string }, reason: string) => {\n const message = `Factory session ${sessionId} can't be woken as its owner: ${reason}.`;\n await reportSessionRunEnd({\n sessionId,\n threadId,\n since: new Date(),\n outcome: { status: 'failed', reason: message, failureCode: 'wake-owner-unresolved' },\n }).catch(error => console.warn('[factory] Unable to report a failed wake.', error));\n throw new Error(message);\n };\n const onTerminalStage = terminalCleanup\n ? (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n revision: number;\n actor: FactoryRuleActor;\n }): Promise<void> =>\n terminalCleanup({\n orgId: args.orgId,\n factoryProjectId: args.factoryProjectId,\n workItemId: args.workItemId,\n revision: args.revision,\n // Leave the seat that drove its own terminal transition running; it\n // is already returning from its transition tool call.\n ...(args.actor.type === 'agent' ? { initiatingBindingId: args.actor.bindingId } : {}),\n })\n : retireTerminalSessions;\n const transitionService = workItemsReady\n ? new FactoryTransitionService({\n configVersion,\n boards: this.#boards,\n storage: workItemsStorage,\n audit: auditDomain,\n autoApprovePlans: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoApprovePlans ?? false;\n },\n selfReviewEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.selfReviewEnabled ?? false;\n },\n ...(onTerminalStage ? { onTerminalStage } : {}),\n onTransitionCommitted: createStageChangeNotifier({\n workItems: workItemsStorage,\n reporting: factoryReporting,\n }),\n ...(githubIntegration\n ? {\n onAccepted: (args: { orgId: string; factoryProjectId: string; item: WorkItemRow }) =>\n reconcileGithubAcceptanceLabels(\n githubIntegration,\n sourceControlStorage.forIntegration(githubIntegration.id),\n args,\n ),\n }\n : {}),\n })\n : undefined;\n // One set of storage and services behind the Factory tools, shared by agent sessions and the MCP endpoint.\n const factoryToolDeps: FactoryToolDependencies = {\n workItems: workItemsStorage,\n comments: workItemCommentsStorage,\n feed: commentsDomain,\n audit: auditStorage,\n boards: this.#boards,\n transitionService,\n auditRecorder: auditDomain,\n sessions: sourceControlSessions,\n sessionModel: {\n projects: factoryProjectsStorage,\n modelDefaults: modelDefaultsStorage,\n ...(auth\n ? {\n tenantCatalog: {\n credentials: modelCredentialsStorage,\n customProviders: customProvidersStorage,\n deploymentProviders: deploymentModelProviders,\n },\n }\n : {}),\n },\n intake: intakeStorage,\n startCoordinator: () => this.#startCoordinator,\n messaging: factoryMessaging,\n };\n // Proactive environment builds exist only when the sandbox can build\n // templates on its own; the workflow is registered on the host's Mastra\n // and the runner reaches the booted instance through the controller.\n this.#environmentBuilds = this.#sandbox?.builds\n ? new EnvironmentBuildRunner(\n {\n sandbox: this.#sandbox,\n projects: factoryProjectsStorage,\n sourceControl: githubIntegration?.versionControl\n ? {\n storage: sourceControlStorage.forIntegration(githubIntegration.id),\n versionControl: githubIntegration.versionControl,\n }\n : undefined,\n logger: { info: (msg, meta) => console.info(`[Mastra Factory] ${msg}`, meta ?? {}) },\n },\n { getMastra: () => this.#prepared?.base.controller.getMastra() },\n )\n : undefined;\n const environmentBuilds = this.#environmentBuilds;\n const projectRoutes = new ProjectRoutes({\n auth: routeAuth,\n sandbox: this.#sandbox,\n ...(environmentBuilds ? { environmentBuilds } : {}),\n projects: factoryProjectsStorage,\n sourceControl: sourceControlStorage,\n versionControlIntegrationIds: integrations\n .filter(integration => integration.versionControl)\n .map(integration => integration.id),\n ...(githubIntegration || gitlabIntegration\n ? {\n resolveRepository: async ({ integrationId, orgId, userId, installationId, externalId, slug }) => {\n if (githubIntegration && integrationId === githubIntegration.id) {\n const installation = await githubIntegration.sourceControlStorage.installations.get({\n orgId,\n id: installationId,\n });\n if (!installation) return null;\n const repositories = await githubIntegration.listInstallationRepos(Number(installation.externalId));\n const selected = repositories.find(repo => repo.id.toString() === externalId && repo.fullName === slug);\n if (!selected) return null;\n return githubIntegration.sourceControlStorage.repositories.upsert({\n orgId,\n input: {\n installationId,\n externalId,\n slug: selected.fullName,\n defaultBranch: isValidGitRef(selected.defaultBranch) ? selected.defaultBranch : 'main',\n providerMetadata: { private: selected.private, owner: selected.owner },\n },\n });\n }\n\n if (\n !gitlabIntegration?.intake ||\n !gitlabIntegration.versionControl ||\n integrationId !== gitlabIntegration.id\n )\n return null;\n const handle = sourceControlStorage.forIntegration(gitlabIntegration.id);\n const installation = await handle.installations.get({ orgId, id: installationId });\n if (!installation) return null;\n const sources = await gitlabIntegration.intake.listSources({ orgId, userId });\n const selected = sources.find(\n source =>\n source.name === slug &&\n typeof source.metadata?.projectId === 'string' &&\n source.metadata.projectId === externalId &&\n source.metadata.connectionId === installation.externalId,\n );\n if (!selected) return null;\n const [repository] = await gitlabIntegration.versionControl.registerRepositories({\n orgId,\n installationId,\n repositories: [\n {\n externalId,\n slug,\n defaultBranch:\n typeof selected.metadata?.defaultBranch === 'string' &&\n isValidGitRef(selected.metadata.defaultBranch)\n ? selected.metadata.defaultBranch\n : 'main',\n metadata: selected.metadata,\n },\n ],\n });\n return repository ?? null;\n },\n }\n : {}),\n ...(githubIntegration || gitlabIntegration\n ? {\n onProjectRepositoryLinked: ({ orgId, projectRepository }) => {\n void (async () => {\n const linkedInGithub =\n githubIntegration &&\n (await sourceControlStorage.forIntegration('github').projectRepositories.get({\n orgId,\n id: projectRepository.id,\n }));\n if (linkedInGithub) {\n await githubIntegration.ingestLinkedRepositoryBacklog({\n orgId,\n projectRepositoryId: projectRepository.id,\n });\n } else if (gitlabIntegration) {\n const linkedInGitlab = await sourceControlStorage.forIntegration('gitlab').projectRepositories.get({\n orgId,\n id: projectRepository.id,\n });\n if (linkedInGitlab) {\n await gitlabIntegration.ingestLinkedRepositoryBacklog({\n orgId,\n projectRepositoryId: projectRepository.id,\n });\n }\n }\n })().catch(error => {\n console.warn('[factory] Failed to import a linked repository backlog:', error);\n });\n },\n }\n : {}),\n ...(sessionRetirement ? { sessionRetirement } : {}),\n ...(workItemsReady\n ? {\n workItems: workItemsStorage,\n controller: {\n getSession: async (sessionId: string) => this.#prepared?.base.controller.getSession(sessionId),\n },\n }\n : {}),\n });\n // The row follows whoever pays for the request, so its memory model is one their credentials reach.\n const memorySettingsRowKey = async (requestContext: RequestContext, binding: FactoryRunBindingRecord | null) => {\n // A wake lends the session owner even with auth off, but credentials stay process-wide there.\n const policy = auth ? await resolveFactoryModelPolicy(requestContext, modelPolicyDependencies) : undefined;\n if (policy) {\n const orgId = tenantOrgId(policy.tenant);\n return policy.tenant.credentialScope === 'factory' && policy.factoryProjectId\n ? { orgId, userId: factoryMemorySettingsUserId(policy.factoryProjectId) }\n : { orgId, userId: policy.tenant.userId };\n }\n // No tenant pays: the session's Factory row applies.\n const scope = readFactorySessionScope(requestContext);\n const factoryProjectId = binding?.factoryProjectId ?? scope?.factoryProjectId;\n if (!factoryProjectId) return { orgId: 'local', userId: 'local' };\n return {\n orgId: binding?.orgId ?? scope?.factoryOrgId ?? 'local',\n userId: factoryMemorySettingsUserId(factoryProjectId),\n };\n };\n const loadMemorySettings = async ({\n requestContext,\n binding,\n }: {\n requestContext: RequestContext | undefined;\n binding: FactoryRunBindingRecord | null;\n }) => {\n if (!requestContext) return;\n const record = await memorySettingsStorage.get(await memorySettingsRowKey(requestContext, binding));\n requestContext.set('mastra__factoryMemorySettings', record);\n };\n // Thinking defaults come from the session's defaults set, never the host's settings.json.\n const resolveDefaultThinkingLevel = (requestContext: RequestContext | undefined) =>\n resolveFactoryThinkingLevel(requestContext, {\n projects: factoryProjectsStorage,\n sourceControl: sourceControlSessions,\n workItems: workItemsStorage,\n modelDefaults: modelDefaultsStorage,\n });\n const factoryProcessor = workItemsReady\n ? new FactoryPhaseStateProcessor({\n configVersion,\n storage: workItemsStorage,\n boards: this.#boards,\n loadMemorySettings,\n defaultThinkingLevel: resolveDefaultThinkingLevel,\n ...(transitionService ? { transitionService } : {}),\n ...(githubIntegration\n ? {\n recordPullRequestProvenance: (input: Parameters<typeof recordFactoryPullRequestProvenance>[4]) =>\n recordFactoryPullRequestProvenance(\n githubIntegration,\n sourceControlStorage.forIntegration('github'),\n integrationStorage.forIntegration('github'),\n workItemsStorage,\n input,\n ),\n }\n : {}),\n messageReader: {\n listMessages: async input => {\n const memory = await storage.getMastraStorage().getStore('memory');\n return memory ? memory.listMessages(input) : { messages: [], hasMore: false };\n },\n },\n })\n : undefined;\n\n // Boot assertion: an active integration that signs OAuth `state` needs a\n // replica-stable signer — a per-process random secret silently breaks the\n // OAuth callback on any replica that didn't sign the state. Fail loud now\n // instead. (The built-ins also assert this inside their readiness gates.)\n for (const { integration } of integrationRegistrations) {\n if (integration.requiresStableStateSigner && !stateSigner.stable) {\n throw new Error(\n `MastraFactory: integration '${integration.id}' signs OAuth state and requires a ` +\n `replica-stable state secret, but none is configured. Set 'stateSecret' on the factory config.`,\n );\n }\n }\n\n // The SDK needs to know which backend the injected Mastra store uses\n // (its own `instanceof` detection breaks when the dependency graph holds\n // duplicate package copies). Resolve it by walking the FactoryStorage\n // prototype chain by class name — the factory can't import the concrete\n // classes since '@mastra/pg' / '@mastra/libsql' are the user's choice.\n const mastraStorageBackend = (() => {\n for (let proto = Object.getPrototypeOf(storage); proto; proto = Object.getPrototypeOf(proto)) {\n if (proto.constructor?.name === 'PgFactoryStorage') return 'pg' as const;\n if (proto.constructor?.name === 'LibSQLFactoryStorage') return 'libsql' as const;\n }\n return undefined;\n })();\n\n const integrationInputProcessors = integrations.flatMap(integration => integration.processors?.input ?? []);\n // Integrations contributing tools to agent sessions: org-scoped\n // `agentTools` (resolved per request) + session-scoped `sessionTools`.\n const toolIntegrations = integrationRegistrations.filter(\n ({ integration }) => integration.agentTools || integration.sessionTools,\n );\n const sourceControlToolProviders = integrations.flatMap(integration =>\n integration.versionControl\n ? [\n {\n id: integration.id,\n versionControl: integration.versionControl,\n storage: sourceControlStorage.forIntegration(integration.id),\n },\n ]\n : [],\n );\n\n // Build the real production controller (agents, tools, memory, OM, MCP,\n // providers) — the terminal app's, minus modes. Agent state lives in\n // the storage backend's Mastra store alongside the Factory app tables —\n // one shared database for all users, separated by `resourceId` scoping.\n const prepared = await timedPhase('prepare.controllerMount', () =>\n prepareAgentControllerMount({\n controllerId: CONTROLLER_ID,\n browser: this.#config.browser,\n coAuthor: { name: 'mastra-platform[bot]' },\n ...(this.#config.disableBuiltinTools?.length ? { disableBuiltinTools: this.#config.disableBuiltinTools } : {}),\n modes: false,\n // Subagents are disabled, matching the Mastra Code TUI default.\n subagents: [],\n resolveDefaultThinkingLevel: ({ requestContext }) => resolveDefaultThinkingLevel(requestContext),\n workspace: createWorkspaceFactory({\n ...(sandboxConfig ? { sandbox: sandboxConfig } : {}),\n ...(this.#config.sandboxStart ? { sandboxStart: this.#config.sandboxStart } : {}),\n sourceControls: integrations.flatMap(integration =>\n integration.versionControl\n ? [\n {\n id: integration.id,\n versionControl: integration.versionControl,\n storage: sourceControlStorage.forIntegration(integration.id),\n ...(integration.id === 'github' && githubIntegration ? { github: githubIntegration } : {}),\n },\n ]\n : [],\n ),\n ...(factoryProjectsStorage ? { projects: factoryProjectsStorage } : {}),\n ...(workItemsStorage ? { workItems: workItemsStorage } : {}),\n workspaceRegistry,\n }),\n disableGithubSignals: true,\n // A wake (notification or peer signal) has no signed-in request, so\n // tenant credential resolution would fail closed. Run it as the Factory\n // session's owner in its org.\n // With auth on, a wake whose owner can't be resolved must not run (it\n // would fail on credentials with no hint why); it fails, and the\n // session's followers get a failed report naming the reason.\n prepareWakeRequestContext: async ({ requestContext, resourceId, threadId }) => {\n if (!storage.isDomainReady('source-control')) {\n if (auth) await failWake({ sessionId: threadId, threadId }, 'session storage is not ready');\n return;\n }\n const { sessionId, row } = await resolveWakeSession({ resourceId, threadId });\n // Only a session that owns the thread's resource may lend its owner;\n // the unresolved fallback id must never be looked up as a session.\n if (!row) {\n if (auth) await failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['session-not-found']);\n return;\n }\n const prepared = await prepareSessionRunContext(requestContext, sessionId, {\n sessions: sourceControlSessions,\n });\n if (prepared !== 'prepared') {\n if (auth) await failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED[prepared]);\n return;\n }\n await primeCustomProvidersForRequestContext(requestContext);\n },\n // A deferred delivery can land after the session closed, after a\n // restart, or on another replica: nobody here owns it, and the wake\n // would run with no identity at all. Bring the session online as its\n // row's owner first, as a direct message to an offline session does.\n ...(auth\n ? {\n resumeWakeSession: async ({ resourceId, threadId }: { resourceId: string; threadId: string }) => {\n const controller = this.#prepared?.base.controller;\n if (!controller) return failWake({ sessionId: threadId, threadId }, 'the Factory is not started');\n const thread = await controller.queryThreadById({ threadId });\n if (!thread || thread.resourceId !== resourceId) {\n return failWake({ sessionId: threadId, threadId }, `thread ${threadId} is not the session's`);\n }\n const { sessionId, row } = storage.isDomainReady('source-control')\n ? await resolveWakeSession({ resourceId, threadId, thread })\n : { sessionId: threadId, row: null };\n if (!row?.factoryProjectId)\n return failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['session-not-found']);\n if (!hasResolvedOrg(row.orgId)) {\n return failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['organization-unresolved']);\n }\n if (await controller.getSession(sessionId)) return;\n await createSessionAsRowOwner(controller, {\n sessionId,\n ownerResourceId: resourceId,\n row,\n tags: {\n factoryProjectId: row.factoryProjectId,\n ...(row.projectRepositoryId ? { projectRepositoryId: row.projectRepositoryId } : {}),\n },\n threadId,\n });\n },\n }\n : {}),\n // Memory settings live in the factory's `memory-settings` app table (per\n // org/user), so the host machine's TUI settings.json must not seed them.\n disableSettingsOmSeed: true,\n hostInstructions: async ({ requestContext }) => {\n const context = requestContext.get('controller') as\n | AgentControllerRequestContext<MastraCodeState>\n | undefined;\n // The SDK resolves this callback before it loads repository\n // AGENTS.md/CLAUDE.md. A controller recreated after restart has\n // only initialState, and a partially persisted one can keep\n // `factoryProjectId` while `untrustedCheckout` is gone, so the\n // presence of the project id alone proves nothing. Heal whenever any\n // trust field the recovery writes is missing, now, not later when\n // the agent's tools are assembled. Unbound sessions never gain these\n // fields and pay one binding lookup per prompt.\n if (context?.threadId && context.sessionId) {\n const current = context.getState();\n const trustStateComplete =\n Boolean(current.factoryProjectId) &&\n Boolean(current.factoryOrgId) &&\n typeof current.untrustedCheckout === 'boolean';\n if (!trustStateComplete) {\n const recovered = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n forceBindingLookup: true,\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n });\n if (recovered?.binding) {\n const state = context.getState();\n if (\n state.factoryProjectId !== recovered.binding.factoryProjectId ||\n (recovered.binding.role === 'review' && state.untrustedCheckout !== true)\n ) {\n throw new Error(\n 'Factory review session security state could not be restored before prompt creation.',\n );\n }\n }\n }\n }\n return undefined;\n },\n // A factory reads the repository it works on and its skill, never the\n // ~/.claude instructions of whoever hosts the process. On the controller\n // rather than per session, so webhook-recreated sessions keep it too.\n // Blank project identity for the same reason: the SDK's defaults seed\n // sessions with the HOST process's own project root / name / branch,\n // which must never reach a hosted session's prompt. Repo-backed\n // sessions get their real workdir pinned by workspace resolution;\n // chat-only sessions legitimately have no project.\n // Factory sessions also start fail-closed on org classification: the\n // unresolved marker is set at birth, a successful org seed clears it,\n // and a resolved `factoryOrgId` always takes precedence — so a failed\n // (best-effort) seed can never leave a session classified as local.\n initialState: {\n skipGlobalInstructions: true,\n factoryOrgUnresolved: true,\n projectPath: '',\n projectName: '',\n gitBranch: '',\n },\n storage: storage.getMastraStorage(),\n ...(mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {}),\n ...(this.#config.knowledge ? { knowledge: this.#config.knowledge } : {}),\n // The environment signal tells the agent which repositories its\n // sandbox holds and where; the phase signal, when work items are on,\n // comes after it.\n inputProcessors: async ({ requestContext }: { requestContext: RequestContext }) => {\n const environmentProcessor = new FactoryEnvironmentStateProcessor();\n const sessionsProcessor =\n workItemsStorage && storage.isDomainReady('source-control')\n ? [\n new FactorySessionsStateProcessor({\n authEnabled: routeAuth.enabled(),\n sessions: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n boards: this.#boards,\n isRunning: async sessionId => {\n const session = await this.#prepared?.base.controller.getSession(sessionId);\n return session?.stream.isActive() ?? false;\n },\n lastActivity: async threadId => {\n const thread = await this.#prepared?.base.controller.queryThreadById({ threadId });\n return thread?.updatedAt ? new Date(thread.updatedAt) : null;\n },\n notifications: async () => (await factoryMessaging())?.notifications ?? null,\n }),\n ]\n : [];\n if (factoryProcessor) {\n await factoryProcessor.prepareMemorySettings(requestContext);\n return [...integrationInputProcessors, environmentProcessor, ...sessionsProcessor, factoryProcessor];\n }\n // Without work items there is no run binding, so the caller's row applies.\n try {\n await loadMemorySettings({ requestContext, binding: null });\n } catch (error) {\n reportMemorySettingsUnavailable(requestContext, error instanceof Error ? error.message : String(error));\n }\n return [...integrationInputProcessors, environmentProcessor, ...sessionsProcessor];\n },\n outputProcessors: [\n ...integrations.flatMap(integration => integration.processors?.output ?? []),\n new FactoryReplyCredentialProcessor(),\n ],\n ...(vector ? { vector } : {}),\n extraTools: async ({ requestContext }: { requestContext: RequestContext }) => {\n const tools: IntegrationTools = {};\n const toolOwners = new Map<string, string>();\n const mergeTools = (ownerId: string, contributed: IntegrationTools) => {\n for (const [name, tool] of Object.entries(contributed)) {\n const owner = toolOwners.get(name);\n if (owner) {\n throw new Error(\n `MastraFactory: integration tool '${name}' from '${ownerId}' conflicts with '${owner}'.`,\n );\n }\n toolOwners.set(name, ownerId);\n tools[name] = tool;\n }\n };\n if (storage.isDomainReady('source-control')) {\n mergeTools(\n 'source-control',\n await createSourceControlTools({\n requestContext,\n providers: sourceControlToolProviders,\n audit: auditDomain,\n testChecksEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.reviewTestChecksEnabled ?? false;\n },\n ...(workItemsStorage\n ? {\n selfReviewApprovedHead: async () => {\n const resolution = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n });\n if (!resolution) return undefined;\n const binding =\n resolution.binding ?? (await workItemsStorage.findActiveRunBinding(resolution.address));\n if (!binding) return undefined;\n const item = await workItemsStorage.get({ orgId: binding.orgId, id: binding.workItemId });\n if (!item || boardForWorkItem(item) !== 'work') return undefined;\n if (typeof item.metadata?.openPullRequestNumber === 'number') return undefined;\n // A verdict already recorded still binds the change request to its head.\n if (item.metadata?.selfReviewVerdict === undefined) {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({\n orgId: binding.orgId,\n id: binding.factoryProjectId,\n });\n if (!project?.selfReviewEnabled) return undefined;\n }\n const sha = item.metadata?.selfReviewedHeadSha;\n return item.metadata?.selfReviewVerdict === 'approve' && typeof sha === 'string' ? sha : null;\n },\n boundChangeRequestId: async () => {\n const resolution = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n });\n if (!resolution) return undefined;\n const binding =\n resolution.binding ?? (await workItemsStorage.findActiveRunBinding(resolution.address));\n if (binding?.role !== 'review') return undefined;\n const item = await workItemsStorage.get({ orgId: binding.orgId, id: binding.workItemId });\n const source = item?.externalSource;\n if (!source || !/pull-request|merge-request/.test(source.type)) return undefined;\n return /(\\d+)$/.exec(source.externalId)?.[1];\n },\n }\n : {}),\n }),\n );\n }\n if (workItemsStorage && transitionService) {\n mergeTools(\n 'factory',\n await createFactoryTransitionTools({\n requestContext,\n storage: workItemsStorage,\n transitionService,\n boards: this.#boards,\n // Heals crash-resumed sessions: recovered addresses re-seed\n // projectRepositoryId/baseRef from the source session record.\n // Only offered while the source-control domain is ready — a\n // throwing lookup would abort recovery's catch block and also\n // skip the metadata baseRef fallback.\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n }),\n );\n // Review-role sessions get `factory_review_source` so the\n // published review can carry the session URL that produced it\n // — the affordance that lets a suspicious review (e.g. one\n // that lands on the wrong PR) be traced back to its run.\n //\n // The session URL is browser-facing (a human opens it from a\n // GitHub/GitLab review comment), so it needs the UI host —\n // the same origin Slack session deep-links resolve against\n // (`integrations/slack/slack.ts:168-171`, `:809-812`). In a\n // separate-SPA deployment `publicUrl` (i.e. `publicOrigin`)\n // is the API host, so we read `MASTRACODE_PUBLIC_URL` and\n // mirror Slack's behavior: when it is unset, pass `null` so\n // the tool is omitted from the toolset rather than fall back\n // to the API/localhost origin and publish that URL into a\n // public review body. The skill's tool-not-available branch\n // handles the absence as stop-don't-publish. Blank counts as\n // unset: `.env.schema` ships `MASTRACODE_PUBLIC_URL=`, so an\n // empty/whitespace value must not register the tool with a\n // hostless `sessionUrl`.\n const reviewSourceUiOrigin = resolveReviewSourceUiOrigin(process.env.MASTRACODE_PUBLIC_URL);\n mergeTools(\n 'factory-review-source',\n await createReviewSourceTool({\n requestContext,\n storage: workItemsStorage,\n uiOrigin: reviewSourceUiOrigin,\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n }),\n );\n if (storage.isDomainReady('source-control')) {\n const scope = await resolveFactoryToolScope({\n requestContext,\n authEnabled: routeAuth.enabled(),\n sessions: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n });\n if (scope) {\n mergeTools(\n 'factory-tools',\n createFactoryTools({\n scope,\n deps: factoryToolDeps,\n }),\n );\n if (sessionRetirement && sandboxConfig && SELF_RECREATE_SANDBOX_PROVIDERS.has(sandboxConfig.provider)) {\n mergeTools(\n 'factory-sandbox-tools',\n createFactorySandboxTools(scope, {\n sessions: sourceControlSessions,\n resetSandbox: input => sessionRetirement.resetSessionSandbox(input),\n }),\n );\n }\n }\n }\n }\n for (const { integration, ready, ensureReady } of toolIntegrations) {\n if (!ready && ensureReady) {\n try {\n await ensureReady();\n } catch {\n continue;\n }\n }\n if (integration.agentTools) {\n mergeTools(integration.id, await integration.agentTools({ requestContext }));\n }\n if (integration.sessionTools) {\n mergeTools(integration.id, integration.sessionTools({ requestContext }));\n }\n }\n return tools;\n },\n postToolObserver: async (toolContext: IntegrationPostToolContext) => {\n const requestContext = (toolContext.context as { requestContext?: RequestContext } | undefined)\n ?.requestContext;\n if (requestContext) {\n await observeAgentGitAction({\n audit: auditDomain,\n toolContext: { ...toolContext, context: requestContext },\n resolveRepositorySlugs: async sessionId => {\n for (const provider of sourceControlToolProviders) {\n const session = await provider.storage.sessions.getBySessionId(sessionId);\n if (!session) continue;\n return environmentSlugs(\n await resolveSessionRepositories({ sourceControl: provider.storage, session }),\n );\n }\n return [];\n },\n });\n }\n await Promise.all(\n integrations.map(async integration => {\n if (!integration.postToolObserver) return;\n try {\n await integration.postToolObserver({ toolContext, requestContext });\n } catch (error) {\n console.warn(`[factory] Integration '${integration.id}' post-tool observer failed:`, error);\n }\n }),\n );\n },\n ...(pubsub ? { pubsub, crossProcessPubSub: true } : {}),\n buildApiRoutes: ({ controller, authStorage }: BuildApiRoutesDeps) => [\n // Public `/auth/*` routes (login/callback/logout/me). Folded in as\n // `apiRoutes` (not plain Hono routes) because the entry can't touch the\n // Hono app the deployer generates. `requiresAuth: false`; the gate\n // skips `/auth/*`. Auth-disabled mode still answers `/auth/me` (404).\n ...(auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : buildAuthDisabledRoutes()),\n ...(mcpEnabled\n ? buildFactoryMcpRoutes({\n auth: routeAuth,\n publicOrigin,\n authorizationServers: mcpAuthorizationServers,\n projects: factoryProjectsStorage,\n sourceControls: sourceControlHandles,\n tools: factoryToolDeps,\n })\n : []),\n ...new TelemetryRoutes({ auth: routeAuth, providerName: auth?.name, publicOrigin, allowedOrigins }).routes(),\n // Custom `/web/*` routes (fs / config / integrations / factory / audit).\n ...assembleFactoryApiRoutes({\n controllerId: CONTROLLER_ID,\n controller,\n liveSessions: liveSessionsTouchingTheFeed(controller, eventBus),\n auth: routeAuth,\n ...(auth && isUserProvider(auth) ? { users: auth } : {}),\n authStorage,\n audit: auditDomain,\n publicOrigin,\n stateSigner,\n sandbox: sandboxConfig,\n ...(environmentBuilds ? { onRepositoryPush: environmentBuilds.onRepositoryPush } : {}),\n sessionRetirement,\n moveThread: async ({ threadId, resourceId }) => {\n // The sessions' own Memory, so a moved thread takes its observation vectors along.\n const sessionMemory = getDynamicMemory(storage.getMastraStorage(), vector);\n await sessionMemory({ requestContext: new RequestContext() }).updateThreadResourceId({\n threadId,\n resourceId,\n });\n await sessionMemory.settled();\n },\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n domains,\n feed: commentsDomain,\n integrations: integrationRegistrations,\n intakeReady,\n factoryReady,\n knowledgeEnabled,\n mcpEnabled,\n deploymentModelProviders,\n knowledgeKey: this.#config.knowledge?.key,\n configVersion,\n boardRegistry: this.#boards,\n factoryTransitionService: transitionService,\n onFactoryRuntime: ({ transitionService: runtimeTransitionService, startCoordinator, prepareBinding }) => {\n this.#startCoordinator = startCoordinator;\n this.#dispatcher ??= new FactoryDecisionDispatcher({\n controller,\n transitionService: runtimeTransitionService,\n storage: storage.getDomain<WorkItemsStorage>('work-items'),\n audit: auditDomain,\n boards: this.#boards,\n maxInFlight: this.#config.dispatcher?.maxInFlight,\n isAutoRunEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoRunEnabled ?? false;\n },\n autoApprovePlans: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoApprovePlans ?? false;\n },\n reconcileToolResults: () => factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n prepareBinding,\n feedReader: new FactoryFeedReader(workItemCommentsStorage),\n ...(githubIntegration\n ? {\n dismissStaleReviews: async decision => {\n await dismissStaleFactoryReviews(\n githubIntegration.versionControl,\n decision,\n login => isFactoryGithubLogin(githubIntegration, login),\n login =>\n trustedCollaborator(githubIntegration, {\n installationId: decision.installationId,\n repository: decision.repository,\n login,\n }),\n );\n },\n }\n : {}),\n primeCredentials: tenant => primeTenantCredentials({ tenant, credentials: modelCredentialsStorage }),\n reportRunEnd: createWorkItemRunEndReporter({\n workItems: storage.getDomain<WorkItemsStorage>('work-items'),\n reporting: factoryReporting,\n }),\n resolveLinkedWorkItemParentId: async ({ orgId, factoryProjectId, decision }) => {\n if (decision.source !== 'github-pr') return null;\n const repositoryId = decision.metadata?.githubRepositoryId;\n const pullRequestNumber = decision.metadata?.githubPullRequestNumber;\n if (typeof repositoryId !== 'number' || typeof pullRequestNumber !== 'number') return null;\n return resolveFactoryPullRequestParentWorkItemId(\n integrationStorage.forIntegration<\n Record<string, unknown>,\n Record<string, unknown>,\n FactoryPullRequestProvenanceData\n >('github'),\n { orgId, factoryProjectId, repositoryId, pullRequestNumber },\n );\n },\n });\n },\n }),\n ...projectRoutes.routes(),\n ...auditDomain.routes(),\n ...commentsDomain.routes(),\n // Connect/reconnect session minting for Platform-managed providers.\n // Server-side because only the deploy holds Platform machine\n // credentials; the SPA runs the OAuth popup with the minted token.\n ...(hasPlatformCredentials()\n ? buildPlatformConnectRoutes({\n auth: routeAuth,\n client: new PlatformApiClient(platformApiClientConfigFromEnv()),\n })\n : []),\n ],\n buildServerConfig: () => {\n // MCP 2026-07-28 clients send `Mcp-*` headers on every request and\n // read the OAuth challenge from `WWW-Authenticate`; the deployer\n // merges these into its default allow/expose lists.\n const mcpCors = {\n allowHeaders: ['Mcp-Protocol-Version', 'Mcp-Method', 'Mcp-Name'],\n exposeHeaders: ['WWW-Authenticate'],\n };\n const cors = {\n cors: allowedOrigins.length ? { origin: allowedOrigins, credentials: true, ...mcpCors } : mcpCors,\n };\n // Log route errors with method/path/stack and answer with structured\n // JSON instead of an opaque `Internal Server Error`. Applied by the\n // deployer to both the top-level app and the custom-route sub-app.\n const onError = { onError: handleServerError };\n // Same-origin SPA: when a vite build is present (see resolveUiDistDir),\n // serve it at `/` from this server. Mounted last so the auth gate (when\n // enabled) covers it; it always passes `/api`, `/web`, `/auth` through.\n const uiDist = resolveUiDistDir();\n const spa = uiDist ? [createSpaStaticMiddleware(uiDist)] : [];\n const timing = factoryTimingEnabled ? [createRequestTimingMiddleware()] : [];\n if (!auth) {\n // Auth disabled: no gate. Still prime the sentinel-local custom\n // provider snapshot so model calls see DB rows, then SPA + CORS.\n return {\n middleware: [\n ...timing,\n createFactoryInteractiveMarker(),\n createCustomProvidersPrimer({ auth: routeAuth, storage: customProvidersStorage, authEnabled: false }),\n ...spa,\n ],\n ...cors,\n ...onError,\n };\n }\n\n // Ordered middleware. The deployer applies these AFTER its context\n // middleware sets `c.set('mastra', mastra)` and BEFORE routes, so:\n // 1. gate — validates the auth session, stashes the user, and 401s /\n // redirects unauthenticated requests. Skips public `/auth/*`.\n // 2. access — 404s requests addressing another user's private session.\n // 3. primers — hydrate the caller's model-credential and custom\n // provider snapshots so the request's first model call\n // resolves tenant credentials and custom providers.\n // 4. spa — serves the built UI for everything the server doesn't own.\n // `auth` also lands on `server.auth` so the core auth middleware (and\n // Studio's dual-auth routing — see `studio.auth` on the returned args)\n // authenticates core `/api/*` routes with the same provider.\n return {\n auth,\n middleware: [\n ...timing,\n createFactoryAuthGate(auth),\n createSessionAccessGuard({\n auth: routeAuth,\n sessions: sourceControlSessions,\n projects: {\n get: async args => {\n if (!storage.isDomainReady('projects')) return null;\n await factoryProjectsStorage.ensureReady();\n return factoryProjectsStorage.get(args);\n },\n },\n controller: () => this.#prepared?.base.controller,\n }),\n createTenantCredentialPrimer({ auth: routeAuth, credentials: modelCredentialsStorage }),\n createCustomProvidersPrimer({\n auth: routeAuth,\n storage: customProvidersStorage,\n authEnabled: Boolean(auth),\n }),\n ...spa,\n ],\n ...cors,\n ...onError,\n };\n },\n }),\n );\n\n const notifyApprovalRequested = createSessionApprovalNotifier(sessionReports);\n prepared.base.controller.onSessionCreated(session => {\n observeSessionFilesystem(session, {\n filesystem: filesystemStorage,\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionFirstMessage(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionFirstExec(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionThreadTitle(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionRunEnd(session, { audit: auditDomain });\n // Every run end of a work or side session, and every tool call it holds for\n // approval, reaches whoever follows it, however the run started;\n // re-attached when a session is created again.\n observeSessionRunReports(\n session,\n (outcome, since) =>\n reportSessionRunEnd({\n sessionId: session.identity.getId(),\n threadId: session.thread.getId(),\n outcome,\n since,\n }),\n {\n onApprovalRequested: request =>\n notifyApprovalRequested({\n sessionId: session.identity.getId(),\n threadId: session.thread.getId(),\n ...request,\n }),\n },\n );\n observeSessionThreadStamp(session);\n });\n\n // Blocking: `createSession` awaits the organization seed so per-invocation\n // memory settings and knowledge capture use the correct tenant immediately.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionMemorySettings(session, {\n sourceControl: { sessions: sourceControlSessions },\n }),\n { blocking: true },\n );\n\n // Personal default models seed interactive user sessions only. Active Factory\n // run bindings are excluded and continue to use the project default model.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionDefaultModel(session, {\n sourceControl: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n modelDefaults: modelDefaultsStorage,\n }),\n { blocking: true },\n );\n\n // Factory tools fall in the SDK's `mcp` category (default `ask`); allow the\n // no-approval ones per session before the session's first turn.\n prepared.base.controller.onSessionCreated(\n session => applyFactoryToolPermissions(session, { sessions: sourceControlSessions }),\n { blocking: true },\n );\n\n this.#prepared = prepared;\n this.#factoryProcessor = factoryProcessor;\n\n // Chat-platform channels (Slack, Discord, …) contributed by integrations,\n // attached to the mounted controller so inbound platform messages reach\n // the same agents the web UI drives. READY integrations only — readiness\n // means the `channel-identity` domain's `init()` succeeded, so its link\n // table is queryable. Without it a sender can't be resolved to a tenant,\n // and attaching anyway would dispatch runs on default credentials.\n const channelRegistrations = integrationRegistrations.filter(\n ({ integration, ready }) => ready && integration.channels,\n );\n // `setChannels` replaces rather than merges, so a second provider would\n // silently never receive a message. Fail loud instead.\n if (channelRegistrations.length > 1) {\n throw new Error(\n `MastraFactory: integrations [${channelRegistrations\n .map(({ integration }) => integration.id)\n .join(', ')}] all provide channels, but only one may. Remove all but one.`,\n );\n }\n for (const { integration } of channelRegistrations) {\n const context = buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n // Integrations return a channels CONFIG; the factory owns construction.\n prepared.base.controller.setChannels(new AgentControllerChannels(integration.channels!(context)));\n }\n\n // Feed publishers mirror web-feed comments outward (a chat bridge, a\n // webhook, an issue tracker). Independent of channels(): an integration may\n // publish without owning a chat channel. READY integrations only — the\n // array is held by reference by CommentsDomain (see `feedPublishers` above),\n // so pushing here wires the publisher into comment dispatch.\n for (const { integration } of integrationRegistrations.filter(\n ({ integration, ready }) => ready && integration.feedPublisher,\n )) {\n const context = buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n const publisher = integration.feedPublisher!(context);\n if (publisher) feedPublishers.push(publisher);\n }\n\n // Integration lifecycle workers (e.g. polling an upstream without\n // webhooks): collected from READY integrations only, folded into the\n // constructor args so `new Mastra(...)` merges them with the default\n // workers and `finalize()`'s `startWorkers()` starts them alongside the\n // built-ins. Never passed for the disabled/not-ready case — a worker for\n // an unavailable integration must not run.\n const integrationWorkers = integrationRegistrations\n .filter(({ integration, ready }) => ready && integration.workers)\n .flatMap(({ integration }) =>\n integration.workers!(\n buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n ),\n ),\n );\n\n return {\n ...prepared.mastraArgs,\n // Same provider on `studio.auth` as on `server.auth` (buildServerConfig):\n // deployed factories must authenticate BOTH plain API callers and Studio\n // requests (`x-mastra-client-type: studio` routes to `studio.auth`).\n ...(auth ? { studio: { auth } } : {}),\n ...(integrationWorkers.length > 0 ? { workers: integrationWorkers } : {}),\n ...(environmentBuilds ? { workflows: { [ENVIRONMENT_BUILD_WORKFLOW_ID]: environmentBuilds.workflow } } : {}),\n };\n }\n\n /**\n * Post-construct boot: initialize the controller (which inherits the\n * constructed Mastra's storage) and start its workers. Call AFTER the entry\n * has run `new Mastra(prepare()'s args)`.\n */\n async finalize(): Promise<void> {\n if (!this.#prepared) {\n throw new Error('MastraFactory.finalize() called before prepare()');\n }\n await timedPhase('finalize.controller', () => this.#prepared!.finalize());\n await this.#environmentBuilds?.probeSchedules();\n await timedPhase(\n 'finalize.reconcileBoundThreads',\n () => this.#factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n );\n // A thread's messages move before its run binding does, so a reconcile that\n // overlapped the migration can miss them. Catch up once the bindings moved.\n void this.#sessionResourceMigration\n ?.then(movedRunBindings => (movedRunBindings ? this.#factoryProcessor?.reconcileAllBoundThreads() : undefined))\n .catch(error =>\n console.warn(\n `[factory] reconciling bound threads after the session resource migration failed: ${error instanceof Error ? error.message : error}`,\n ),\n );\n this.#dispatcher?.start();\n }\n\n /** Stop Factory-owned background dispatch before the host process shuts down. */\n async shutdown(): Promise<void> {\n await this.#dispatcher?.stop();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"factory.js","names":[],"sources":["../src/factory.ts"],"sourcesContent":["/**\n * `MastraFactory` — the single entry point to the whole Mastra Software Factory.\n *\n * The consumer's deploy entry constructs deployment-specific config instances\n * (auth adapter, pubsub) and passes them here explicitly. The only provider\n * defaults constructed here are Platform GitHub, GitLab, Jira, incident.io, and\n * Linear integrations when Platform credentials exist and the caller did not\n * provide those integrations.\n *\n * `prepare()` resolves feature readiness, threads every dependency explicitly,\n * assembles the web routes/middleware, and returns the constructor args for\n * `new Mastra(...)`. The literal `export const mastra = new Mastra(...)` must\n * stay in the entry file — the deployer's `checkConfigExport` Babel plugin\n * only marks the config valid when it finds that literal in the entry AST —\n * so the factory produces args instead of the instance. `finalize()` runs the\n * post-construct boot (controller init + workers).\n *\n * Integration readiness is derived from each instance's declared capabilities\n * and the storage domains those capabilities require.\n */\n\nimport { MastraAuthStudio } from '@mastra/auth-studio';\nimport { prepareAgentControllerMount } from '@mastra/code-sdk';\nimport { getDynamicMemory } from '@mastra/code-sdk/agents/memory';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentControllerRequestContext, BuiltinToolId } from '@mastra/core/agent-controller';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport { AgentControllerChannels } from '@mastra/core/channels';\nimport { EventEmitterPubSub } from '@mastra/core/events';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Knowledge } from '@mastra/core/knowledge';\nimport type { Mastra } from '@mastra/core/mastra';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { hasAuthInit, isUserProvider } from '@mastra/core/server';\nimport type { IMastraAuthProvider } from '@mastra/core/server';\nimport type { FactoryStorage } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { describeFactorySandbox, isFactorySandbox } from '@mastra/core/workspace';\nimport type { FactorySandbox, FactorySandboxDescription, WorkspaceSandbox } from '@mastra/core/workspace';\nimport {\n buildAuthDisabledRoutes,\n buildAuthRoutes,\n createFactoryAuthGate,\n createFactoryInteractiveMarker,\n createFactoryRouteAuth,\n getFactoryAuthOrgId,\n getFactoryAuthUserFromContext,\n getFactoryAuthUserId,\n} from './auth.js';\nimport { createBoardRegistry, isTerminalWorkItem } from './boards/index.js';\nimport type { BoardRegistry, InstalledBoard } from './boards/index.js';\nimport { boardForWorkItem } from './boards/semantics.js';\nimport { EnvironmentBuildRunner } from './environment/build-runner.js';\nimport { ENVIRONMENT_BUILD_WORKFLOW_ID } from './environment/build-workflow.js';\nimport { touchFeed } from './feed-events.js';\nimport type { FactoryIntegration, IntegrationPostToolContext, IntegrationTools } from './integrations/base.js';\nimport { reconcileGithubAcceptanceLabels } from './integrations/github/acceptance-labels.js';\nimport type { GithubRuleOverrides } from './integrations/github/default-rules.js';\nimport type { GithubIntegration } from './integrations/github/integration.js';\nimport {\n recordFactoryPullRequestProvenance,\n resolveFactoryPullRequestParentWorkItemId,\n} from './integrations/github/provenance.js';\nimport type { FactoryPullRequestProvenanceData } from './integrations/github/provenance.js';\nimport { isFactoryGithubLogin, trustedCollaborator } from './integrations/github/rules.js';\nimport { dismissStaleFactoryReviews } from './integrations/github/stale-reviews.js';\nimport type { GitLabIntegrationBase } from './integrations/gitlab/integration.js';\nimport { PlatformApiClient, platformApiClientConfigFromEnv } from './integrations/platform/api-client.js';\nimport { buildPlatformConnectRoutes } from './integrations/platform/connect/routes.js';\nimport { createSessionAsRowOwner, prepareSessionRunContext } from './integrations/subscription-session.js';\nimport { buildFactoryMcpRoutes, resolveMcpAuthorizationServers } from './mcp/routes.js';\nimport type { FactoryMcpConfig } from './mcp/routes.js';\nimport { resolveDeploymentModelProviders } from './routes/config.js';\nimport {\n createCustomProvidersPrimer,\n primeCustomProvidersForRequestContext,\n registerCustomProvidersSource,\n} from './routes/custom-provider-source.js';\nimport { ProjectRoutes } from './routes/projects.js';\nimport { tenantOrgId } from './routes/provider-credentials.js';\nimport { createSessionAccessGuard } from './routes/session-access.js';\nimport { assembleFactoryApiRoutes, buildIntegrationContext } from './routes/surface.js';\nimport type { FactoryApiRoutesDeps } from './routes/surface.js';\nimport { TelemetryRoutes } from './routes/telemetry.js';\nimport {\n createTenantCredentialPrimer,\n primeTenantCredentials,\n registerTenantCredentialResolver,\n} from './routes/tenant-credentials.js';\nimport { readFactorySessionScope, resolveFactorySessionAddress } from './rules/binding-context.js';\nimport { FactoryDecisionDispatcher } from './rules/dispatcher.js';\nimport type { FactoryRuleActor } from './rules/index.js';\nimport { FactoryPhaseStateProcessor, reportMemorySettingsUnavailable } from './rules/processor.js';\nimport { createReviewSourceTool, resolveReviewSourceUiOrigin } from './rules/review-source-tool.js';\nimport type { FactoryStartCoordinator } from './rules/start-coordinator.js';\nimport { createTerminalStageCleanup } from './rules/terminal-cleanup.js';\nimport { createFactoryTransitionTools } from './rules/tools.js';\nimport { FactoryTransitionService } from './rules/transition-service.js';\nimport { assertFactoryConfigVersion, DEFAULT_FACTORY_CONFIG_VERSION } from './rules/validation.js';\nimport { CallbackFactorySandbox } from './sandbox/callback-factory-sandbox.js';\nimport { isValidGitRef } from './sandbox/git-ref.js';\nimport { LocalFactorySandbox } from './sandbox/local-factory-sandbox.js';\nimport { SessionRetirementCoordinator } from './sandbox/session-retirement.js';\nimport type { MastraFactorySandboxOption } from './sandbox/session-sandbox.js';\nimport { createPlaintextFactorySecretEncryption } from './secret-encryption.js';\nimport type { FactorySecretEncryption } from './secret-encryption.js';\nimport { handleServerError } from './server-error.js';\nimport { resolveFactoryCredentialTenant, resolveFactoryModelPolicy } from './session/credential-policy.js';\nimport { hydrateSessionDefaultModel } from './session/default-model-hydration.js';\nimport { environmentSlugs, resolveSessionRepositories } from './session/environment-repositories.js';\nimport { FactoryEnvironmentStateProcessor } from './session/environment-state-processor.js';\nimport { createSourceControlSessionLookup } from './session/factory-session.js';\nimport { observeSessionFilesystem } from './session/filesystem-capture.js';\nimport { observeSessionFirstExec } from './session/first-exec-capture.js';\nimport { observeSessionFirstMessage } from './session/first-message-capture.js';\nimport { LiveSessions } from './session/live-sessions.js';\nimport { hydrateSessionMemorySettings } from './session/memory-settings-hydration.js';\nimport { hasResolvedOrg } from './session/org-seed.js';\nimport { FactoryReplyCredentialProcessor } from './session/reply-credential-processor.js';\nimport { migrateSessionResources, privatizeOwnerResourceSessions } from './session/resource-migration.js';\nimport { observeSessionRunEnd } from './session/run-audit.js';\nimport { sessionMemoryResourceId, sessionStampCounts } from './session/session-threads.js';\nimport { createSourceControlTools } from './session/source-control-tools.js';\nimport { resolveFactoryThinkingLevel } from './session/thinking-default.js';\nimport { observeSessionThreadStamp } from './session/thread-session-stamp.js';\nimport { observeSessionThreadTitle } from './session/thread-title-mirror.js';\nimport { createSpaStaticMiddleware, resolveUiDistDir } from './spa-static.js';\nimport { createStateSigner } from './state-signing.js';\nimport { observeAgentGitAction } from './storage/domains/audit/agent-audit.js';\nimport { AuditStorage } from './storage/domains/audit/base.js';\nimport { AuditDomain } from './storage/domains/audit/domain.js';\nimport { ChannelIdentityStorage } from './storage/domains/channel-identity/base.js';\nimport { WorkItemCommentsStorage } from './storage/domains/comments/base.js';\nimport { CommentsDomain } from './storage/domains/comments/domain.js';\nimport { FactoryFeedReader } from './storage/domains/comments/feed-context.js';\nimport type { WorkItemFeedPublisher } from './storage/domains/comments/feed-sync.js';\nimport { ModelCredentialsStorage } from './storage/domains/credentials/base.js';\nimport { CustomProvidersStorage } from './storage/domains/custom-providers/base.js';\nimport { FilesystemStorage } from './storage/domains/filesystem/base.js';\nimport { IntakeStorage } from './storage/domains/intake/base.js';\nimport { IntegrationStorage } from './storage/domains/integrations/base.js';\nimport { factoryMemorySettingsUserId, MemorySettingsStorage } from './storage/domains/memory-settings/base.js';\nimport { ModelDefaultsStorage } from './storage/domains/model-defaults/base.js';\nimport { FactoryProjectsStorage } from './storage/domains/projects/base.js';\nimport { QueueHealthStorage } from './storage/domains/queue-health/base.js';\nimport { SourceControlStorage } from './storage/domains/source-control/base.js';\nimport { WorkItemsStorage } from './storage/domains/work-items/base.js';\nimport type { FactoryRunBindingRecord, WorkItemRow } from './storage/domains/work-items/base.js';\nimport { createRequestTimingMiddleware, factoryTimingEnabled, instrumentAsyncMethods, timedPhase } from './timing.js';\nimport { deliverFactorySessionNotification } from './tools/deliver.js';\nimport { applyFactoryToolPermissions, createFactoryTools, resolveFactoryToolScope } from './tools/index.js';\nimport type { FactoryToolDependencies } from './tools/index.js';\nimport {\n createSessionApprovalNotifier,\n createSessionRunEndReporter,\n createStageChangeNotifier,\n createWorkItemRunEndReporter,\n} from './tools/reports.js';\nimport type { FactoryReporting } from './tools/reports.js';\nimport { observeSessionRunReports } from './tools/run-watch.js';\nimport { createFactorySandboxTools } from './tools/sandbox-tools.js';\nimport { FactorySessionsStateProcessor } from './tools/sessions-state-processor.js';\nimport { createWorkspaceFactory, FactoryWorkspaceRegistry } from './workspace.js';\nimport type { FactorySandboxStart } from './workspace.js';\n\ntype BuildApiRoutesDeps = Pick<FactoryApiRoutesDeps, 'controller' | 'authStorage'>;\n\n/** Constructor args for the `new Mastra(...)` literal in the deploy entry. */\nexport type MastraArgs = NonNullable<ConstructorParameters<typeof Mastra>[0]>;\n\nexport interface MastraFactoryConfig {\n /**\n * Auth provider instance — `MastraAuthStudio` (`@mastra/auth-studio`),\n * `MastraAuthWorkos` (`@mastra/auth-workos`), `MastraAuthBetterAuth`\n * (`@mastra/auth-better-auth`), or any custom `MastraAuthProvider`. Whatever\n * instance is passed is the active provider; a passed instance is always\n * honored as-is.\n *\n * Omitted → the factory defaults to `MastraAuthStudio`, proxying auth\n * through the shared Mastra platform API. `MastraAuthStudio` resolves its\n * own env (`MASTRA_SHARED_API_URL`, `MASTRA_ORGANIZATION_ID`,\n * `MASTRA_COOKIE_DOMAIN`).\n *\n * Pass `null` to disable auth entirely (open server, local-dev behavior)\n * without falling back to the default.\n */\n auth?: IMastraAuthProvider | null;\n /**\n * REQUIRED. Factory storage backend powering BOTH agent storage (threads,\n * messages, memory, OM — via `getMastraStorage()`) and the app tables\n * (projects/source-control/audit/intake — via the generic ops surface). Pass a\n * `PgFactoryStorage` (`@mastra/pg`) for deployments or a\n * `LibSQLFactoryStorage` (`@mastra/libsql`) for local dev — one backend,\n * one connection, every feature on.\n */\n storage: FactoryStorage;\n /**\n * Vector store instance for recall search — `PgVector` (`@mastra/pg`) on\n * the same database as `storage`. Omitted → the SDK mount's default vector\n * store resolution applies.\n */\n vector?: MastraVector;\n /**\n * Host-owned Knowledge runtime. Factory registers this exact instance under `key` and uses that\n * key for its read surfaces. Omitted leaves Mastra Code's experimental default wiring in place.\n */\n knowledge?: { key: string; instance: Knowledge };\n /**\n * Distributed event bus instance (e.g. `new RedisStreamsPubSub({ url })`).\n * When set, streams/workflows/signals ride it across processes and the\n * controller drops file-based thread locks in favor of pubsub-coordinated\n * leases. Omitted → in-process default.\n */\n pubsub?: PubSub;\n /**\n * Browser-facing origin used to build integration OAuth/install callback\n * URLs and to derive the auth redirect URI. On the platform the SPA is\n * hosted separately, so this MUST be the public API origin.\n * Default: `http://localhost:4111` (the local Factory server, which also\n * serves the UI).\n */\n publicUrl?: string;\n /**\n * The Factory MCP server at `/web/factory/projects/:projectId/mcp`, which lets\n * MCP clients such as ChatGPT use the Factory tools as the signed-in user.\n * On by default with Mastra Platform auth; other providers need\n * `authorizationServers` set. Pass `false` to turn it off.\n */\n mcp?: false | FactoryMcpConfig;\n /**\n * Allowed cross-origin SPA origins. The SPA may be served from a separate\n * static host, so credentialed requests must be explicitly allowed.\n */\n allowedOrigins?: string[];\n /**\n * The host's sandbox: a FactorySandbox instance such as\n * `new PlatformFactorySandbox({ ... })`, which owns the session sandbox\n * constructor, the repo template and the schema of environment settings.\n * A bare callback is also accepted and wrapped as a `provider: 'custom'`\n * sandbox with no settings. Omitted with Platform credentials → the factory\n * installs a `LocalFactorySandbox` under `mastra dev` and a\n * `PlatformFactorySandbox` in built deployments. Omitted without Platform\n * credentials → repository sandboxes are disabled.\n */\n sandbox?: MastraFactorySandboxOption;\n /** Browser automation provider for Factory agent sessions. */\n browser?: MastraBrowser;\n /**\n * When a session's sandbox boots: on the agent's first command (`'lazy'`,\n * the default) or as soon as the session's workspace is first resolved\n * (`'eager'`), so the boot overlaps the model's own latency.\n */\n sandboxStart?: FactorySandboxStart;\n /**\n * Agent controller built-in tools (e.g. `submit_plan`) removed from every\n * Factory session, along with their prompt guidance. Use this when a custom\n * board gates planning with its own phase transition, so the in-session plan\n * approval cannot bypass that gate.\n */\n disableBuiltinTools?: BuiltinToolId[];\n /** Background Factory dispatcher configuration. */\n dispatcher?: MastraFactoryDispatcherConfig;\n /**\n * Deployment-stable secret for signing integration OAuth `state` values.\n * Omitted → a per-process random secret, which is fine for single-process\n * local development but rejected for integrations that declare\n * `requiresStableStateSigner`.\n */\n stateSecret?: string;\n /**\n * Encryption boundary for persisted model credentials, custom-provider API\n * keys, integration connections, and integration settings. Strongly\n * recommended whenever auth is enabled — omitting it falls back to explicit\n * plaintext compatibility with a boot-time warning.\n */\n secretEncryption?: FactorySecretEncryption;\n /**\n * Model providers that authenticate with the server process's own\n * credentials instead of per-account credentials. With auth enabled, these\n * providers are only usable when listed here; the stored-key flow is never\n * offered for them. Supported: `'amazon-bedrock'` (AWS credential chain —\n * `AWS_BEARER_TOKEN_BEDROCK` or access keys/profile/role plus `AWS_REGION`).\n * Every signed-in account can then run these models on the deployment's\n * credentials. Default: none.\n */\n deploymentModelProviders?: readonly string[];\n /**\n * Registered capability providers. The factory registers the pieces each\n * `FactoryIntegration` instance provides — HTTP routes, storage domains,\n * agent/session tools, intake, source control, and diagnostics — into the\n * system. When Platform credentials are configured, missing `github`,\n * `gitlab`, and `linear` integrations default to their Platform-backed\n * implementations. Missing `jira` and `incidentio` integrations also default\n * to their Platform-backed implementations, which discover visible `jira` and\n * `incident-io` connections at runtime.\n */\n integrations?: FactoryIntegration[];\n /**\n * Operator-maintained provenance label stamped on transition audit rows,\n * deferred decisions, and session kickoff headers so a row can be traced\n * back to the deployment that produced it. Nothing branches on it.\n * Default: `factory-config-v1`.\n */\n configVersion?: string;\n /** Board definitions installed for this Factory instance. */\n boards?: readonly InstalledBoard[];\n /** Whether the built-in Work and Review boards are installed. Default: true. */\n includeDefaultBoards?: boolean;\n\n /**\n * Platform-specific overrides.\n */\n platform?: {\n /** Identifies Factory's own GitHub App writes so their webhook deliveries do not retrigger triage. */\n githubAppSlug?: string;\n /**\n * Overrides for the `PlatformGithubIntegration` the factory installs itself\n * when Platform credentials are present; these options are forwarded to its\n * constructor. An explicit integration with id `github` in `integrations`\n * takes precedence and makes this key a no-op, so the two are not meant to\n * be used together.\n */\n github?: {\n /** Replace an event handler, or disable it with null; omitted events keep defaults. */\n rules?: GithubRuleOverrides;\n /**\n * GitHub App slug used to recognize Factory's own webhook writes. Falls\n * back to `githubAppSlug` when omitted.\n */\n slug?: string;\n };\n };\n}\n\nexport type { MastraFactorySandboxConfig, MastraFactorySandboxOption } from './sandbox/session-sandbox.js';\nexport type { FactorySandboxStart } from './workspace.js';\n\n/**\n * Per-process cap on concurrent background Factory dispatches. Omitted means\n * the dispatcher default; this is a local replica budget, not a global queue\n * limit shared across deployments.\n */\nexport interface MastraFactoryDispatcherConfig {\n maxInFlight?: number;\n}\n\nconst CONTROLLER_ID = 'code';\n\n/**\n * Providers whose sandbox a session's agent may recreate itself. Each needs\n * its `destroy()` to leave the instance able to start a fresh VM, proven\n * against the real provider.\n */\nconst SELF_RECREATE_SANDBOX_PROVIDERS: ReadonlySet<string> = new Set(['platform']);\n\n/** Why a wake couldn't be run as its Factory session's owner. */\nconst WAKE_OWNER_UNRESOLVED = {\n 'session-not-found': 'no Factory session row names its owner',\n 'organization-unresolved': \"its owner's organization is unresolved\",\n 'organization-mismatch': \"its owner's organization doesn't match\",\n} as const;\n\nfunction hasPlatformCredentials(): boolean {\n // MASTRA_PLATFORM_ACCESS_TOKEN is the credential Mastra Platform injects\n // into deployed projects; MASTRA_PLATFORM_SECRET_KEY is the org secret key\n // written by project scaffolding. Either enables the platform integrations.\n return Boolean(process.env.MASTRA_PLATFORM_ACCESS_TOKEN?.trim() || process.env.MASTRA_PLATFORM_SECRET_KEY?.trim());\n}\n\n/**\n * The sandbox the factory installs when the host passes none and Platform\n * credentials are present: a local sandbox under `mastra dev` (or\n * NODE_ENV=development), so development never boots remote machines, and\n * a Platform sandbox in built deployments. Without credentials, sandboxes\n * stay disabled.\n */\nasync function platformDefaultSandbox(): Promise<FactorySandbox | undefined> {\n if (!hasPlatformCredentials()) return undefined;\n if (process.env.MASTRA_DEV === 'true' || process.env.NODE_ENV === 'development') {\n return new LocalFactorySandbox();\n }\n const missing = ['MASTRA_PROJECT_ID', 'MASTRA_ENVIRONMENT_ID'].filter(key => !process.env[key]?.trim());\n if (missing.length > 0) {\n console.warn(\n `MastraFactory: Platform credentials are set but ${missing.join(' and ')} ${missing.length > 1 ? 'are' : 'is'} missing, so no Platform sandbox was installed and repository sandboxes are disabled.`,\n );\n return undefined;\n }\n const { PlatformFactorySandbox } = await import('@mastra/platform-workspace');\n return new PlatformFactorySandbox();\n}\n\n/**\n * Default auth provider — `MastraAuthStudio`, which proxies identity to the\n * shared Mastra platform API and resolves its own env (`MASTRA_SHARED_API_URL`,\n * `MASTRA_ORGANIZATION_ID`, ...).\n *\n * The session cookie is **host-only** (`__Host-wos-session` on secure\n * deployments). No parent `Domain` (e.g. `.mastra.cloud`) is derived from\n * `publicUrl`: a parent-scoped session cookie is sent by the browser to every\n * host under that parent, including other tenants' deployments. Callers that\n * really want a domain-scoped cookie pass their own `MastraAuthStudio` (with\n * `cookieDomain`) via `auth:`.\n */\nfunction buildDefaultStudioAuth(): IMastraAuthProvider {\n return new MastraAuthStudio();\n}\n\n/** A session parking or being answered is inbox news, so the registry bumps the project's feed. */\nfunction liveSessionsTouchingTheFeed(controller: BuildApiRoutesDeps['controller'], eventBus: PubSub): LiveSessions {\n const liveSessions = new LiveSessions(controller);\n liveSessions.onParkedChanged(session => {\n const { factoryOrgId, factoryProjectId } = session.state.get();\n if (factoryOrgId && factoryProjectId) touchFeed(eventBus, { orgId: factoryOrgId, factoryProjectId });\n });\n return liveSessions;\n}\n\n/**\n * The fleet-era `sandbox` options and what replaced each one. Only the keys\n * the host actually passed are explained, so a host that never used the fleet\n * gets the short message.\n */\nconst RETIRED_SANDBOX_OPTIONS: Record<string, string> = {\n machine:\n \"'machine' becomes the provider instance: one sandbox per session, constructed by the FactorySandbox, instead of one template machine cloned per repository\",\n workdir:\n \"'workdir' becomes the workingDirectory of the FactorySandboxContext, which every provider passes to its sandbox; when it is absent the provider uses its own default\",\n maxSandboxes: \"'maxSandboxes' is gone with the sandbox fleet: there is one sandbox per session and no pool to cap\",\n};\n\nfunction invalidSandboxOptionMessage(option: unknown): string {\n const lines = [\n `MastraFactory: 'sandbox' must be a FactorySandbox instance or a callback constructing a MastraSandbox from a FactorySandboxContext:`,\n ` sandbox: new PlatformFactorySandbox()`,\n ` sandbox: ctx => new PlatformSandbox({ id: ctx.sessionId, sandboxId: ctx.sandboxId })`,\n ];\n if (typeof option === 'object' && option !== null) {\n const retired = Object.keys(RETIRED_SANDBOX_OPTIONS).filter(key => key in option);\n if (retired.length > 0) {\n lines.push(`The object you passed is the retired alpha sandbox config. Its options map as follows:`);\n for (const key of retired) lines.push(` ${RETIRED_SANDBOX_OPTIONS[key]}.`);\n }\n }\n return lines.join('\\n');\n}\n\nexport class MastraFactory {\n readonly #config: MastraFactoryConfig;\n /** The normalized sandbox, set by `prepare()`. Undefined until then and when sandboxes are disabled. */\n #sandbox: FactorySandbox | undefined;\n #sandboxDescription: FactorySandboxDescription | undefined;\n readonly #boards: BoardRegistry;\n readonly #configVersion: string;\n #prepared: Awaited<ReturnType<typeof prepareAgentControllerMount>> | undefined;\n #dispatcher: FactoryDecisionDispatcher | undefined;\n #startCoordinator: FactoryStartCoordinator | undefined;\n #factoryProcessor: FactoryPhaseStateProcessor | undefined;\n #channelShutdowns: Array<() => Promise<void>> = [];\n #shutdownPromise: Promise<void> | undefined;\n /** Environment builds through the sandbox's `builds`; undefined when the sandbox has none. */\n #environmentBuilds: EnvironmentBuildRunner | undefined;\n /** The background session resource migration; resolves `true` when it moved run bindings. */\n #sessionResourceMigration: Promise<boolean> | undefined;\n #preparing = false;\n\n constructor(config: MastraFactoryConfig) {\n if (!config?.storage) {\n throw new Error(\n \"MastraFactory: 'storage' is required. Pass a FactoryStorage backend — e.g. \" +\n \"new PgFactoryStorage({ connectionString }) from '@mastra/pg' for deployments, or \" +\n \"new LibSQLFactoryStorage({ url }) from '@mastra/libsql' for local dev.\",\n );\n }\n this.#boards = createBoardRegistry({\n boards: config.boards,\n includeDefaultBoards: config.includeDefaultBoards,\n });\n if ('rules' in config) {\n throw new Error(\n \"MastraFactory: 'rules' was removed. Set 'configVersion' for the audit label and declare tool-result \" +\n 'rules on the owning board via defineBoard({ tools }).',\n );\n }\n this.#configVersion = assertFactoryConfigVersion(config.configVersion ?? DEFAULT_FACTORY_CONFIG_VERSION);\n this.#config = config;\n }\n\n /**\n * The host sandbox's provider, settings schema (JSON Schema) and\n * capabilities, as the environment route reports them. Undefined before\n * `prepare()` and when sandboxes are disabled.\n */\n get sandboxDescription(): FactorySandboxDescription | undefined {\n if (!this.#sandbox) return undefined;\n this.#sandboxDescription ??= describeFactorySandbox(this.#sandbox);\n return this.#sandboxDescription;\n }\n\n /**\n * Resolve feature readiness, wire every dependency explicitly, and assemble\n * everything needed to construct the server-owned Mastra. Returns the args\n * for the `new Mastra(...)` literal that must live in the entry file.\n */\n async prepare(): Promise<MastraArgs> {\n // Guard set synchronously (before the first await) so overlapping calls —\n // not just strictly sequential ones — can't double-seed the runtime\n // registry or double-run one-time adapter init.\n if (this.#preparing) throw new Error('MastraFactory.prepare() called twice');\n this.#preparing = true;\n\n const publicOrigin = (this.#config.publicUrl ?? 'http://localhost:4111').replace(/\\/+$/, '');\n const allowedOrigins = (this.#config.allowedOrigins ?? []).map(o => o.replace(/\\/+$/, '')).filter(Boolean);\n const storage = instrumentAsyncMethods(this.#config.storage, 'storage');\n const vector = this.#config.vector;\n const pubsub = this.#config.pubsub;\n // One bus for feed/attention events: a second fallback instance would leave\n // SSE subscribers and producers on different emitters in single-process runs.\n const eventBus = pubsub ?? new EventEmitterPubSub();\n // Default auth: honor an explicitly-passed provider (including `null` to\n // disable auth) as-is; otherwise fall back to `MastraAuthStudio`\n // (platform-proxied identity). The default derives its cookie domain\n // from `publicUrl` — deploys on `<sub>.mastra.cloud` mint parent-domain\n // cookies without the caller wiring `MASTRA_COOKIE_DOMAIN` explicitly.\n const configuredAuth = this.#config.auth;\n const auth: IMastraAuthProvider | undefined =\n configuredAuth === null ? undefined : (configuredAuth ?? buildDefaultStudioAuth());\n if (auth && !this.#config.secretEncryption) {\n console.warn(\n \"[factory] auth is enabled but 'secretEncryption' is not configured. Persisted model credentials, \" +\n 'custom-provider API keys, and integration secrets will be stored as plaintext. Provide ' +\n \"'secretEncryption' (e.g. via FACTORY_CREDENTIAL_ENCRYPTION_KEY) to encrypt them at rest.\",\n );\n }\n const secretEncryption = this.#config.secretEncryption ?? createPlaintextFactorySecretEncryption();\n const deploymentModelProviders = resolveDeploymentModelProviders(this.#config.deploymentModelProviders);\n // One RouteAuth seam per boot, closed over the resolved provider. Every\n // factory route module receives this handle — no service locator.\n const routeAuth = createFactoryRouteAuth(auth);\n const mcpConfig = this.#config.mcp;\n const mcpAuthorizationServers =\n mcpConfig === false || mcpConfig?.enabled === false ? [] : resolveMcpAuthorizationServers(auth?.name, mcpConfig);\n // The MCP endpoint authenticates callers itself, so it needs an auth\n // provider and somewhere for clients to get tokens.\n const mcpEnabled = Boolean(auth) && mcpAuthorizationServers.length > 0;\n\n // Explicit integrations win. Platform credentials fill only missing\n // provider slots so callers can override each integration independently.\n const integrations = [...(this.#config.integrations ?? [])];\n const explicitGithub = integrations.some(integration => integration.id === 'github');\n // Whether this boot constructed the GitHub integration on the caller's\n // behalf — `platform.github` is only meaningful in that case.\n let installedPlatformGithub = false;\n if (hasPlatformCredentials()) {\n if (!explicitGithub) {\n // Forward `platform.github` to the integration the factory installs\n // itself. `slug` falls back to the sibling `githubAppSlug` so existing\n // deploys keep working; the constructor validates and freezes `rules`,\n // so invalid ones fail boot.\n const { PlatformGithubIntegration } = await import('./integrations/platform/github/integration.js');\n integrations.push(\n new PlatformGithubIntegration({\n rules: this.#config.platform?.github?.rules,\n slug: this.#config.platform?.github?.slug ?? this.#config.platform?.githubAppSlug,\n }),\n );\n installedPlatformGithub = true;\n }\n if (!integrations.some(integration => integration.id === 'incidentio')) {\n const { PlatformIncidentioIntegration } = await import('./integrations/platform/incidentio/integration.js');\n integrations.push(new PlatformIncidentioIntegration());\n }\n if (!integrations.some(integration => integration.id === 'jira')) {\n const { PlatformJiraIntegration } = await import('./integrations/platform/jira/integration.js');\n integrations.push(new PlatformJiraIntegration());\n }\n if (!integrations.some(integration => integration.id === 'gitlab')) {\n const { PlatformGitLabIntegration } = await import('./integrations/platform/gitlab/integration.js');\n integrations.push(new PlatformGitLabIntegration());\n }\n if (!integrations.some(integration => integration.id === 'linear')) {\n const { PlatformLinearIntegration } = await import('./integrations/platform/linear/integration.js');\n integrations.push(new PlatformLinearIntegration());\n }\n }\n // Never let the key be a silent no-op: it only applies to the integration\n // the factory installs itself, so warn when it had nothing to apply to.\n if (this.#config.platform?.github && !installedPlatformGithub) {\n console.warn(\n \"[factory] 'platform.github' config was provided but the factory installed no GitHub integration of its \" +\n 'own ' +\n (explicitGithub\n ? \"(an explicit integration with id 'github' takes precedence, so these options were ignored).\"\n : '(no Platform credentials are configured and no explicit GitHub integration was passed).'),\n );\n }\n\n // Validate ids up front so a copy-paste duplicate fails loud instead of one\n // instance silently shadowing the other.\n const integrationIds = new Set<string>();\n for (const integration of integrations) {\n if (integrationIds.has(integration.id)) {\n throw new Error(`MastraFactory: duplicate integration id '${integration.id}' in 'integrations'.`);\n }\n integrationIds.add(integration.id);\n }\n const configVersion = this.#configVersion;\n\n // FactoryStorage owns every app-table domain and initializes them through\n // the same lifecycle as the backend connection.\n const intakeStorage = storage.registerDomain(new IntakeStorage());\n const auditStorage = storage.registerDomain(new AuditStorage());\n const workItemsStorage = storage.registerDomain(new WorkItemsStorage());\n workItemsStorage.onAttentionChanged(scope => touchFeed(eventBus, scope));\n workItemsStorage.useTerminalPhasePredicate(item => isTerminalWorkItem(this.#boards, item));\n const modelCredentialsStorage = storage.registerDomain(new ModelCredentialsStorage(secretEncryption));\n const modelDefaultsStorage = storage.registerDomain(new ModelDefaultsStorage());\n const memorySettingsStorage = storage.registerDomain(new MemorySettingsStorage());\n const customProvidersStorage = storage.registerDomain(new CustomProvidersStorage(secretEncryption));\n const queueHealthStorage = storage.registerDomain(new QueueHealthStorage());\n // Generic integration storage (connections/subscriptions/settings) — the\n // default persistence surface for integrations without a bespoke domain.\n const integrationStorage = storage.registerDomain(new IntegrationStorage(secretEncryption));\n const factoryProjectsStorage = storage.registerDomain(new FactoryProjectsStorage());\n const filesystemStorage = storage.registerDomain(new FilesystemStorage());\n const sourceControlStorage = storage.registerDomain(new SourceControlStorage());\n // Reverse index from a platform sender (Slack/Discord/...) to a Mastra\n // tenant, so inbound channel events can resolve the sender's model creds.\n const channelIdentityStorage = storage.registerDomain(new ChannelIdentityStorage());\n const workItemCommentsStorage = storage.registerDomain(new WorkItemCommentsStorage());\n // Every app-table domain handle the route builders and integrations need,\n // threaded explicitly (no service locator).\n const domains = {\n intake: intakeStorage,\n modelCredentials: modelCredentialsStorage,\n modelDefaults: modelDefaultsStorage,\n memorySettings: memorySettingsStorage,\n customProviders: customProvidersStorage,\n filesystem: filesystemStorage,\n projects: factoryProjectsStorage,\n queueHealth: queueHealthStorage,\n workItems: workItemsStorage,\n channelIdentity: channelIdentityStorage,\n comments: workItemCommentsStorage,\n };\n const auditDomain = new AuditDomain({\n auth: routeAuth,\n audit: auditStorage,\n projects: factoryProjectsStorage,\n users: auth && isUserProvider(auth) ? auth : undefined,\n sinks: integrations,\n agentTenant: requestContext => {\n const user = getFactoryAuthUserFromContext(requestContext);\n return { orgId: getFactoryAuthOrgId(user), userId: getFactoryAuthUserId(user) };\n },\n });\n // Held by reference: the channel attach below pushes into it, long after this.\n const feedPublishers: WorkItemFeedPublisher[] = [];\n const commentsDomain = new CommentsDomain({\n auth: routeAuth,\n comments: workItemCommentsStorage,\n workItems: workItemsStorage,\n projects: factoryProjectsStorage,\n channelIdentity: channelIdentityStorage,\n audit: auditDomain,\n publishers: feedPublishers,\n pubsub: eventBus,\n });\n\n const sandboxOption = this.#config.sandbox;\n let sandboxConfig: FactorySandbox | undefined;\n if (sandboxOption === undefined) {\n sandboxConfig = await platformDefaultSandbox();\n } else if (isFactorySandbox(sandboxOption)) {\n sandboxConfig = sandboxOption;\n } else if (typeof sandboxOption === 'function') {\n sandboxConfig = new CallbackFactorySandbox(sandboxOption);\n } else {\n throw new Error(invalidSandboxOptionMessage(sandboxOption));\n }\n this.#sandbox = sandboxConfig;\n\n const workspaceRegistry = new FactoryWorkspaceRegistry();\n\n // One shared OAuth state signer per boot. The deploy entry supplies a\n // replica-stable secret when needed; otherwise local development gets a\n // per-process random signer (`stable: false`).\n const stateSigner = createStateSigner(this.#config.stateSecret);\n\n // One-time provider initialization with factory-level context (e.g.\n // better-auth builds its default instance on the backend's auth\n // database, WorkOS derives its redirect URI from the public URL).\n // Failures surface here, at prepare() — a misconfigured provider must\n // not boot.\n if (auth && hasAuthInit(auth)) {\n await timedPhase('prepare.auth.init', () =>\n auth.init({ database: storage.authDatabase?.(), publicUrl: publicOrigin, allowedOrigins }),\n );\n }\n\n // Single init path: backend connection failure is a hard boot error;\n // registered app domains initialize fail-soft inside FactoryStorage.\n await timedPhase('prepare.storage.init', () => storage.init());\n\n // Per-tenant model credentials: once the credentials domain is up, model\n // resolution goes through the caller's own store and the SDK stops\n // mirroring stored API keys into process.env.\n //\n // Only register when a real auth adapter gates callers. In local /\n // auth-disabled mode there is no authenticated tenant, so registering would\n // force every model call through an empty tenant store (fail-closed, no env\n // fallback) and break chat with \"Not logged in\". Leaving it unregistered\n // lets the SDK fall back to the file-backed AuthStorage (auth.json) — the\n // same store the local /login and Settings pages read and write.\n // Custom providers: DB-backed in both modes (org rows in tenant mode, the\n // sentinel `local` org in no-auth mode). Once registered, model resolution\n // and the gateway catalog never read settings.json custom providers.\n registerCustomProvidersSource({ storage: customProvidersStorage, authEnabled: Boolean(auth) });\n\n for (const integration of integrations) {\n const integrationSourceControl = integration.versionControl\n ? sourceControlStorage.forIntegration(integration.id)\n : undefined;\n integration.initialize?.({\n storage: integrationStorage.forIntegration(integration.id),\n projects: factoryProjectsStorage,\n auth: routeAuth,\n intake: intakeStorage,\n ...(integrationSourceControl ? { sourceControl: integrationSourceControl } : {}),\n channels: () => this.#prepared?.base.controller.getChannels(),\n });\n if (integration.versionControl && integrationSourceControl) {\n integration.versionControl.initialize({ storage: integrationSourceControl });\n }\n }\n // Keep the legacy GitHub partition readable even when no GitHub\n // integration is registered; existing sessions may outlive a config change.\n const sourceControlIntegrationIds = [\n ...new Set(['github', ...integrations.filter(integration => integration.versionControl).map(({ id }) => id)]),\n ];\n const sourceControlHandles = sourceControlIntegrationIds.map(id => sourceControlStorage.forIntegration(id));\n const sourceControlSessions = createSourceControlSessionLookup(sourceControlHandles);\n const modelPolicyDependencies = {\n projects: factoryProjectsStorage,\n sourceControl: sourceControlSessions,\n workItems: workItemsStorage,\n };\n if (auth) {\n registerTenantCredentialResolver(modelCredentialsStorage, deploymentModelProviders, requestContext =>\n resolveFactoryCredentialTenant(requestContext, modelPolicyDependencies),\n );\n }\n\n // Every integration uses generic integration storage. Version-control\n // providers additionally require the source-control storage domain. Readiness\n // is derived solely from capability presence, never from provider ids.\n const integrationRegistrations = integrations.map(integration => {\n const requiredDomains = [\n 'integrations',\n ...(integration.versionControl ? ['source-control'] : []),\n // Channels resolve an inbound sender to a tenant through the reverse\n // index; without it every message would dispatch tenant-less.\n ...(integration.channels ? ['channel-identity'] : []),\n ];\n return {\n integration,\n ready: requiredDomains.every(domain => storage.isDomainReady(domain)),\n ensureReady: async () => {\n for (const domain of requiredDomains) await storage.ensureDomainReady(domain);\n },\n };\n });\n const intakeReady =\n integrations.some(integration => integration.intake !== undefined) && storage.isDomainReady('intake');\n const factoryReady = storage.isDomainReady('projects') && storage.isDomainReady('work-items');\n // Sessions from before shared resources ran under their own id. Move them\n // onto their Factory or owner in the background: it can take minutes on a\n // remote database, and an unmoved session keeps working under its own id\n // meanwhile. Run bindings decide which sessions belong to a Factory, so it\n // waits for work items.\n if (storage.isDomainReady('source-control') && storage.isDomainReady('work-items')) {\n this.#sessionResourceMigration = timedPhase('background.migrate.sessionResources', async () => {\n try {\n const mastraStorage = storage.getMastraStorage();\n const memory = await mastraStorage.getStore('memory');\n if (!memory) return false;\n // The sessions' own Memory, so a moved thread takes its observation vectors along.\n const sessionMemory = getDynamicMemory(mastraStorage, vector);\n const report = await migrateSessionResources({\n sessions: sourceControlStorage,\n workItems: workItemsStorage,\n ...(storage.isDomainReady('integrations') ? { integrations: integrationStorage } : {}),\n memory,\n threads: sessionMemory({ requestContext: new RequestContext() }),\n });\n await sessionMemory.settled();\n await privatizeOwnerResourceSessions({ sessions: sourceControlStorage, workItems: workItemsStorage, memory });\n return report.runBindings > 0;\n } catch (error) {\n // Unmoved sessions keep working under their own id; the next start retries.\n console.warn(\n `[factory] session resource migration stopped early: ${error instanceof Error ? error.message : error}`,\n );\n return false;\n }\n });\n }\n const knowledgeEnabled =\n this.#config.knowledge !== undefined || process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === '1';\n const githubIntegration = integrations.find(integration => integration.id === 'github') as\n | GithubIntegration\n | undefined;\n const gitlabIntegration = integrations.find(\n integration => integration.id === 'gitlab' && integration.intake && integration.versionControl,\n ) as GitLabIntegrationBase | undefined;\n const workItemsReady = storage.isDomainReady('work-items');\n const sessionRetirement =\n sandboxConfig && storage.isDomainReady('source-control')\n ? new SessionRetirementCoordinator({\n invalidateSession: sessionId => workspaceRegistry.invalidateSession(sessionId),\n sandbox: sandboxConfig,\n })\n : undefined;\n const retireTerminalSessions =\n sessionRetirement && workItemsReady\n ? async ({ orgId, workItemId }: { orgId: string; workItemId: string }) => {\n const item = await workItemsStorage.get({ orgId, id: workItemId });\n if (!item) return;\n const sessionIds = [...new Set(Object.values(item.sessions).map(session => session.sessionId))];\n await Promise.all(\n sessionIds.map(async sessionId => {\n const sourceControl = await sourceControlSessions.getSourceControlBySessionId(sessionId);\n if (!sourceControl) return;\n await sessionRetirement.retireSession({\n sourceControl,\n orgId,\n sessionId,\n deleteSession: false,\n });\n }),\n );\n }\n : undefined;\n // Terminal-stage cleanup: ingest any trailing tool results from the item's\n // bound threads, then revoke the bindings so completed items leave the\n // reconcile walk (the active-binding set otherwise grows forever), and\n // finally release the item's sandboxes. Each step is best-effort — a\n // committed transition never fails on cleanup.\n const terminalCleanup = workItemsReady\n ? createTerminalStageCleanup({\n workItems: workItemsStorage,\n // `factoryProcessor` is assigned below in this scope; the cleanup\n // only runs on transitions long after bootstrap completes.\n reconcileBinding: async (binding): Promise<void> => {\n await factoryProcessor?.reconcileBinding(binding);\n },\n // Abort the live run on a retired seat so the model cannot keep\n // executing unbound (or be resumed later) once its binding is revoked.\n // `this.#prepared` is assigned below; cleanup only runs long after.\n abortSession: async (binding): Promise<void> => {\n const controller = this.#prepared?.base.controller;\n if (!controller) return;\n const session = await controller.getSession(binding.sessionId);\n if (session?.stream.isActive()) session.abort();\n },\n // Session retirement supersedes the older direct sandbox release: it\n // invalidates the session and stops/destroys its sandbox.\n ...(retireTerminalSessions ? { releaseSandboxes: retireTerminalSessions } : {}),\n })\n : undefined;\n // Factory messaging needs the controller and its notifications store, which exist once the mount is up.\n const factoryMessaging = async () => {\n const controller = this.#prepared?.base.controller;\n const notifications = await controller?.getMastra()?.getStorage()?.getStore('notifications');\n return controller && notifications ? { controller, notifications } : null;\n };\n const factoryReporting = async (): Promise<FactoryReporting | null> => {\n const messaging = await factoryMessaging();\n if (!messaging) return null;\n return {\n notifications: messaging.notifications,\n deliver: (target, notification, options) =>\n deliverFactorySessionNotification({\n controller: messaging.controller,\n sessions: sourceControlSessions,\n runs: workItemsStorage,\n target,\n notification,\n ...options,\n }),\n };\n };\n const sessionReports = {\n sessions: sourceControlSessions,\n workItems: workItemsStorage,\n reporting: factoryReporting,\n };\n const reportSessionRunEnd = createSessionRunEndReporter(sessionReports);\n // Repeated attempts of one delivery send one report: identical failures to\n // the same follower are deduplicated.\n // A woken thread under a Factory or user resource names its session with its\n // stamp, or is the session's own thread; an unmigrated thread still runs\n // under its session id as its resource.\n const resolveWakeSession = async ({\n resourceId,\n threadId,\n thread,\n }: {\n resourceId: string;\n threadId: string;\n thread?: { metadata?: Record<string, unknown> } | null;\n }) => {\n const stored =\n thread === undefined ? await this.#prepared?.base.controller.queryThreadById({ threadId }) : thread;\n const stamp = stored?.metadata?.factorySessionId;\n const candidates = [...new Set([typeof stamp === 'string' ? stamp : '', threadId, resourceId])].filter(Boolean);\n for (const sessionId of candidates) {\n const row = await sourceControlSessions.getBySessionId(sessionId);\n // The stamp is client-writable metadata: a session only claims a\n // thread that runs under its own memory resource, or under its own id\n // as the resource from before resources were shared.\n // A stamp (neither the thread's own id nor its legacy resource) only\n // counts where the session's stamps are trusted.\n const viaStamp = sessionId !== threadId && sessionId !== resourceId;\n if (\n row &&\n (!viaStamp || sessionStampCounts(row, resourceId)) &&\n (resourceId === sessionId ||\n resourceId === (await sessionMemoryResourceId(this.#prepared?.base.controller, row, workItemsStorage)))\n ) {\n return { sessionId, row };\n }\n }\n // Unresolved: report on the woken thread, never on a session a stamp merely names.\n return { sessionId: threadId, row: null };\n };\n const failWake = async ({ sessionId, threadId }: { sessionId: string; threadId: string }, reason: string) => {\n const message = `Factory session ${sessionId} can't be woken as its owner: ${reason}.`;\n await reportSessionRunEnd({\n sessionId,\n threadId,\n since: new Date(),\n outcome: { status: 'failed', reason: message, failureCode: 'wake-owner-unresolved' },\n }).catch(error => console.warn('[factory] Unable to report a failed wake.', error));\n throw new Error(message);\n };\n const onTerminalStage = terminalCleanup\n ? (args: {\n orgId: string;\n factoryProjectId: string;\n workItemId: string;\n revision: number;\n actor: FactoryRuleActor;\n }): Promise<void> =>\n terminalCleanup({\n orgId: args.orgId,\n factoryProjectId: args.factoryProjectId,\n workItemId: args.workItemId,\n revision: args.revision,\n // Leave the seat that drove its own terminal transition running; it\n // is already returning from its transition tool call.\n ...(args.actor.type === 'agent' ? { initiatingBindingId: args.actor.bindingId } : {}),\n })\n : retireTerminalSessions;\n const transitionService = workItemsReady\n ? new FactoryTransitionService({\n configVersion,\n boards: this.#boards,\n storage: workItemsStorage,\n audit: auditDomain,\n autoApprovePlans: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoApprovePlans ?? false;\n },\n selfReviewEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.selfReviewEnabled ?? false;\n },\n ...(onTerminalStage ? { onTerminalStage } : {}),\n onTransitionCommitted: createStageChangeNotifier({\n workItems: workItemsStorage,\n reporting: factoryReporting,\n }),\n ...(githubIntegration\n ? {\n onAccepted: (args: { orgId: string; factoryProjectId: string; item: WorkItemRow }) =>\n reconcileGithubAcceptanceLabels(\n githubIntegration,\n sourceControlStorage.forIntegration(githubIntegration.id),\n args,\n ),\n }\n : {}),\n })\n : undefined;\n // One set of storage and services behind the Factory tools, shared by agent sessions and the MCP endpoint.\n const factoryToolDeps: FactoryToolDependencies = {\n workItems: workItemsStorage,\n comments: workItemCommentsStorage,\n feed: commentsDomain,\n audit: auditStorage,\n boards: this.#boards,\n transitionService,\n auditRecorder: auditDomain,\n sessions: sourceControlSessions,\n sessionModel: {\n projects: factoryProjectsStorage,\n modelDefaults: modelDefaultsStorage,\n ...(auth\n ? {\n tenantCatalog: {\n credentials: modelCredentialsStorage,\n customProviders: customProvidersStorage,\n deploymentProviders: deploymentModelProviders,\n },\n }\n : {}),\n },\n intake: intakeStorage,\n startCoordinator: () => this.#startCoordinator,\n messaging: factoryMessaging,\n };\n // Proactive environment builds exist only when the sandbox can build\n // templates on its own; the workflow is registered on the host's Mastra\n // and the runner reaches the booted instance through the controller.\n this.#environmentBuilds = this.#sandbox?.builds\n ? new EnvironmentBuildRunner(\n {\n sandbox: this.#sandbox,\n projects: factoryProjectsStorage,\n sourceControl: githubIntegration?.versionControl\n ? {\n storage: sourceControlStorage.forIntegration(githubIntegration.id),\n versionControl: githubIntegration.versionControl,\n }\n : undefined,\n logger: { info: (msg, meta) => console.info(`[Mastra Factory] ${msg}`, meta ?? {}) },\n },\n { getMastra: () => this.#prepared?.base.controller.getMastra() },\n )\n : undefined;\n const environmentBuilds = this.#environmentBuilds;\n const projectRoutes = new ProjectRoutes({\n auth: routeAuth,\n sandbox: this.#sandbox,\n ...(environmentBuilds ? { environmentBuilds } : {}),\n projects: factoryProjectsStorage,\n sourceControl: sourceControlStorage,\n versionControlIntegrationIds: integrations\n .filter(integration => integration.versionControl)\n .map(integration => integration.id),\n ...(githubIntegration || gitlabIntegration\n ? {\n resolveRepository: async ({ integrationId, orgId, userId, installationId, externalId, slug }) => {\n if (githubIntegration && integrationId === githubIntegration.id) {\n const installation = await githubIntegration.sourceControlStorage.installations.get({\n orgId,\n id: installationId,\n });\n if (!installation) return null;\n const repositories = await githubIntegration.listInstallationRepos(Number(installation.externalId));\n const selected = repositories.find(repo => repo.id.toString() === externalId && repo.fullName === slug);\n if (!selected) return null;\n return githubIntegration.sourceControlStorage.repositories.upsert({\n orgId,\n input: {\n installationId,\n externalId,\n slug: selected.fullName,\n defaultBranch: isValidGitRef(selected.defaultBranch) ? selected.defaultBranch : 'main',\n providerMetadata: { private: selected.private, owner: selected.owner },\n },\n });\n }\n\n if (\n !gitlabIntegration?.intake ||\n !gitlabIntegration.versionControl ||\n integrationId !== gitlabIntegration.id\n )\n return null;\n const handle = sourceControlStorage.forIntegration(gitlabIntegration.id);\n const installation = await handle.installations.get({ orgId, id: installationId });\n if (!installation) return null;\n const sources = await gitlabIntegration.intake.listSources({ orgId, userId });\n const selected = sources.find(\n source =>\n source.name === slug &&\n typeof source.metadata?.projectId === 'string' &&\n source.metadata.projectId === externalId &&\n source.metadata.connectionId === installation.externalId,\n );\n if (!selected) return null;\n const [repository] = await gitlabIntegration.versionControl.registerRepositories({\n orgId,\n installationId,\n repositories: [\n {\n externalId,\n slug,\n defaultBranch:\n typeof selected.metadata?.defaultBranch === 'string' &&\n isValidGitRef(selected.metadata.defaultBranch)\n ? selected.metadata.defaultBranch\n : 'main',\n metadata: selected.metadata,\n },\n ],\n });\n return repository ?? null;\n },\n }\n : {}),\n ...(githubIntegration || gitlabIntegration\n ? {\n onProjectRepositoryLinked: ({ orgId, projectRepository }) => {\n void (async () => {\n const linkedInGithub =\n githubIntegration &&\n (await sourceControlStorage.forIntegration('github').projectRepositories.get({\n orgId,\n id: projectRepository.id,\n }));\n if (linkedInGithub) {\n await githubIntegration.ingestLinkedRepositoryBacklog({\n orgId,\n projectRepositoryId: projectRepository.id,\n });\n } else if (gitlabIntegration) {\n const linkedInGitlab = await sourceControlStorage.forIntegration('gitlab').projectRepositories.get({\n orgId,\n id: projectRepository.id,\n });\n if (linkedInGitlab) {\n await gitlabIntegration.ingestLinkedRepositoryBacklog({\n orgId,\n projectRepositoryId: projectRepository.id,\n });\n }\n }\n })().catch(error => {\n console.warn('[factory] Failed to import a linked repository backlog:', error);\n });\n },\n }\n : {}),\n ...(sessionRetirement ? { sessionRetirement } : {}),\n ...(workItemsReady\n ? {\n workItems: workItemsStorage,\n controller: {\n getSession: async (sessionId: string) => this.#prepared?.base.controller.getSession(sessionId),\n },\n }\n : {}),\n });\n // The row follows whoever pays for the request, so its memory model is one their credentials reach.\n const memorySettingsRowKey = async (requestContext: RequestContext, binding: FactoryRunBindingRecord | null) => {\n // A wake lends the session owner even with auth off, but credentials stay process-wide there.\n const policy = auth ? await resolveFactoryModelPolicy(requestContext, modelPolicyDependencies) : undefined;\n if (policy) {\n const orgId = tenantOrgId(policy.tenant);\n return policy.tenant.credentialScope === 'factory' && policy.factoryProjectId\n ? { orgId, userId: factoryMemorySettingsUserId(policy.factoryProjectId) }\n : { orgId, userId: policy.tenant.userId };\n }\n // No tenant pays: the session's Factory row applies.\n const scope = readFactorySessionScope(requestContext);\n const factoryProjectId = binding?.factoryProjectId ?? scope?.factoryProjectId;\n if (!factoryProjectId) return { orgId: 'local', userId: 'local' };\n return {\n orgId: binding?.orgId ?? scope?.factoryOrgId ?? 'local',\n userId: factoryMemorySettingsUserId(factoryProjectId),\n };\n };\n const loadMemorySettings = async ({\n requestContext,\n binding,\n }: {\n requestContext: RequestContext | undefined;\n binding: FactoryRunBindingRecord | null;\n }) => {\n if (!requestContext) return;\n const record = await memorySettingsStorage.get(await memorySettingsRowKey(requestContext, binding));\n requestContext.set('mastra__factoryMemorySettings', record);\n };\n // Thinking defaults come from the session's defaults set, never the host's settings.json.\n const resolveDefaultThinkingLevel = (requestContext: RequestContext | undefined) =>\n resolveFactoryThinkingLevel(requestContext, {\n projects: factoryProjectsStorage,\n sourceControl: sourceControlSessions,\n workItems: workItemsStorage,\n modelDefaults: modelDefaultsStorage,\n });\n const factoryProcessor = workItemsReady\n ? new FactoryPhaseStateProcessor({\n configVersion,\n storage: workItemsStorage,\n boards: this.#boards,\n loadMemorySettings,\n defaultThinkingLevel: resolveDefaultThinkingLevel,\n ...(transitionService ? { transitionService } : {}),\n ...(githubIntegration\n ? {\n recordPullRequestProvenance: (input: Parameters<typeof recordFactoryPullRequestProvenance>[4]) =>\n recordFactoryPullRequestProvenance(\n githubIntegration,\n sourceControlStorage.forIntegration('github'),\n integrationStorage.forIntegration('github'),\n workItemsStorage,\n input,\n ),\n }\n : {}),\n messageReader: {\n listMessages: async input => {\n const memory = await storage.getMastraStorage().getStore('memory');\n return memory ? memory.listMessages(input) : { messages: [], hasMore: false };\n },\n },\n })\n : undefined;\n\n // Boot assertion: an active integration that signs OAuth `state` needs a\n // replica-stable signer — a per-process random secret silently breaks the\n // OAuth callback on any replica that didn't sign the state. Fail loud now\n // instead. (The built-ins also assert this inside their readiness gates.)\n for (const { integration } of integrationRegistrations) {\n if (integration.requiresStableStateSigner && !stateSigner.stable) {\n throw new Error(\n `MastraFactory: integration '${integration.id}' signs OAuth state and requires a ` +\n `replica-stable state secret, but none is configured. Set 'stateSecret' on the factory config.`,\n );\n }\n }\n\n // The SDK needs to know which backend the injected Mastra store uses\n // (its own `instanceof` detection breaks when the dependency graph holds\n // duplicate package copies). Resolve it by walking the FactoryStorage\n // prototype chain by class name — the factory can't import the concrete\n // classes since '@mastra/pg' / '@mastra/libsql' are the user's choice.\n const mastraStorageBackend = (() => {\n for (let proto = Object.getPrototypeOf(storage); proto; proto = Object.getPrototypeOf(proto)) {\n if (proto.constructor?.name === 'PgFactoryStorage') return 'pg' as const;\n if (proto.constructor?.name === 'LibSQLFactoryStorage') return 'libsql' as const;\n }\n return undefined;\n })();\n\n const integrationInputProcessors = integrations.flatMap(integration => integration.processors?.input ?? []);\n // Integrations contributing tools to agent sessions: org-scoped\n // `agentTools` (resolved per request) + session-scoped `sessionTools`.\n const toolIntegrations = integrationRegistrations.filter(\n ({ integration }) => integration.agentTools || integration.sessionTools,\n );\n const sourceControlToolProviders = integrations.flatMap(integration =>\n integration.versionControl\n ? [\n {\n id: integration.id,\n versionControl: integration.versionControl,\n storage: sourceControlStorage.forIntegration(integration.id),\n },\n ]\n : [],\n );\n\n // Build the real production controller (agents, tools, memory, OM, MCP,\n // providers) — the terminal app's, minus modes. Agent state lives in\n // the storage backend's Mastra store alongside the Factory app tables —\n // one shared database for all users, separated by `resourceId` scoping.\n const prepared = await timedPhase('prepare.controllerMount', () =>\n prepareAgentControllerMount({\n controllerId: CONTROLLER_ID,\n browser: this.#config.browser,\n coAuthor: { name: 'mastra-platform[bot]' },\n ...(this.#config.disableBuiltinTools?.length ? { disableBuiltinTools: this.#config.disableBuiltinTools } : {}),\n modes: false,\n // Subagents are disabled, matching the Mastra Code TUI default.\n subagents: [],\n resolveDefaultThinkingLevel: ({ requestContext }) => resolveDefaultThinkingLevel(requestContext),\n workspace: createWorkspaceFactory({\n ...(sandboxConfig ? { sandbox: sandboxConfig } : {}),\n ...(this.#config.sandboxStart ? { sandboxStart: this.#config.sandboxStart } : {}),\n sourceControls: integrations.flatMap(integration =>\n integration.versionControl\n ? [\n {\n id: integration.id,\n versionControl: integration.versionControl,\n storage: sourceControlStorage.forIntegration(integration.id),\n ...(integration.id === 'github' && githubIntegration ? { github: githubIntegration } : {}),\n },\n ]\n : [],\n ),\n ...(factoryProjectsStorage ? { projects: factoryProjectsStorage } : {}),\n ...(workItemsStorage ? { workItems: workItemsStorage } : {}),\n workspaceRegistry,\n }),\n disableGithubSignals: true,\n // A wake (notification or peer signal) has no signed-in request, so\n // tenant credential resolution would fail closed. Run it as the Factory\n // session's owner in its org.\n // With auth on, a wake whose owner can't be resolved must not run (it\n // would fail on credentials with no hint why); it fails, and the\n // session's followers get a failed report naming the reason.\n prepareWakeRequestContext: async ({ requestContext, resourceId, threadId }) => {\n if (!storage.isDomainReady('source-control')) {\n if (auth) await failWake({ sessionId: threadId, threadId }, 'session storage is not ready');\n return;\n }\n const { sessionId, row } = await resolveWakeSession({ resourceId, threadId });\n // Only a session that owns the thread's resource may lend its owner;\n // the unresolved fallback id must never be looked up as a session.\n if (!row) {\n if (auth) await failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['session-not-found']);\n return;\n }\n const prepared = await prepareSessionRunContext(requestContext, sessionId, {\n sessions: sourceControlSessions,\n });\n if (prepared !== 'prepared') {\n if (auth) await failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED[prepared]);\n return;\n }\n await primeCustomProvidersForRequestContext(requestContext);\n },\n // A deferred delivery can land after the session closed, after a\n // restart, or on another replica: nobody here owns it, and the wake\n // would run with no identity at all. Bring the session online as its\n // row's owner first, as a direct message to an offline session does.\n ...(auth\n ? {\n resumeWakeSession: async ({ resourceId, threadId }: { resourceId: string; threadId: string }) => {\n const controller = this.#prepared?.base.controller;\n if (!controller) return failWake({ sessionId: threadId, threadId }, 'the Factory is not started');\n const thread = await controller.queryThreadById({ threadId });\n if (!thread || thread.resourceId !== resourceId) {\n return failWake({ sessionId: threadId, threadId }, `thread ${threadId} is not the session's`);\n }\n const { sessionId, row } = storage.isDomainReady('source-control')\n ? await resolveWakeSession({ resourceId, threadId, thread })\n : { sessionId: threadId, row: null };\n if (!row?.factoryProjectId)\n return failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['session-not-found']);\n if (!hasResolvedOrg(row.orgId)) {\n return failWake({ sessionId, threadId }, WAKE_OWNER_UNRESOLVED['organization-unresolved']);\n }\n if (await controller.getSession(sessionId)) return;\n await createSessionAsRowOwner(controller, {\n sessionId,\n ownerResourceId: resourceId,\n row,\n tags: {\n factoryProjectId: row.factoryProjectId,\n ...(row.projectRepositoryId ? { projectRepositoryId: row.projectRepositoryId } : {}),\n },\n threadId,\n });\n },\n }\n : {}),\n // Memory settings live in the factory's `memory-settings` app table (per\n // org/user), so the host machine's TUI settings.json must not seed them.\n disableSettingsOmSeed: true,\n hostInstructions: async ({ requestContext }) => {\n const context = requestContext.get('controller') as\n | AgentControllerRequestContext<MastraCodeState>\n | undefined;\n // The SDK resolves this callback before it loads repository\n // AGENTS.md/CLAUDE.md. A controller recreated after restart has\n // only initialState, and a partially persisted one can keep\n // `factoryProjectId` while `untrustedCheckout` is gone, so the\n // presence of the project id alone proves nothing. Heal whenever any\n // trust field the recovery writes is missing, now, not later when\n // the agent's tools are assembled. Unbound sessions never gain these\n // fields and pay one binding lookup per prompt.\n if (context?.threadId && context.sessionId) {\n const current = context.getState();\n const trustStateComplete =\n Boolean(current.factoryProjectId) &&\n Boolean(current.factoryOrgId) &&\n typeof current.untrustedCheckout === 'boolean';\n if (!trustStateComplete) {\n const recovered = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n forceBindingLookup: true,\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n });\n if (recovered?.binding) {\n const state = context.getState();\n if (\n state.factoryProjectId !== recovered.binding.factoryProjectId ||\n (recovered.binding.role === 'review' && state.untrustedCheckout !== true)\n ) {\n throw new Error(\n 'Factory review session security state could not be restored before prompt creation.',\n );\n }\n }\n }\n }\n return undefined;\n },\n // A factory reads the repository it works on and its skill, never the\n // ~/.claude instructions of whoever hosts the process. On the controller\n // rather than per session, so webhook-recreated sessions keep it too.\n // Blank project identity for the same reason: the SDK's defaults seed\n // sessions with the HOST process's own project root / name / branch,\n // which must never reach a hosted session's prompt. Repo-backed\n // sessions get their real workdir pinned by workspace resolution;\n // chat-only sessions legitimately have no project.\n // Factory sessions also start fail-closed on org classification: the\n // unresolved marker is set at birth, a successful org seed clears it,\n // and a resolved `factoryOrgId` always takes precedence — so a failed\n // (best-effort) seed can never leave a session classified as local.\n initialState: {\n skipGlobalInstructions: true,\n factoryOrgUnresolved: true,\n projectPath: '',\n projectName: '',\n gitBranch: '',\n },\n storage: storage.getMastraStorage(),\n ...(mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {}),\n ...(this.#config.knowledge ? { knowledge: this.#config.knowledge } : {}),\n // The environment signal tells the agent which repositories its\n // sandbox holds and where; the phase signal, when work items are on,\n // comes after it.\n inputProcessors: async ({ requestContext }: { requestContext: RequestContext }) => {\n const environmentProcessor = new FactoryEnvironmentStateProcessor();\n const sessionsProcessor =\n workItemsStorage && storage.isDomainReady('source-control')\n ? [\n new FactorySessionsStateProcessor({\n authEnabled: routeAuth.enabled(),\n sessions: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n boards: this.#boards,\n isRunning: async sessionId => {\n const session = await this.#prepared?.base.controller.getSession(sessionId);\n return session?.stream.isActive() ?? false;\n },\n lastActivity: async threadId => {\n const thread = await this.#prepared?.base.controller.queryThreadById({ threadId });\n return thread?.updatedAt ? new Date(thread.updatedAt) : null;\n },\n notifications: async () => (await factoryMessaging())?.notifications ?? null,\n }),\n ]\n : [];\n if (factoryProcessor) {\n await factoryProcessor.prepareMemorySettings(requestContext);\n return [...integrationInputProcessors, environmentProcessor, ...sessionsProcessor, factoryProcessor];\n }\n // Without work items there is no run binding, so the caller's row applies.\n try {\n await loadMemorySettings({ requestContext, binding: null });\n } catch (error) {\n reportMemorySettingsUnavailable(requestContext, error instanceof Error ? error.message : String(error));\n }\n return [...integrationInputProcessors, environmentProcessor, ...sessionsProcessor];\n },\n outputProcessors: [\n ...integrations.flatMap(integration => integration.processors?.output ?? []),\n new FactoryReplyCredentialProcessor(),\n ],\n ...(vector ? { vector } : {}),\n extraTools: async ({ requestContext }: { requestContext: RequestContext }) => {\n const tools: IntegrationTools = {};\n const toolOwners = new Map<string, string>();\n const mergeTools = (ownerId: string, contributed: IntegrationTools) => {\n for (const [name, tool] of Object.entries(contributed)) {\n const owner = toolOwners.get(name);\n if (owner) {\n throw new Error(\n `MastraFactory: integration tool '${name}' from '${ownerId}' conflicts with '${owner}'.`,\n );\n }\n toolOwners.set(name, ownerId);\n tools[name] = tool;\n }\n };\n if (storage.isDomainReady('source-control')) {\n mergeTools(\n 'source-control',\n await createSourceControlTools({\n requestContext,\n providers: sourceControlToolProviders,\n audit: auditDomain,\n testChecksEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.reviewTestChecksEnabled ?? false;\n },\n ...(workItemsStorage\n ? {\n selfReviewApprovedHead: async () => {\n const resolution = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n });\n if (!resolution) return undefined;\n const binding =\n resolution.binding ?? (await workItemsStorage.findActiveRunBinding(resolution.address));\n if (!binding) return undefined;\n const item = await workItemsStorage.get({ orgId: binding.orgId, id: binding.workItemId });\n if (!item || boardForWorkItem(item) !== 'work') return undefined;\n if (typeof item.metadata?.openPullRequestNumber === 'number') return undefined;\n // A verdict already recorded still binds the change request to its head.\n if (item.metadata?.selfReviewVerdict === undefined) {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({\n orgId: binding.orgId,\n id: binding.factoryProjectId,\n });\n if (!project?.selfReviewEnabled) return undefined;\n }\n const sha = item.metadata?.selfReviewedHeadSha;\n return item.metadata?.selfReviewVerdict === 'approve' && typeof sha === 'string' ? sha : null;\n },\n boundChangeRequestId: async () => {\n const resolution = await resolveFactorySessionAddress({\n requestContext,\n storage: workItemsStorage,\n });\n if (!resolution) return undefined;\n const binding =\n resolution.binding ?? (await workItemsStorage.findActiveRunBinding(resolution.address));\n if (binding?.role !== 'review') return undefined;\n const item = await workItemsStorage.get({ orgId: binding.orgId, id: binding.workItemId });\n const source = item?.externalSource;\n if (!source || !/pull-request|merge-request/.test(source.type)) return undefined;\n return /(\\d+)$/.exec(source.externalId)?.[1];\n },\n }\n : {}),\n }),\n );\n }\n if (workItemsStorage && transitionService) {\n mergeTools(\n 'factory',\n await createFactoryTransitionTools({\n requestContext,\n storage: workItemsStorage,\n transitionService,\n boards: this.#boards,\n // Heals crash-resumed sessions: recovered addresses re-seed\n // projectRepositoryId/baseRef from the source session record.\n // Only offered while the source-control domain is ready — a\n // throwing lookup would abort recovery's catch block and also\n // skip the metadata baseRef fallback.\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n }),\n );\n // Review-role sessions get `factory_review_source` so the\n // published review can carry the session URL that produced it\n // — the affordance that lets a suspicious review (e.g. one\n // that lands on the wrong PR) be traced back to its run.\n //\n // The session URL is browser-facing (a human opens it from a\n // GitHub/GitLab review comment), so it needs the UI host —\n // the same origin Slack session deep-links resolve against\n // (`integrations/slack/slack.ts:168-171`, `:809-812`). In a\n // separate-SPA deployment `publicUrl` (i.e. `publicOrigin`)\n // is the API host, so we read `MASTRACODE_PUBLIC_URL` and\n // mirror Slack's behavior: when it is unset, pass `null` so\n // the tool is omitted from the toolset rather than fall back\n // to the API/localhost origin and publish that URL into a\n // public review body. The skill's tool-not-available branch\n // handles the absence as stop-don't-publish. Blank counts as\n // unset: `.env.schema` ships `MASTRACODE_PUBLIC_URL=`, so an\n // empty/whitespace value must not register the tool with a\n // hostless `sessionUrl`.\n const reviewSourceUiOrigin = resolveReviewSourceUiOrigin(process.env.MASTRACODE_PUBLIC_URL);\n mergeTools(\n 'factory-review-source',\n await createReviewSourceTool({\n requestContext,\n storage: workItemsStorage,\n uiOrigin: reviewSourceUiOrigin,\n ...(storage.isDomainReady('source-control') ? { sessions: sourceControlSessions } : {}),\n }),\n );\n if (storage.isDomainReady('source-control')) {\n const scope = await resolveFactoryToolScope({\n requestContext,\n authEnabled: routeAuth.enabled(),\n sessions: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n });\n if (scope) {\n mergeTools(\n 'factory-tools',\n createFactoryTools({\n scope,\n deps: factoryToolDeps,\n }),\n );\n if (sessionRetirement && sandboxConfig && SELF_RECREATE_SANDBOX_PROVIDERS.has(sandboxConfig.provider)) {\n mergeTools(\n 'factory-sandbox-tools',\n createFactorySandboxTools(scope, {\n sessions: sourceControlSessions,\n resetSandbox: input => sessionRetirement.resetSessionSandbox(input),\n }),\n );\n }\n }\n }\n }\n for (const { integration, ready, ensureReady } of toolIntegrations) {\n if (!ready && ensureReady) {\n try {\n await ensureReady();\n } catch {\n continue;\n }\n }\n if (integration.agentTools) {\n mergeTools(integration.id, await integration.agentTools({ requestContext }));\n }\n if (integration.sessionTools) {\n mergeTools(integration.id, integration.sessionTools({ requestContext }));\n }\n }\n return tools;\n },\n postToolObserver: async (toolContext: IntegrationPostToolContext) => {\n const requestContext = (toolContext.context as { requestContext?: RequestContext } | undefined)\n ?.requestContext;\n if (requestContext) {\n await observeAgentGitAction({\n audit: auditDomain,\n toolContext: { ...toolContext, context: requestContext },\n resolveRepositorySlugs: async sessionId => {\n for (const provider of sourceControlToolProviders) {\n const session = await provider.storage.sessions.getBySessionId(sessionId);\n if (!session) continue;\n return environmentSlugs(\n await resolveSessionRepositories({ sourceControl: provider.storage, session }),\n );\n }\n return [];\n },\n });\n }\n await Promise.all(\n integrations.map(async integration => {\n if (!integration.postToolObserver) return;\n try {\n await integration.postToolObserver({ toolContext, requestContext });\n } catch (error) {\n console.warn(`[factory] Integration '${integration.id}' post-tool observer failed:`, error);\n }\n }),\n );\n },\n ...(pubsub ? { pubsub, crossProcessPubSub: true } : {}),\n buildApiRoutes: ({ controller, authStorage }: BuildApiRoutesDeps) => [\n // Public `/auth/*` routes (login/callback/logout/me). Folded in as\n // `apiRoutes` (not plain Hono routes) because the entry can't touch the\n // Hono app the deployer generates. `requiresAuth: false`; the gate\n // skips `/auth/*`. Auth-disabled mode still answers `/auth/me` (404).\n ...(auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : buildAuthDisabledRoutes()),\n ...(mcpEnabled\n ? buildFactoryMcpRoutes({\n auth: routeAuth,\n publicOrigin,\n authorizationServers: mcpAuthorizationServers,\n projects: factoryProjectsStorage,\n sourceControls: sourceControlHandles,\n tools: factoryToolDeps,\n })\n : []),\n ...new TelemetryRoutes({ auth: routeAuth, providerName: auth?.name, publicOrigin, allowedOrigins }).routes(),\n // Custom `/web/*` routes (fs / config / integrations / factory / audit).\n ...assembleFactoryApiRoutes({\n controllerId: CONTROLLER_ID,\n controller,\n liveSessions: liveSessionsTouchingTheFeed(controller, eventBus),\n auth: routeAuth,\n ...(auth && isUserProvider(auth) ? { users: auth } : {}),\n authStorage,\n audit: auditDomain,\n publicOrigin,\n stateSigner,\n sandbox: sandboxConfig,\n ...(environmentBuilds ? { onRepositoryPush: environmentBuilds.onRepositoryPush } : {}),\n sessionRetirement,\n moveThread: async ({ threadId, resourceId }) => {\n // The sessions' own Memory, so a moved thread takes its observation vectors along.\n const sessionMemory = getDynamicMemory(storage.getMastraStorage(), vector);\n await sessionMemory({ requestContext: new RequestContext() }).updateThreadResourceId({\n threadId,\n resourceId,\n });\n await sessionMemory.settled();\n },\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n domains,\n feed: commentsDomain,\n integrations: integrationRegistrations,\n intakeReady,\n factoryReady,\n knowledgeEnabled,\n mcpEnabled,\n deploymentModelProviders,\n knowledgeKey: this.#config.knowledge?.key,\n configVersion,\n boardRegistry: this.#boards,\n factoryTransitionService: transitionService,\n onFactoryRuntime: ({ transitionService: runtimeTransitionService, startCoordinator, prepareBinding }) => {\n this.#startCoordinator = startCoordinator;\n this.#dispatcher ??= new FactoryDecisionDispatcher({\n controller,\n transitionService: runtimeTransitionService,\n storage: storage.getDomain<WorkItemsStorage>('work-items'),\n audit: auditDomain,\n boards: this.#boards,\n maxInFlight: this.#config.dispatcher?.maxInFlight,\n isAutoRunEnabled: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoRunEnabled ?? false;\n },\n autoApprovePlans: async ({ orgId, factoryProjectId }) => {\n await factoryProjectsStorage.ensureReady();\n const project = await factoryProjectsStorage.get({ orgId, id: factoryProjectId });\n return project?.autoApprovePlans ?? false;\n },\n reconcileToolResults: () => factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n prepareBinding,\n feedReader: new FactoryFeedReader(workItemCommentsStorage),\n ...(githubIntegration\n ? {\n dismissStaleReviews: async decision => {\n await dismissStaleFactoryReviews(\n githubIntegration.versionControl,\n decision,\n login => isFactoryGithubLogin(githubIntegration, login),\n login =>\n trustedCollaborator(githubIntegration, {\n installationId: decision.installationId,\n repository: decision.repository,\n login,\n }),\n );\n },\n }\n : {}),\n primeCredentials: tenant => primeTenantCredentials({ tenant, credentials: modelCredentialsStorage }),\n reportRunEnd: createWorkItemRunEndReporter({\n workItems: storage.getDomain<WorkItemsStorage>('work-items'),\n reporting: factoryReporting,\n }),\n resolveLinkedWorkItemParentId: async ({ orgId, factoryProjectId, decision }) => {\n if (decision.source !== 'github-pr') return null;\n const repositoryId = decision.metadata?.githubRepositoryId;\n const pullRequestNumber = decision.metadata?.githubPullRequestNumber;\n if (typeof repositoryId !== 'number' || typeof pullRequestNumber !== 'number') return null;\n return resolveFactoryPullRequestParentWorkItemId(\n integrationStorage.forIntegration<\n Record<string, unknown>,\n Record<string, unknown>,\n FactoryPullRequestProvenanceData\n >('github'),\n { orgId, factoryProjectId, repositoryId, pullRequestNumber },\n );\n },\n });\n },\n }),\n ...projectRoutes.routes(),\n ...auditDomain.routes(),\n ...commentsDomain.routes(),\n // Connect/reconnect session minting for Platform-managed providers.\n // Server-side because only the deploy holds Platform machine\n // credentials; the SPA runs the OAuth popup with the minted token.\n ...(hasPlatformCredentials()\n ? buildPlatformConnectRoutes({\n auth: routeAuth,\n client: new PlatformApiClient(platformApiClientConfigFromEnv()),\n })\n : []),\n ],\n buildServerConfig: () => {\n // MCP 2026-07-28 clients send `Mcp-*` headers on every request and\n // read the OAuth challenge from `WWW-Authenticate`; the deployer\n // merges these into its default allow/expose lists.\n const mcpCors = {\n allowHeaders: ['Mcp-Protocol-Version', 'Mcp-Method', 'Mcp-Name'],\n exposeHeaders: ['WWW-Authenticate'],\n };\n const cors = {\n cors: allowedOrigins.length ? { origin: allowedOrigins, credentials: true, ...mcpCors } : mcpCors,\n };\n // Log route errors with method/path/stack and answer with structured\n // JSON instead of an opaque `Internal Server Error`. Applied by the\n // deployer to both the top-level app and the custom-route sub-app.\n const onError = { onError: handleServerError };\n // Same-origin SPA: when a vite build is present (see resolveUiDistDir),\n // serve it at `/` from this server. Mounted last so the auth gate (when\n // enabled) covers it; it always passes `/api`, `/web`, `/auth` through.\n const uiDist = resolveUiDistDir();\n const spa = uiDist ? [createSpaStaticMiddleware(uiDist)] : [];\n const timing = factoryTimingEnabled ? [createRequestTimingMiddleware()] : [];\n if (!auth) {\n // Auth disabled: no gate. Still prime the sentinel-local custom\n // provider snapshot so model calls see DB rows, then SPA + CORS.\n return {\n middleware: [\n ...timing,\n createFactoryInteractiveMarker(),\n createCustomProvidersPrimer({ auth: routeAuth, storage: customProvidersStorage, authEnabled: false }),\n ...spa,\n ],\n ...cors,\n ...onError,\n };\n }\n\n // Ordered middleware. The deployer applies these AFTER its context\n // middleware sets `c.set('mastra', mastra)` and BEFORE routes, so:\n // 1. gate — validates the auth session, stashes the user, and 401s /\n // redirects unauthenticated requests. Skips public `/auth/*`.\n // 2. access — 404s requests addressing another user's private session.\n // 3. primers — hydrate the caller's model-credential and custom\n // provider snapshots so the request's first model call\n // resolves tenant credentials and custom providers.\n // 4. spa — serves the built UI for everything the server doesn't own.\n // `auth` also lands on `server.auth` so the core auth middleware (and\n // Studio's dual-auth routing — see `studio.auth` on the returned args)\n // authenticates core `/api/*` routes with the same provider.\n return {\n auth,\n middleware: [\n ...timing,\n createFactoryAuthGate(auth),\n createSessionAccessGuard({\n auth: routeAuth,\n sessions: sourceControlSessions,\n projects: {\n get: async args => {\n if (!storage.isDomainReady('projects')) return null;\n await factoryProjectsStorage.ensureReady();\n return factoryProjectsStorage.get(args);\n },\n },\n controller: () => this.#prepared?.base.controller,\n }),\n createTenantCredentialPrimer({ auth: routeAuth, credentials: modelCredentialsStorage }),\n createCustomProvidersPrimer({\n auth: routeAuth,\n storage: customProvidersStorage,\n authEnabled: Boolean(auth),\n }),\n ...spa,\n ],\n ...cors,\n ...onError,\n };\n },\n }),\n );\n\n const notifyApprovalRequested = createSessionApprovalNotifier(sessionReports);\n prepared.base.controller.onSessionCreated(session => {\n observeSessionFilesystem(session, {\n filesystem: filesystemStorage,\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionFirstMessage(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionFirstExec(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionThreadTitle(session, {\n sourceControl: { sessions: sourceControlSessions },\n });\n observeSessionRunEnd(session, { audit: auditDomain });\n // Every run end of a work or side session, and every tool call it holds for\n // approval, reaches whoever follows it, however the run started;\n // re-attached when a session is created again.\n observeSessionRunReports(\n session,\n (outcome, since) =>\n reportSessionRunEnd({\n sessionId: session.identity.getId(),\n threadId: session.thread.getId(),\n outcome,\n since,\n }),\n {\n onApprovalRequested: request =>\n notifyApprovalRequested({\n sessionId: session.identity.getId(),\n threadId: session.thread.getId(),\n ...request,\n }),\n },\n );\n observeSessionThreadStamp(session);\n });\n\n // Blocking: `createSession` awaits the organization seed so per-invocation\n // memory settings and knowledge capture use the correct tenant immediately.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionMemorySettings(session, {\n sourceControl: { sessions: sourceControlSessions },\n }),\n { blocking: true },\n );\n\n // Personal default models seed interactive user sessions only. Active Factory\n // run bindings are excluded and continue to use the project default model.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionDefaultModel(session, {\n sourceControl: sourceControlSessions,\n projects: factoryProjectsStorage,\n workItems: workItemsStorage,\n modelDefaults: modelDefaultsStorage,\n }),\n { blocking: true },\n );\n\n // Factory tools fall in the SDK's `mcp` category (default `ask`); allow the\n // no-approval ones per session before the session's first turn.\n prepared.base.controller.onSessionCreated(\n session => applyFactoryToolPermissions(session, { sessions: sourceControlSessions }),\n { blocking: true },\n );\n\n this.#prepared = prepared;\n this.#factoryProcessor = factoryProcessor;\n\n // Chat-platform channels (Slack, Discord, …) contributed by integrations,\n // attached to the mounted controller so inbound platform messages reach\n // the same agents the web UI drives. READY integrations only — readiness\n // means the `channel-identity` domain's `init()` succeeded, so its link\n // table is queryable. Without it a sender can't be resolved to a tenant,\n // and attaching anyway would dispatch runs on default credentials.\n const channelRegistrations = integrationRegistrations.filter(\n ({ integration, ready }) => ready && integration.channels,\n );\n // `setChannels` replaces rather than merges, so a second provider would\n // silently never receive a message. Fail loud instead.\n if (channelRegistrations.length > 1) {\n throw new Error(\n `MastraFactory: integrations [${channelRegistrations\n .map(({ integration }) => integration.id)\n .join(', ')}] all provide channels, but only one may. Remove all but one.`,\n );\n }\n this.#channelShutdowns = [];\n for (const { integration } of channelRegistrations) {\n const context = buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n // Integrations return a channels CONFIG; the factory owns construction and teardown.\n const channels = new AgentControllerChannels(integration.channels!(context));\n prepared.base.controller.setChannels(channels);\n for (const adapter of Object.values(channels.adapters)) {\n const disconnect = (adapter as unknown as { disconnect?: () => Promise<void> }).disconnect;\n if (disconnect) this.#channelShutdowns.push(() => disconnect.call(adapter));\n }\n }\n\n // Feed publishers mirror web-feed comments outward (a chat bridge, a\n // webhook, an issue tracker). Independent of channels(): an integration may\n // publish without owning a chat channel. READY integrations only — the\n // array is held by reference by CommentsDomain (see `feedPublishers` above),\n // so pushing here wires the publisher into comment dispatch.\n for (const { integration } of integrationRegistrations.filter(\n ({ integration, ready }) => ready && integration.feedPublisher,\n )) {\n const context = buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n const publisher = integration.feedPublisher!(context);\n if (publisher) feedPublishers.push(publisher);\n }\n\n // Integration lifecycle workers (e.g. polling an upstream without\n // webhooks): collected from READY integrations only, folded into the\n // constructor args so `new Mastra(...)` merges them with the default\n // workers and `finalize()`'s `startWorkers()` starts them alongside the\n // built-ins. Never passed for the disabled/not-ready case — a worker for\n // an unavailable integration must not run.\n const integrationWorkers = integrationRegistrations\n .filter(({ integration, ready }) => ready && integration.workers)\n .flatMap(({ integration }) =>\n integration.workers!(\n buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n sandbox: sandboxConfig,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n integrations: integrationRegistrations,\n configVersion,\n boardRegistry: this.#boards,\n factoryReady,\n domains,\n feed: commentsDomain,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n ),\n ),\n );\n\n return {\n ...prepared.mastraArgs,\n // Same provider on `studio.auth` as on `server.auth` (buildServerConfig):\n // deployed factories must authenticate BOTH plain API callers and Studio\n // requests (`x-mastra-client-type: studio` routes to `studio.auth`).\n ...(auth ? { studio: { auth } } : {}),\n ...(integrationWorkers.length > 0 ? { workers: integrationWorkers } : {}),\n ...(environmentBuilds ? { workflows: { [ENVIRONMENT_BUILD_WORKFLOW_ID]: environmentBuilds.workflow } } : {}),\n };\n }\n\n /**\n * Post-construct boot: initialize the controller (which inherits the\n * constructed Mastra's storage) and start its workers. Call AFTER the entry\n * has run `new Mastra(prepare()'s args)`.\n */\n async finalize(): Promise<void> {\n if (!this.#prepared) {\n throw new Error('MastraFactory.finalize() called before prepare()');\n }\n await timedPhase('finalize.controller', () => this.#prepared!.finalize());\n await this.#environmentBuilds?.probeSchedules();\n await timedPhase(\n 'finalize.reconcileBoundThreads',\n () => this.#factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n );\n // A thread's messages move before its run binding does, so a reconcile that\n // overlapped the migration can miss them. Catch up once the bindings moved.\n void this.#sessionResourceMigration\n ?.then(movedRunBindings => (movedRunBindings ? this.#factoryProcessor?.reconcileAllBoundThreads() : undefined))\n .catch(error =>\n console.warn(\n `[factory] reconciling bound threads after the session resource migration failed: ${error instanceof Error ? error.message : error}`,\n ),\n );\n this.#dispatcher?.start();\n }\n\n /** Stop Factory-owned background work and channel transports before the host process shuts down. */\n async shutdown(): Promise<void> {\n if (this.#shutdownPromise) return this.#shutdownPromise;\n\n const channelShutdowns = this.#channelShutdowns;\n this.#channelShutdowns = [];\n const shutdownPromise = (async () => {\n const results = await Promise.allSettled([\n this.#dispatcher?.stop() ?? Promise.resolve(),\n ...channelShutdowns.map(async shutdown => shutdown()),\n ]);\n results.slice(1).forEach((result, index) => {\n if (result.status === 'rejected') this.#channelShutdowns.push(channelShutdowns[index]!);\n });\n const failure = results.find(result => result.status === 'rejected');\n if (failure) throw failure.reason;\n })();\n this.#shutdownPromise = shutdownPromise;\n try {\n await shutdownPromise;\n } finally {\n if (this.#shutdownPromise === shutdownPromise) this.#shutdownPromise = undefined;\n }\n }\n}\n"],"mappings":"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"}