@mastra/factory 0.7.1-alpha.5 → 0.8.0-alpha.11
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.
- package/CHANGELOG.md +70 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +22 -16
- package/dist/factory.js.map +1 -1
- package/dist/integrations/base.d.ts +3 -0
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/integration.d.ts +9 -0
- package/dist/integrations/github/integration.d.ts.map +1 -1
- package/dist/integrations/github/integration.js +8 -1
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/routes.d.ts +1 -0
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +48 -21
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/sandbox-release.d.ts +2 -1
- package/dist/integrations/github/sandbox-release.d.ts.map +1 -1
- package/dist/integrations/github/sandbox-release.js +1 -1
- package/dist/integrations/github/sandbox-release.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +17 -21
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +26 -8
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/github/webhook.d.ts +19 -0
- package/dist/integrations/github/webhook.d.ts.map +1 -1
- package/dist/integrations/github/webhook.js +43 -9
- package/dist/integrations/github/webhook.js.map +1 -1
- package/dist/integrations/linear/integration.d.ts +2 -1
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/integration.js +2 -1
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/routes.d.ts +10 -0
- package/dist/integrations/linear/routes.d.ts.map +1 -1
- package/dist/integrations/linear/routes.js +35 -1
- package/dist/integrations/linear/routes.js.map +1 -1
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/github/event-worker.js +12 -3
- package/dist/integrations/platform/github/event-worker.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts +5 -0
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +7 -0
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.js +1 -0
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +2 -0
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/intake.d.ts +15 -0
- package/dist/routes/intake.d.ts.map +1 -1
- package/dist/routes/intake.js +65 -2
- package/dist/routes/intake.js.map +1 -1
- package/dist/routes/projects.d.ts +3 -0
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +41 -10
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/surface.d.ts +1 -0
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +1 -0
- package/dist/routes/surface.js.map +1 -1
- package/dist/rules/start-coordinator.js +1 -1
- package/dist/sandbox/session-retirement.d.ts +40 -0
- package/dist/sandbox/session-retirement.d.ts.map +1 -0
- package/dist/sandbox/session-retirement.js +221 -0
- package/dist/sandbox/session-retirement.js.map +1 -0
- package/dist/session/filesystem-capture.d.ts +7 -0
- package/dist/session/filesystem-capture.d.ts.map +1 -1
- package/dist/session/filesystem-capture.js +41 -4
- package/dist/session/filesystem-capture.js.map +1 -1
- package/dist/storage/domains/intake/base.d.ts +36 -0
- package/dist/storage/domains/intake/base.d.ts.map +1 -1
- package/dist/storage/domains/intake/base.js +91 -2
- package/dist/storage/domains/intake/base.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +6 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +11 -0
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +3 -0
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +2 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +43 -0
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +54 -8
- package/dist/workspace.js.map +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,75 @@
|
|
|
1
1
|
# @mastra/factory
|
|
2
2
|
|
|
3
|
+
## 0.8.0-alpha.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`b860493`](https://github.com/mastra-ai/mastra/commit/b86049391100e665d579f700c8a2034c036defc3)]:
|
|
8
|
+
- @mastra/core@1.60.0-alpha.10
|
|
9
|
+
- @mastra/code-sdk@1.3.0-alpha.10
|
|
10
|
+
|
|
11
|
+
## 0.8.0-alpha.10
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`b0a2a07`](https://github.com/mastra-ai/mastra/commit/b0a2a07800d42bd9823292e7db832374ed084c9c), [`ccbbcd9`](https://github.com/mastra-ai/mastra/commit/ccbbcd974eedff4367a54ed0e24c9ee742ab2f61), [`3f5c6f7`](https://github.com/mastra-ai/mastra/commit/3f5c6f728ea35da344248de9aa070f12849f3aa0), [`77e6b1b`](https://github.com/mastra-ai/mastra/commit/77e6b1bc4c46ce94fe501023fb4393c812ec6be3), [`2e1d098`](https://github.com/mastra-ai/mastra/commit/2e1d0984e325fd319d32ea182f596b3170be3847)]:
|
|
16
|
+
- @mastra/core@1.60.0-alpha.9
|
|
17
|
+
- @mastra/code-sdk@1.3.0-alpha.9
|
|
18
|
+
|
|
19
|
+
## 0.8.0-alpha.9
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- Added a configurable allowlist of reviewer bots that can trigger GitHub review and comment notifications. Set MASTRACODE_GITHUB_AUTHORIZED_BOTS (comma-separated logins) or pass authorizedBots to GithubIntegration to trust bots beyond the built-in defaults; previously only coderabbitai[bot] and devin-ai-integration[bot] were accepted and every other bot was dropped without a log line. Bot logins now match case-insensitively and rejected senders are logged. Fixes #21621 ([#21697](https://github.com/mastra-ai/mastra/pull/21697))
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Fixed the Factory chat transcript drawing the same content twice after coming back to a tab. While a run streams, leaving the tab drops the event stream and the transcript refetches on return: an assistant reply the server had persisted as its own step, and a steer whose live event was missed, both landed on screen a second time. The refetched window is now paired against what is already drawn — by message id, by tool call, then by the text itself — so it only inserts what is genuinely missing. ([#21651](https://github.com/mastra-ai/mastra/pull/21651))
|
|
28
|
+
|
|
29
|
+
Also fixed a tool call rendering as two half-filled cards when a steer interrupted it: live tool state followed the newest assistant message instead of staying with the call it belongs to.
|
|
30
|
+
|
|
31
|
+
- The turn-end filesystem capture no longer blocks agent turn completion. Readers of the persisted workspace file listing wait up to 10 seconds for the in-flight capture to observe the just-ended turn's files; if a capture takes longer, a reader can temporarily receive the previous listing. ([#21679](https://github.com/mastra-ai/mastra/pull/21679))
|
|
32
|
+
|
|
33
|
+
- Fixed Linear intake so issues only land in the Factory project their Linear project is routed to. Previously, opening any board pulled in every selected Linear project's open issues and auto-triaged them there, repeating for each Factory project you viewed. ([#21698](https://github.com/mastra-ai/mastra/pull/21698))
|
|
34
|
+
|
|
35
|
+
**Routing Linear projects**
|
|
36
|
+
|
|
37
|
+
In Settings › Intake, each selected Linear project now picks the Factory it feeds. A project left unrouted no longer feeds any board, and boards only show the Linear intake feed for projects routed to them. Organizations with a single Factory keep working with no configuration.
|
|
38
|
+
|
|
39
|
+
**Deleted cards stay deleted**
|
|
40
|
+
|
|
41
|
+
Removing an intake card now also clears the stored routing decision behind it, so it no longer reappears on the next intake poll.
|
|
42
|
+
|
|
43
|
+
Fixes #21614
|
|
44
|
+
|
|
45
|
+
- Updated dependencies [[`4e7a421`](https://github.com/mastra-ai/mastra/commit/4e7a421dce8a48742f785d1e93ad2f43a572b282), [`242e324`](https://github.com/mastra-ai/mastra/commit/242e3241e73cbd5c9bb86a31ebb49ca0256488d4), [`217e967`](https://github.com/mastra-ai/mastra/commit/217e9672d8b3160eb729d8e9f0044949e88da239), [`d774e89`](https://github.com/mastra-ai/mastra/commit/d774e8930c781df8c9effe3763e6b501c099b6cc), [`9c27a53`](https://github.com/mastra-ai/mastra/commit/9c27a53cd9d3de4f3f025bc387d94ce371c33f95), [`3a634e9`](https://github.com/mastra-ai/mastra/commit/3a634e9b32e3c47db3f287292ce37e862a02e005), [`dff25a1`](https://github.com/mastra-ai/mastra/commit/dff25a1103fa72ee082a9b6f805ebeb5ce400753), [`217e967`](https://github.com/mastra-ai/mastra/commit/217e9672d8b3160eb729d8e9f0044949e88da239), [`7f78585`](https://github.com/mastra-ai/mastra/commit/7f785857e401570e2ffb316911f126ed363aa537), [`f2a4afd`](https://github.com/mastra-ai/mastra/commit/f2a4afd7e37e809669001ed17724b341a5c1f45e), [`d438148`](https://github.com/mastra-ai/mastra/commit/d438148e222c1e2fb3c652725ce75680962ebec4), [`ba05fe0`](https://github.com/mastra-ai/mastra/commit/ba05fe0738f70cb686777546e968237d09269142), [`d26a8d4`](https://github.com/mastra-ai/mastra/commit/d26a8d4281f28414715b333c85bedaf70d0b2890), [`677cdc6`](https://github.com/mastra-ai/mastra/commit/677cdc6af564dec29a13464d12b7ab2a4efc22e9), [`a318490`](https://github.com/mastra-ai/mastra/commit/a318490e17da32f338d50929c770d901a9b3dd72), [`763e0c6`](https://github.com/mastra-ai/mastra/commit/763e0c61e04d76ad9a9efd301aa57525ca0cbea9), [`298aafd`](https://github.com/mastra-ai/mastra/commit/298aafd70d7fea6517b6e2a4b55f3ef9e824d96b), [`23e0be2`](https://github.com/mastra-ai/mastra/commit/23e0be261381e49534b4ff3101c60ee64a946cbf), [`7fc8806`](https://github.com/mastra-ai/mastra/commit/7fc880627d3cbf995d31ea0e8b807bf15417e651), [`0e02eac`](https://github.com/mastra-ai/mastra/commit/0e02eacdb2e30e1697a41910b41163742a181dc1), [`4df174c`](https://github.com/mastra-ai/mastra/commit/4df174c32bddf093a82f273070b8380aef7c9e90), [`f7c25b5`](https://github.com/mastra-ai/mastra/commit/f7c25b5106ddfb48e591f98df7a51e0f2dd01dba), [`dc09cc1`](https://github.com/mastra-ai/mastra/commit/dc09cc1083d861cde192c1cd235324dc75b8c731), [`36b4649`](https://github.com/mastra-ai/mastra/commit/36b4649045a3a380cbab8ceca866db4086223aff), [`377eb81`](https://github.com/mastra-ai/mastra/commit/377eb81ce43b964e3a6b541df172da74a8ff3716)]:
|
|
46
|
+
- @mastra/core@1.60.0-alpha.8
|
|
47
|
+
- @mastra/code-sdk@1.3.0-alpha.8
|
|
48
|
+
|
|
49
|
+
## 0.8.0-alpha.8
|
|
50
|
+
|
|
51
|
+
### Patch Changes
|
|
52
|
+
|
|
53
|
+
- Updated dependencies [[`940bf5c`](https://github.com/mastra-ai/mastra/commit/940bf5ccf04f2c9ebd8a1390431733222a03b1cd)]:
|
|
54
|
+
- @mastra/core@1.60.0-alpha.7
|
|
55
|
+
- @mastra/code-sdk@1.2.2-alpha.7
|
|
56
|
+
|
|
57
|
+
## 0.8.0-alpha.7
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- Fixed Linear issue reconciliation for issues that are not assigned to a project. ([#21601](https://github.com/mastra-ai/mastra/pull/21601))
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [[`0b4f108`](https://github.com/mastra-ai/mastra/commit/0b4f1089aa8d92e67c2a8e99726822c5ee410784), [`88ddc7c`](https://github.com/mastra-ai/mastra/commit/88ddc7ce01d40175f13a3228b789a906779680bd), [`a7dd322`](https://github.com/mastra-ai/mastra/commit/a7dd32247d95afc539f483ca37f4594af0387f59)]:
|
|
64
|
+
- @mastra/core@1.60.0-alpha.6
|
|
65
|
+
- @mastra/code-sdk@1.2.2-alpha.6
|
|
66
|
+
|
|
67
|
+
## 0.8.0-alpha.6
|
|
68
|
+
|
|
69
|
+
### Minor Changes
|
|
70
|
+
|
|
71
|
+
- Add per-repository worktree teardown commands and run them during terminal, explicit, and destructive Factory session cleanup. ([#21564](https://github.com/mastra-ai/mastra/pull/21564))
|
|
72
|
+
|
|
3
73
|
## 0.7.1-alpha.5
|
|
4
74
|
|
|
5
75
|
### Patch Changes
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,OAAO,KAAK,EAAE,kBAAkB,EAAgD,MAAM,wBAAwB,CAAC;AAmB/G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAiCrD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAClC;;;;;;;OAOG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,mDAAmD;IACnD,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwFD,qBAAa,aAAa;;gBAOZ,MAAM,EAAE,mBAAmB;IAWvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAgmBpC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAY/B,iFAAiF;IAC3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
package/dist/factory.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { timedPhase } from "./timing.js";
|
|
2
2
|
import { buildAuthRoutes, createFactoryAuthGate, createFactoryRouteAuth, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
|
|
3
3
|
import { recordFactoryPullRequestProvenance } from "./integrations/github/provenance.js";
|
|
4
|
-
import { SandboxFleet } from "./sandbox/fleet.js";
|
|
5
|
-
import { releaseWorkItemSandboxes } from "./integrations/github/sandbox-release.js";
|
|
6
4
|
import { assertFactoryRules } from "./rules/validation.js";
|
|
5
|
+
import { SandboxFleet } from "./sandbox/fleet.js";
|
|
7
6
|
import { PlatformGithubIntegration } from "./integrations/platform/github/integration.js";
|
|
8
7
|
import { PlatformLinearIntegration } from "./integrations/platform/linear/integration.js";
|
|
9
8
|
import { createCustomProvidersPrimer, registerCustomProvidersSource } from "./routes/custom-provider-source.js";
|
|
10
9
|
import { ProjectRoutes } from "./routes/projects.js";
|
|
11
10
|
import { hydrateSessionMemorySettings } from "./session/memory-settings-hydration.js";
|
|
12
11
|
import { FactoryTransitionService } from "./rules/transition-service.js";
|
|
12
|
+
import { observeSessionFilesystem } from "./session/filesystem-capture.js";
|
|
13
13
|
import { ModelCredentialsStorage } from "./storage/domains/credentials/base.js";
|
|
14
|
-
import { createWorkspaceFactory } from "./workspace.js";
|
|
14
|
+
import { FactoryWorkspaceRegistry, createWorkspaceFactory } from "./workspace.js";
|
|
15
15
|
import { createTenantCredentialPrimer, primeTenantCredentials, registerTenantCredentialResolver } from "./routes/tenant-credentials.js";
|
|
16
16
|
import { QueueHealthStorage } from "./storage/domains/queue-health/base.js";
|
|
17
17
|
import { WorkItemsStorage } from "./storage/domains/work-items/base.js";
|
|
@@ -21,9 +21,9 @@ import { FactoryDecisionDispatcher } from "./rules/dispatcher.js";
|
|
|
21
21
|
import { FactoryPhaseStateProcessor } from "./rules/processor.js";
|
|
22
22
|
import { createFactoryTransitionTools } from "./rules/tools.js";
|
|
23
23
|
import { registerSandboxReattach } from "./sandbox/reattach.js";
|
|
24
|
+
import { SessionRetirementCoordinator } from "./sandbox/session-retirement.js";
|
|
24
25
|
import { handleServerError } from "./server-error.js";
|
|
25
26
|
import { observeSessionCheckpoint } from "./session/checkpoint-capture.js";
|
|
26
|
-
import { observeSessionFilesystem } from "./session/filesystem-capture.js";
|
|
27
27
|
import { observeSessionFirstExec } from "./session/first-exec-capture.js";
|
|
28
28
|
import { observeSessionFirstMessage } from "./session/first-message-capture.js";
|
|
29
29
|
import { createSpaStaticMiddleware, resolveUiDistDir } from "./spa-static.js";
|
|
@@ -44,7 +44,6 @@ import { hasAuthInit, isUserProvider } from "@mastra/core/server";
|
|
|
44
44
|
import { MastraAuthStudio } from "@mastra/auth-studio";
|
|
45
45
|
import { prepareAgentControllerMount } from "@mastra/code-sdk";
|
|
46
46
|
import { AgentControllerChannels } from "@mastra/core/channels";
|
|
47
|
-
import { LocalSandbox } from "@mastra/core/workspace";
|
|
48
47
|
//#region src/factory.ts
|
|
49
48
|
/**
|
|
50
49
|
* `MastraFactory` — the single entry point to the whole Mastra Software Factory.
|
|
@@ -195,12 +194,6 @@ var MastraFactory = class {
|
|
|
195
194
|
workItems: workItemsStorage,
|
|
196
195
|
channelIdentity: storage.registerDomain(new ChannelIdentityStorage())
|
|
197
196
|
};
|
|
198
|
-
const projectRoutes = new ProjectRoutes({
|
|
199
|
-
auth: routeAuth,
|
|
200
|
-
projects: factoryProjectsStorage,
|
|
201
|
-
sourceControl: sourceControlStorage,
|
|
202
|
-
versionControlIntegrationIds: integrations.filter((integration) => integration.versionControl).map((integration) => integration.id)
|
|
203
|
-
});
|
|
204
197
|
const auditDomain = new AuditDomain({
|
|
205
198
|
auth: routeAuth,
|
|
206
199
|
audit: auditStorage,
|
|
@@ -224,6 +217,7 @@ var MastraFactory = class {
|
|
|
224
217
|
maxSandboxes: sandboxConfig?.maxSandboxes
|
|
225
218
|
} : void 0);
|
|
226
219
|
registerSandboxReattach(fleet);
|
|
220
|
+
const workspaceRegistry = new FactoryWorkspaceRegistry();
|
|
227
221
|
const stateSigner = createStateSigner(this.#config.stateSecret);
|
|
228
222
|
if (auth && hasAuthInit(auth)) await timedPhase("prepare.auth.init", () => auth.init({
|
|
229
223
|
database: storage.authDatabase?.(),
|
|
@@ -262,18 +256,28 @@ var MastraFactory = class {
|
|
|
262
256
|
const factoryReady = storage.isDomainReady("projects") && storage.isDomainReady("work-items");
|
|
263
257
|
const githubIntegration = integrations.find((integration) => integration.id === "github");
|
|
264
258
|
const workItemsReady = storage.isDomainReady("work-items");
|
|
265
|
-
const
|
|
266
|
-
workItems: workItemsStorage,
|
|
267
|
-
sourceControl: sourceControlStorage.forIntegration("github"),
|
|
259
|
+
const sessionRetirement = machine && storage.isDomainReady("source-control") ? new SessionRetirementCoordinator({
|
|
268
260
|
fleet,
|
|
261
|
+
invalidateSession: (sessionId) => workspaceRegistry.invalidateSession(sessionId)
|
|
262
|
+
}) : void 0;
|
|
263
|
+
const retireTerminalSessions = sessionRetirement && githubIntegration && workItemsReady ? async ({ orgId, workItemId }) => sessionRetirement.retireWorkItemSessions({
|
|
264
|
+
workItems: workItemsStorage,
|
|
265
|
+
sourceControl: sourceControlStorage.forIntegration(githubIntegration.id),
|
|
269
266
|
orgId,
|
|
270
267
|
workItemId
|
|
271
268
|
}) : void 0;
|
|
272
269
|
const transitionService = workItemsReady ? new FactoryTransitionService({
|
|
273
270
|
rules,
|
|
274
271
|
storage: workItemsStorage,
|
|
275
|
-
...
|
|
272
|
+
...retireTerminalSessions ? { onTerminalStage: retireTerminalSessions } : {}
|
|
276
273
|
}) : void 0;
|
|
274
|
+
const projectRoutes = new ProjectRoutes({
|
|
275
|
+
auth: routeAuth,
|
|
276
|
+
projects: factoryProjectsStorage,
|
|
277
|
+
sourceControl: sourceControlStorage,
|
|
278
|
+
versionControlIntegrationIds: integrations.filter((integration) => integration.versionControl).map((integration) => integration.id),
|
|
279
|
+
...sessionRetirement ? { sessionRetirement } : {}
|
|
280
|
+
});
|
|
277
281
|
const factoryProcessor = workItemsReady ? new FactoryPhaseStateProcessor({
|
|
278
282
|
rules,
|
|
279
283
|
storage: workItemsStorage,
|
|
@@ -301,7 +305,8 @@ var MastraFactory = class {
|
|
|
301
305
|
...this.#config.sandbox ? { sandbox: this.#config.sandbox } : {},
|
|
302
306
|
...githubIntegration ? { github: githubIntegration } : {},
|
|
303
307
|
...workItemsStorage ? { workItems: workItemsStorage } : {},
|
|
304
|
-
fleet
|
|
308
|
+
fleet,
|
|
309
|
+
workspaceRegistry
|
|
305
310
|
}),
|
|
306
311
|
disableGithubSignals: true,
|
|
307
312
|
disableSettingsOmSeed: true,
|
|
@@ -374,6 +379,7 @@ var MastraFactory = class {
|
|
|
374
379
|
publicOrigin,
|
|
375
380
|
stateSigner,
|
|
376
381
|
fleet,
|
|
382
|
+
sessionRetirement,
|
|
377
383
|
factoryStorage: storage,
|
|
378
384
|
integrationStorage,
|
|
379
385
|
sourceControlStorage,
|
package/dist/factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","names":["#config","#preparing","#dispatcher","#prepared","#factoryProcessor"],"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 and Linear integrations when\n * Platform credentials exist and the caller did not 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 { AgentControllerChannels } from '@mastra/core/channels';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { 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 { LocalSandbox } from '@mastra/core/workspace';\nimport type { WorkspaceSandbox } from '@mastra/core/workspace';\nimport {\n buildAuthRoutes,\n createFactoryAuthGate,\n createFactoryRouteAuth,\n getFactoryAuthOrgId,\n getFactoryAuthUserFromContext,\n getFactoryAuthUserId,\n} from './auth.js';\nimport type { FactoryIntegration, IntegrationPostToolContext, IntegrationTools } from './integrations/base.js';\nimport type { GithubIntegration } from './integrations/github/integration.js';\nimport { recordFactoryPullRequestProvenance } from './integrations/github/provenance.js';\nimport { releaseWorkItemSandboxes } from './integrations/github/sandbox-release.js';\nimport { PlatformGithubIntegration } from './integrations/platform/github/integration.js';\nimport { PlatformLinearIntegration } from './integrations/platform/linear/integration.js';\nimport { createCustomProvidersPrimer, registerCustomProvidersSource } from './routes/custom-provider-source.js';\nimport { ProjectRoutes } from './routes/projects.js';\nimport { assembleFactoryApiRoutes, buildIntegrationContext } from './routes/surface.js';\nimport type { FactoryApiRoutesDeps } from './routes/surface.js';\nimport {\n createTenantCredentialPrimer,\n primeTenantCredentials,\n registerTenantCredentialResolver,\n} from './routes/tenant-credentials.js';\nimport { builtInFactoryRules } from './rules/defaults.js';\nimport { FactoryDecisionDispatcher } from './rules/dispatcher.js';\nimport { FactoryPhaseStateProcessor } from './rules/processor.js';\nimport { createFactoryTransitionTools } from './rules/tools.js';\nimport { FactoryTransitionService } from './rules/transition-service.js';\nimport type { FactoryRules } from './rules/types.js';\nimport { assertFactoryRules } from './rules/validation.js';\nimport { SandboxFleet } from './sandbox/fleet.js';\nimport { registerSandboxReattach } from './sandbox/reattach.js';\nimport { handleServerError } from './server-error.js';\nimport { observeSessionCheckpoint } from './session/checkpoint-capture.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 { hydrateSessionMemorySettings } from './session/memory-settings-hydration.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 { 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 { MemorySettingsStorage } from './storage/domains/memory-settings/base.js';\nimport { ModelPacksStorage } from './storage/domains/model-packs/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 { timedPhase } from './timing.js';\nimport { createWorkspaceFactory } 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 * 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 * 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 /** Sandbox configuration. Omitted → repository sandboxes are disabled. */\n sandbox?: MastraFactorySandboxConfig;\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 * 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` and\n * `linear` integrations default to their Platform-backed implementations.\n */\n integrations?: FactoryIntegration[];\n /**\n * Authoritative Factory board, tool-result, and GitHub-event rules. Construct\n * with `defaultFactoryRules({ version, overrides })` so deployment policy has\n * an explicit version and exact handler leaves replace rather than compose.\n * Omitted → conservative built-in rules for the current deployment.\n */\n rules?: FactoryRules;\n\n /**\n * Platform-specific overrides. `githubAppSlug` identifies Factory's own\n * GitHub App writes so their webhook deliveries do not retrigger triage.\n */\n platform?: {\n githubAppSlug?: string;\n };\n}\n\nexport interface MastraFactorySandboxConfig {\n /**\n * Template machine — `RailwaySandbox` (`@mastra/railway`), core\n * `LocalSandbox` (`@mastra/core/workspace`), or any `WorkspaceSandbox` that\n * implements `clone()`. Each project-repository execution environment gets\n * its own sandbox cloned from this machine; the machine itself is never\n * started. `prepare()` fails fast when the instance lacks `clone()`.\n */\n machine: WorkspaceSandbox;\n /**\n * In-sandbox base directory repos check out under (nested `owner/name` per\n * repo). Default: the machine's own `workingDirectory` when it exposes one\n * (core `LocalSandbox` does), else `/workspace`.\n */\n workdir?: string;\n /**\n * Per-replica cap on concurrently provisioned sandboxes. `0`/omitted means\n * unlimited. A lightweight per-process budget, not a cross-replica scheduler.\n */\n maxSandboxes?: number;\n}\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\nfunction hasPlatformSecretKey(): boolean {\n return Boolean(process.env.MASTRA_PLATFORM_SECRET_KEY?.trim());\n}\n\n/**\n * The template sandbox's own working directory, when it exposes one as a\n * string (core `LocalSandbox` does; remote providers generally don't).\n * Used as the default checkout base so a local template rooted at a host\n * directory checks repos out under that same root.\n */\nfunction templateWorkingDirectory(sandbox: WorkspaceSandbox): string | undefined {\n const wd = (sandbox as { workingDirectory?: unknown }).workingDirectory;\n return typeof wd === 'string' && wd.length > 0 ? wd : undefined;\n}\n\nfunction resolveSandboxWorkdirBase(machine: WorkspaceSandbox, configuredWorkdir?: string): string {\n const machineWorkdir = templateWorkingDirectory(machine);\n const workdir =\n configuredWorkdir === '/workspace' && machineWorkdir ? machineWorkdir : (configuredWorkdir ?? machineWorkdir);\n return (workdir ?? '/workspace').replace(/\\/+$/, '');\n}\n\n/**\n * Default auth provider — `MastraAuthStudio`, which proxies identity to the\n * shared Mastra platform API. `MastraAuthStudio` resolves `MASTRA_SHARED_API_URL`,\n * `MASTRA_ORGANIZATION_ID`, and `MASTRA_COOKIE_DOMAIN` from env on its own —\n * this helper only derives a cookie-domain fallback from the factory's\n * `publicUrl`.\n *\n * Cookie-domain resolution (Studio picks the first that wins):\n * 1. explicit `MASTRA_COOKIE_DOMAIN` env, if set;\n * 2. `.mastra.ai` when `sharedApiUrl` is on `.mastra.ai`;\n * 3. this parent-domain fallback derived from `publicUrl` — so a deploy on\n * `https://foo.mastra.cloud` mints cookies with `Domain=.mastra.cloud`\n * without the caller wiring the env var by hand.\n * 4. otherwise host-only (no `Domain=`), which is correct for `localhost`.\n */\nfunction buildDefaultStudioAuth(publicUrl: string): IMastraAuthProvider {\n return new MastraAuthStudio({\n cookieDomain: parentDomainFromPublicUrl(publicUrl),\n });\n}\n\n/**\n * Derive a parent cookie domain from `publicUrl` by stripping the leftmost\n * label — the same shape platform-API's env injection uses (see\n * `platform/servers/api/src/lib/studio-env-vars.ts`: `.${routingDomain.replace(/^[^.]+\\./, '')}`).\n *\n * Rather than a generic `strip-left-label` heuristic — which either emits\n * cookies scoped to a public suffix (`sub.example.co.uk` → `.example.co.uk`\n * requires PSL data to be safe) or misclassifies numeric hostnames like\n * `3scale.example.com` as IPv4 — we only derive a parent domain when the\n * host sits under one of the platform's known registrable domains. Anything\n * else (custom domains, arbitrary tenant hostnames, IPs, `localhost`)\n * falls through to host-only cookies. Callers that need a different scope\n * pass `MASTRA_COOKIE_DOMAIN` explicitly (Studio honors that first).\n */\nconst KNOWN_PLATFORM_COOKIE_PARENTS = ['mastra.cloud', 'mastra.ai'] as const;\n\nfunction isIpLiteral(hostname: string): boolean {\n // IPv6 addresses in URLs are bracketed; `URL.hostname` strips the brackets\n // but the address itself still contains `:`. IPv4 is four dot-separated\n // numeric octets — trust the parser to have already validated shape.\n if (hostname.includes(':')) return true;\n return /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n}\n\nfunction parentDomainFromPublicUrl(publicUrl: string): string | undefined {\n let hostname: string;\n try {\n hostname = new URL(publicUrl).hostname.toLowerCase();\n } catch {\n return undefined;\n }\n if (hostname === 'localhost' || isIpLiteral(hostname)) return undefined;\n for (const parent of KNOWN_PLATFORM_COOKIE_PARENTS) {\n // Exact match → we're already on the parent, host-only is correct.\n // Subdomain match → mint the parent-scoped cookie.\n if (hostname === parent) return undefined;\n if (hostname.endsWith(`.${parent}`)) return `.${parent}`;\n }\n return undefined;\n}\n\nexport class MastraFactory {\n readonly #config: MastraFactoryConfig;\n #prepared: Awaited<ReturnType<typeof prepareAgentControllerMount>> | undefined;\n #dispatcher: FactoryDecisionDispatcher | undefined;\n #factoryProcessor: FactoryPhaseStateProcessor | 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.#config = config;\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 = this.#config.storage;\n const vector = this.#config.vector;\n const pubsub = this.#config.pubsub;\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(publicOrigin));\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\n // Explicit integrations win. Platform credentials fill only missing GitHub\n // and Linear slots so callers can override either provider independently.\n const integrations = [...(this.#config.integrations ?? [])];\n if (hasPlatformSecretKey()) {\n if (!integrations.some(integration => integration.id === 'github')) {\n integrations.push(new PlatformGithubIntegration({ slug: this.#config.platform?.githubAppSlug }));\n }\n if (!integrations.some(integration => integration.id === 'linear')) {\n integrations.push(new PlatformLinearIntegration());\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 rules = this.#config.rules ?? builtInFactoryRules();\n assertFactoryRules(rules);\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 const modelCredentialsStorage = storage.registerDomain(new ModelCredentialsStorage());\n const modelPacksStorage = storage.registerDomain(new ModelPacksStorage());\n const memorySettingsStorage = storage.registerDomain(new MemorySettingsStorage());\n const customProvidersStorage = storage.registerDomain(new CustomProvidersStorage());\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());\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 // 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 modelPacks: modelPacksStorage,\n memorySettings: memorySettingsStorage,\n customProviders: customProvidersStorage,\n filesystem: filesystemStorage,\n projects: factoryProjectsStorage,\n queueHealth: queueHealthStorage,\n workItems: workItemsStorage,\n channelIdentity: channelIdentityStorage,\n };\n const projectRoutes = new ProjectRoutes({\n auth: routeAuth,\n projects: factoryProjectsStorage,\n sourceControl: sourceControlStorage,\n versionControlIntegrationIds: integrations\n .filter(integration => integration.versionControl)\n .map(integration => integration.id),\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\n // Repository execution needs one sandbox per project-repository link,\n // cloned from the configured machine. A machine without `clone()` would\n // only fail on first use, so fail fast at boot instead.\n const sandboxConfig = this.#config.sandbox;\n const machine = sandboxConfig?.machine;\n if (machine && typeof machine.clone !== 'function') {\n throw new Error(\n `MastraFactory: the configured sandbox machine (provider '${machine.provider}') does not implement clone(). ` +\n `Project repositories each get their own sandbox cloned from the configured machine. ` +\n `Pass a machine that implements clone() — e.g. RailwaySandbox (@mastra/railway) or ` +\n `LocalSandbox (@mastra/core/workspace) — or omit 'sandbox' to disable sandboxes.`,\n );\n }\n\n // One sandbox fleet per boot: constructed with the machine config when\n // sandboxes are configured, disabled otherwise. Handed to integrations\n // through the IntegrationContext — no global registry.\n const fleet = new SandboxFleet(\n machine\n ? {\n machine,\n workdirBase: resolveSandboxWorkdirBase(machine, sandboxConfig?.workdir),\n maxSandboxes: sandboxConfig?.maxSandboxes,\n }\n : undefined,\n );\n // Core's `getDynamicWorkspace` reattaches project sandboxes through the\n // SDK seam; only this factory owns the fleet, so register it here.\n registerSandboxReattach(fleet);\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 if (auth) {\n registerTenantCredentialResolver(modelCredentialsStorage);\n }\n\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 integration.initialize?.({\n storage: integrationStorage.forIntegration(integration.id),\n projects: factoryProjectsStorage,\n auth: routeAuth,\n });\n if (integration.versionControl) {\n integration.versionControl.initialize({\n storage: sourceControlStorage.forIntegration(integration.id),\n });\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 const githubIntegration = integrations.find(integration => integration.id === 'github') as\n | GithubIntegration\n | undefined;\n const workItemsReady = storage.isDomainReady('work-items');\n // Terminal work items release their session sandboxes back to the reuse\n // pool so the next session for the same repository/user claims a warm VM\n // instead of provisioning fresh. Remote providers only: local \"sandboxes\"\n // are the host machine with per-session workdirs — nothing to pool.\n const releaseTerminalSandboxes =\n machine && !(machine instanceof LocalSandbox) && workItemsReady && storage.isDomainReady('source-control')\n ? async ({ orgId, workItemId }: { orgId: string; workItemId: string }) =>\n releaseWorkItemSandboxes({\n workItems: workItemsStorage,\n sourceControl: sourceControlStorage.forIntegration('github'),\n fleet,\n orgId,\n workItemId,\n })\n : undefined;\n const transitionService = workItemsReady\n ? new FactoryTransitionService({\n rules,\n storage: workItemsStorage,\n ...(releaseTerminalSandboxes ? { onTerminalStage: releaseTerminalSandboxes } : {}),\n })\n : undefined;\n const factoryProcessor = workItemsReady\n ? new FactoryPhaseStateProcessor({\n rules,\n storage: workItemsStorage,\n ...(transitionService ? { transitionService } : {}),\n ...(githubIntegration\n ? {\n recordPullRequestProvenance: (input: Parameters<typeof recordFactoryPullRequestProvenance>[3]) =>\n recordFactoryPullRequestProvenance(\n githubIntegration,\n sourceControlStorage.forIntegration('github'),\n integrationStorage.forIntegration('github'),\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 // 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\n // Build the real production controller (agents, modes, tools, memory, OM,\n // MCP, providers) — identical to the terminal app. 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 workspace: createWorkspaceFactory({\n ...(this.#config.sandbox ? { sandbox: this.#config.sandbox } : {}),\n ...(githubIntegration ? { github: githubIntegration } : {}),\n ...(workItemsStorage ? { workItems: workItemsStorage } : {}),\n fleet,\n }),\n disableGithubSignals: true,\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 // 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 initialState: { skipGlobalInstructions: true },\n storage: storage.getMastraStorage(),\n ...(mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {}),\n ...(factoryProcessor ? { inputProcessors: [factoryProcessor] } : {}),\n ...(vector ? { vector } : {}),\n ...(toolIntegrations.length > 0 || (workItemsStorage && transitionService)\n ? {\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 (workItemsStorage && transitionService) {\n mergeTools(\n 'factory',\n await createFactoryTransitionTools({\n requestContext,\n storage: workItemsStorage,\n transitionService,\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')\n ? { sessions: sourceControlStorage.forIntegration('github').sessions }\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 }\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 });\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/*`.\n ...(auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : []),\n // Custom `/web/*` routes (fs / config / integrations / factory / audit).\n ...assembleFactoryApiRoutes({\n controllerId: CONTROLLER_ID,\n controller,\n auth: routeAuth,\n authStorage,\n audit: auditDomain,\n publicOrigin,\n stateSigner,\n fleet,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n domains,\n integrations: integrationRegistrations,\n intakeReady,\n factoryReady,\n rules,\n factoryTransitionService: transitionService,\n onFactoryRuntime: ({ transitionService: runtimeTransitionService, prepareBinding }) => {\n this.#dispatcher ??= new FactoryDecisionDispatcher({\n controller,\n transitionService: runtimeTransitionService,\n storage: storage.getDomain<WorkItemsStorage>('work-items'),\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 reconcileToolResults: () => factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n prepareBinding,\n primeCredentials: tenant => primeTenantCredentials({ tenant, credentials: modelCredentialsStorage }),\n });\n },\n }),\n ...projectRoutes.routes(),\n ...auditDomain.routes(),\n ],\n buildServerConfig: () => {\n const cors = allowedOrigins.length ? { cors: { origin: allowedOrigins, credentials: true } } : {};\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 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 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. 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 // 3. 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 createFactoryAuthGate(auth),\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 prepared.base.controller.onSessionCreated(session => {\n observeSessionFilesystem(session, {\n filesystem: filesystemStorage,\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n observeSessionCheckpoint(session);\n observeSessionFirstMessage(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n observeSessionFirstExec(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n });\n\n // Blocking: `createSession` awaits this seed, so when hydration succeeds\n // a session's first run starts with the owner's stored OM settings.\n // Best-effort — failures are logged inside the helper, never thrown, and\n // the session then falls back to its persisted/default OM configuration.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionMemorySettings(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n memorySettings: memorySettingsStorage,\n }),\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 // Integrations return a channels CONFIG; the factory owns construction.\n prepared.base.controller.setChannels(\n new AgentControllerChannels(\n integration.channels!(\n buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n fleet,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n rules,\n factoryReady,\n domains,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n ),\n ),\n ),\n );\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 fleet,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n rules,\n factoryReady,\n domains,\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 };\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 timedPhase(\n 'finalize.reconcileBoundThreads',\n () => this.#factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\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":["#config","#preparing","#dispatcher","#prepared","#factoryProcessor"],"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 and Linear integrations when\n * Platform credentials exist and the caller did not 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 { AgentControllerChannels } from '@mastra/core/channels';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { 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 type { WorkspaceSandbox } from '@mastra/core/workspace';\nimport {\n buildAuthRoutes,\n createFactoryAuthGate,\n createFactoryRouteAuth,\n getFactoryAuthOrgId,\n getFactoryAuthUserFromContext,\n getFactoryAuthUserId,\n} from './auth.js';\nimport type { FactoryIntegration, IntegrationPostToolContext, IntegrationTools } from './integrations/base.js';\nimport type { GithubIntegration } from './integrations/github/integration.js';\nimport { recordFactoryPullRequestProvenance } from './integrations/github/provenance.js';\nimport { PlatformGithubIntegration } from './integrations/platform/github/integration.js';\nimport { PlatformLinearIntegration } from './integrations/platform/linear/integration.js';\nimport { createCustomProvidersPrimer, registerCustomProvidersSource } from './routes/custom-provider-source.js';\nimport { ProjectRoutes } from './routes/projects.js';\nimport { assembleFactoryApiRoutes, buildIntegrationContext } from './routes/surface.js';\nimport type { FactoryApiRoutesDeps } from './routes/surface.js';\nimport {\n createTenantCredentialPrimer,\n primeTenantCredentials,\n registerTenantCredentialResolver,\n} from './routes/tenant-credentials.js';\nimport { builtInFactoryRules } from './rules/defaults.js';\nimport { FactoryDecisionDispatcher } from './rules/dispatcher.js';\nimport { FactoryPhaseStateProcessor } from './rules/processor.js';\nimport { createFactoryTransitionTools } from './rules/tools.js';\nimport { FactoryTransitionService } from './rules/transition-service.js';\nimport type { FactoryRules } from './rules/types.js';\nimport { assertFactoryRules } from './rules/validation.js';\nimport { SandboxFleet } from './sandbox/fleet.js';\nimport { registerSandboxReattach } from './sandbox/reattach.js';\nimport { SessionRetirementCoordinator } from './sandbox/session-retirement.js';\nimport { handleServerError } from './server-error.js';\nimport { observeSessionCheckpoint } from './session/checkpoint-capture.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 { hydrateSessionMemorySettings } from './session/memory-settings-hydration.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 { 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 { MemorySettingsStorage } from './storage/domains/memory-settings/base.js';\nimport { ModelPacksStorage } from './storage/domains/model-packs/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 { timedPhase } from './timing.js';\nimport { createWorkspaceFactory, FactoryWorkspaceRegistry } 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 * 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 * 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 /** Sandbox configuration. Omitted → repository sandboxes are disabled. */\n sandbox?: MastraFactorySandboxConfig;\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 * 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` and\n * `linear` integrations default to their Platform-backed implementations.\n */\n integrations?: FactoryIntegration[];\n /**\n * Authoritative Factory board, tool-result, and GitHub-event rules. Construct\n * with `defaultFactoryRules({ version, overrides })` so deployment policy has\n * an explicit version and exact handler leaves replace rather than compose.\n * Omitted → conservative built-in rules for the current deployment.\n */\n rules?: FactoryRules;\n\n /**\n * Platform-specific overrides. `githubAppSlug` identifies Factory's own\n * GitHub App writes so their webhook deliveries do not retrigger triage.\n */\n platform?: {\n githubAppSlug?: string;\n };\n}\n\nexport interface MastraFactorySandboxConfig {\n /**\n * Template machine — `RailwaySandbox` (`@mastra/railway`), core\n * `LocalSandbox` (`@mastra/core/workspace`), or any `WorkspaceSandbox` that\n * implements `clone()`. Each project-repository execution environment gets\n * its own sandbox cloned from this machine; the machine itself is never\n * started. `prepare()` fails fast when the instance lacks `clone()`.\n */\n machine: WorkspaceSandbox;\n /**\n * In-sandbox base directory repos check out under (nested `owner/name` per\n * repo). Default: the machine's own `workingDirectory` when it exposes one\n * (core `LocalSandbox` does), else `/workspace`.\n */\n workdir?: string;\n /**\n * Per-replica cap on concurrently provisioned sandboxes. `0`/omitted means\n * unlimited. A lightweight per-process budget, not a cross-replica scheduler.\n */\n maxSandboxes?: number;\n}\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\nfunction hasPlatformSecretKey(): boolean {\n return Boolean(process.env.MASTRA_PLATFORM_SECRET_KEY?.trim());\n}\n\n/**\n * The template sandbox's own working directory, when it exposes one as a\n * string (core `LocalSandbox` does; remote providers generally don't).\n * Used as the default checkout base so a local template rooted at a host\n * directory checks repos out under that same root.\n */\nfunction templateWorkingDirectory(sandbox: WorkspaceSandbox): string | undefined {\n const wd = (sandbox as { workingDirectory?: unknown }).workingDirectory;\n return typeof wd === 'string' && wd.length > 0 ? wd : undefined;\n}\n\nfunction resolveSandboxWorkdirBase(machine: WorkspaceSandbox, configuredWorkdir?: string): string {\n const machineWorkdir = templateWorkingDirectory(machine);\n const workdir =\n configuredWorkdir === '/workspace' && machineWorkdir ? machineWorkdir : (configuredWorkdir ?? machineWorkdir);\n return (workdir ?? '/workspace').replace(/\\/+$/, '');\n}\n\n/**\n * Default auth provider — `MastraAuthStudio`, which proxies identity to the\n * shared Mastra platform API. `MastraAuthStudio` resolves `MASTRA_SHARED_API_URL`,\n * `MASTRA_ORGANIZATION_ID`, and `MASTRA_COOKIE_DOMAIN` from env on its own —\n * this helper only derives a cookie-domain fallback from the factory's\n * `publicUrl`.\n *\n * Cookie-domain resolution (Studio picks the first that wins):\n * 1. explicit `MASTRA_COOKIE_DOMAIN` env, if set;\n * 2. `.mastra.ai` when `sharedApiUrl` is on `.mastra.ai`;\n * 3. this parent-domain fallback derived from `publicUrl` — so a deploy on\n * `https://foo.mastra.cloud` mints cookies with `Domain=.mastra.cloud`\n * without the caller wiring the env var by hand.\n * 4. otherwise host-only (no `Domain=`), which is correct for `localhost`.\n */\nfunction buildDefaultStudioAuth(publicUrl: string): IMastraAuthProvider {\n return new MastraAuthStudio({\n cookieDomain: parentDomainFromPublicUrl(publicUrl),\n });\n}\n\n/**\n * Derive a parent cookie domain from `publicUrl` by stripping the leftmost\n * label — the same shape platform-API's env injection uses (see\n * `platform/servers/api/src/lib/studio-env-vars.ts`: `.${routingDomain.replace(/^[^.]+\\./, '')}`).\n *\n * Rather than a generic `strip-left-label` heuristic — which either emits\n * cookies scoped to a public suffix (`sub.example.co.uk` → `.example.co.uk`\n * requires PSL data to be safe) or misclassifies numeric hostnames like\n * `3scale.example.com` as IPv4 — we only derive a parent domain when the\n * host sits under one of the platform's known registrable domains. Anything\n * else (custom domains, arbitrary tenant hostnames, IPs, `localhost`)\n * falls through to host-only cookies. Callers that need a different scope\n * pass `MASTRA_COOKIE_DOMAIN` explicitly (Studio honors that first).\n */\nconst KNOWN_PLATFORM_COOKIE_PARENTS = ['mastra.cloud', 'mastra.ai'] as const;\n\nfunction isIpLiteral(hostname: string): boolean {\n // IPv6 addresses in URLs are bracketed; `URL.hostname` strips the brackets\n // but the address itself still contains `:`. IPv4 is four dot-separated\n // numeric octets — trust the parser to have already validated shape.\n if (hostname.includes(':')) return true;\n return /^\\d+(?:\\.\\d+){3}$/.test(hostname);\n}\n\nfunction parentDomainFromPublicUrl(publicUrl: string): string | undefined {\n let hostname: string;\n try {\n hostname = new URL(publicUrl).hostname.toLowerCase();\n } catch {\n return undefined;\n }\n if (hostname === 'localhost' || isIpLiteral(hostname)) return undefined;\n for (const parent of KNOWN_PLATFORM_COOKIE_PARENTS) {\n // Exact match → we're already on the parent, host-only is correct.\n // Subdomain match → mint the parent-scoped cookie.\n if (hostname === parent) return undefined;\n if (hostname.endsWith(`.${parent}`)) return `.${parent}`;\n }\n return undefined;\n}\n\nexport class MastraFactory {\n readonly #config: MastraFactoryConfig;\n #prepared: Awaited<ReturnType<typeof prepareAgentControllerMount>> | undefined;\n #dispatcher: FactoryDecisionDispatcher | undefined;\n #factoryProcessor: FactoryPhaseStateProcessor | 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.#config = config;\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 = this.#config.storage;\n const vector = this.#config.vector;\n const pubsub = this.#config.pubsub;\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(publicOrigin));\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\n // Explicit integrations win. Platform credentials fill only missing GitHub\n // and Linear slots so callers can override either provider independently.\n const integrations = [...(this.#config.integrations ?? [])];\n if (hasPlatformSecretKey()) {\n if (!integrations.some(integration => integration.id === 'github')) {\n integrations.push(new PlatformGithubIntegration({ slug: this.#config.platform?.githubAppSlug }));\n }\n if (!integrations.some(integration => integration.id === 'linear')) {\n integrations.push(new PlatformLinearIntegration());\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 rules = this.#config.rules ?? builtInFactoryRules();\n assertFactoryRules(rules);\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 const modelCredentialsStorage = storage.registerDomain(new ModelCredentialsStorage());\n const modelPacksStorage = storage.registerDomain(new ModelPacksStorage());\n const memorySettingsStorage = storage.registerDomain(new MemorySettingsStorage());\n const customProvidersStorage = storage.registerDomain(new CustomProvidersStorage());\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());\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 // 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 modelPacks: modelPacksStorage,\n memorySettings: memorySettingsStorage,\n customProviders: customProvidersStorage,\n filesystem: filesystemStorage,\n projects: factoryProjectsStorage,\n queueHealth: queueHealthStorage,\n workItems: workItemsStorage,\n channelIdentity: channelIdentityStorage,\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\n // Repository execution needs one sandbox per project-repository link,\n // cloned from the configured machine. A machine without `clone()` would\n // only fail on first use, so fail fast at boot instead.\n const sandboxConfig = this.#config.sandbox;\n const machine = sandboxConfig?.machine;\n if (machine && typeof machine.clone !== 'function') {\n throw new Error(\n `MastraFactory: the configured sandbox machine (provider '${machine.provider}') does not implement clone(). ` +\n `Project repositories each get their own sandbox cloned from the configured machine. ` +\n `Pass a machine that implements clone() — e.g. RailwaySandbox (@mastra/railway) or ` +\n `LocalSandbox (@mastra/core/workspace) — or omit 'sandbox' to disable sandboxes.`,\n );\n }\n\n // One sandbox fleet per boot: constructed with the machine config when\n // sandboxes are configured, disabled otherwise. Handed to integrations\n // through the IntegrationContext — no global registry.\n const fleet = new SandboxFleet(\n machine\n ? {\n machine,\n workdirBase: resolveSandboxWorkdirBase(machine, sandboxConfig?.workdir),\n maxSandboxes: sandboxConfig?.maxSandboxes,\n }\n : undefined,\n );\n // Core's `getDynamicWorkspace` reattaches project sandboxes through the\n // SDK seam; only this factory owns the fleet, so register it here.\n registerSandboxReattach(fleet);\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 if (auth) {\n registerTenantCredentialResolver(modelCredentialsStorage);\n }\n\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 integration.initialize?.({\n storage: integrationStorage.forIntegration(integration.id),\n projects: factoryProjectsStorage,\n auth: routeAuth,\n });\n if (integration.versionControl) {\n integration.versionControl.initialize({\n storage: sourceControlStorage.forIntegration(integration.id),\n });\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 const githubIntegration = integrations.find(integration => integration.id === 'github') as\n | GithubIntegration\n | undefined;\n const workItemsReady = storage.isDomainReady('work-items');\n const sessionRetirement =\n machine && storage.isDomainReady('source-control')\n ? new SessionRetirementCoordinator({\n fleet,\n invalidateSession: sessionId => workspaceRegistry.invalidateSession(sessionId),\n })\n : undefined;\n const retireTerminalSessions =\n sessionRetirement && githubIntegration && workItemsReady\n ? async ({ orgId, workItemId }: { orgId: string; workItemId: string }) =>\n sessionRetirement.retireWorkItemSessions({\n workItems: workItemsStorage,\n sourceControl: sourceControlStorage.forIntegration(githubIntegration.id),\n orgId,\n workItemId,\n })\n : undefined;\n const transitionService = workItemsReady\n ? new FactoryTransitionService({\n rules,\n storage: workItemsStorage,\n ...(retireTerminalSessions ? { onTerminalStage: retireTerminalSessions } : {}),\n })\n : undefined;\n const projectRoutes = new ProjectRoutes({\n auth: routeAuth,\n projects: factoryProjectsStorage,\n sourceControl: sourceControlStorage,\n versionControlIntegrationIds: integrations\n .filter(integration => integration.versionControl)\n .map(integration => integration.id),\n ...(sessionRetirement ? { sessionRetirement } : {}),\n });\n const factoryProcessor = workItemsReady\n ? new FactoryPhaseStateProcessor({\n rules,\n storage: workItemsStorage,\n ...(transitionService ? { transitionService } : {}),\n ...(githubIntegration\n ? {\n recordPullRequestProvenance: (input: Parameters<typeof recordFactoryPullRequestProvenance>[3]) =>\n recordFactoryPullRequestProvenance(\n githubIntegration,\n sourceControlStorage.forIntegration('github'),\n integrationStorage.forIntegration('github'),\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 // 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\n // Build the real production controller (agents, modes, tools, memory, OM,\n // MCP, providers) — identical to the terminal app. 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 workspace: createWorkspaceFactory({\n ...(this.#config.sandbox ? { sandbox: this.#config.sandbox } : {}),\n ...(githubIntegration ? { github: githubIntegration } : {}),\n ...(workItemsStorage ? { workItems: workItemsStorage } : {}),\n fleet,\n workspaceRegistry,\n }),\n disableGithubSignals: true,\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 // 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 initialState: { skipGlobalInstructions: true },\n storage: storage.getMastraStorage(),\n ...(mastraStorageBackend ? { storageBackend: mastraStorageBackend } : {}),\n ...(factoryProcessor ? { inputProcessors: [factoryProcessor] } : {}),\n ...(vector ? { vector } : {}),\n ...(toolIntegrations.length > 0 || (workItemsStorage && transitionService)\n ? {\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 (workItemsStorage && transitionService) {\n mergeTools(\n 'factory',\n await createFactoryTransitionTools({\n requestContext,\n storage: workItemsStorage,\n transitionService,\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')\n ? { sessions: sourceControlStorage.forIntegration('github').sessions }\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 }\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 });\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/*`.\n ...(auth ? buildAuthRoutes(auth, { publicUrl: publicOrigin }) : []),\n // Custom `/web/*` routes (fs / config / integrations / factory / audit).\n ...assembleFactoryApiRoutes({\n controllerId: CONTROLLER_ID,\n controller,\n auth: routeAuth,\n authStorage,\n audit: auditDomain,\n publicOrigin,\n stateSigner,\n fleet,\n sessionRetirement,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n domains,\n integrations: integrationRegistrations,\n intakeReady,\n factoryReady,\n rules,\n factoryTransitionService: transitionService,\n onFactoryRuntime: ({ transitionService: runtimeTransitionService, prepareBinding }) => {\n this.#dispatcher ??= new FactoryDecisionDispatcher({\n controller,\n transitionService: runtimeTransitionService,\n storage: storage.getDomain<WorkItemsStorage>('work-items'),\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 reconcileToolResults: () => factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\n prepareBinding,\n primeCredentials: tenant => primeTenantCredentials({ tenant, credentials: modelCredentialsStorage }),\n });\n },\n }),\n ...projectRoutes.routes(),\n ...auditDomain.routes(),\n ],\n buildServerConfig: () => {\n const cors = allowedOrigins.length ? { cors: { origin: allowedOrigins, credentials: true } } : {};\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 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 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. 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 // 3. 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 createFactoryAuthGate(auth),\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 prepared.base.controller.onSessionCreated(session => {\n observeSessionFilesystem(session, {\n filesystem: filesystemStorage,\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n observeSessionCheckpoint(session);\n observeSessionFirstMessage(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n observeSessionFirstExec(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n });\n });\n\n // Blocking: `createSession` awaits this seed, so when hydration succeeds\n // a session's first run starts with the owner's stored OM settings.\n // Best-effort — failures are logged inside the helper, never thrown, and\n // the session then falls back to its persisted/default OM configuration.\n prepared.base.controller.onSessionCreated(\n session =>\n hydrateSessionMemorySettings(session, {\n sourceControl: sourceControlStorage.forIntegration('github'),\n memorySettings: memorySettingsStorage,\n }),\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 // Integrations return a channels CONFIG; the factory owns construction.\n prepared.base.controller.setChannels(\n new AgentControllerChannels(\n integration.channels!(\n buildIntegrationContext(\n {\n controller: prepared.base.controller,\n publicOrigin,\n auth: routeAuth,\n stateSigner,\n fleet,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n rules,\n factoryReady,\n domains,\n ...(githubIntegration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n ),\n ),\n ),\n );\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 fleet,\n factoryStorage: storage,\n integrationStorage,\n sourceControlStorage,\n rules,\n factoryReady,\n domains,\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 };\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 timedPhase(\n 'finalize.reconcileBoundThreads',\n () => this.#factoryProcessor?.reconcileAllBoundThreads() ?? Promise.resolve(),\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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"}
|
|
@@ -27,6 +27,7 @@ import type { VersionControl } from '../capabilities/version-control.js';
|
|
|
27
27
|
import type { RouteAuth } from '../routes/route.js';
|
|
28
28
|
import type { FactoryRules } from '../rules/types.js';
|
|
29
29
|
import type { SandboxFleet } from '../sandbox/fleet.js';
|
|
30
|
+
import type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';
|
|
30
31
|
import type { StateSigner } from '../state-signing.js';
|
|
31
32
|
import type { AuditEventRow } from '../storage/domains/audit/base.js';
|
|
32
33
|
import type { AuditEmitter } from '../storage/domains/audit/domain.js';
|
|
@@ -81,6 +82,8 @@ export interface IntegrationContext {
|
|
|
81
82
|
* every integration's OAuth flow signs and verifies with the same secret.
|
|
82
83
|
*/
|
|
83
84
|
stateSigner?: StateSigner;
|
|
85
|
+
/** Shared source-control session retirement lifecycle used by integration routes. */
|
|
86
|
+
sessionRetirement?: SessionRetirementCoordinator;
|
|
84
87
|
/** Persistence handles pre-scoped to this integration's stable id. */
|
|
85
88
|
storage: {
|
|
86
89
|
generic: IntegrationStorageHandle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/integrations/base.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/integrations/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -96,6 +96,13 @@ export interface GithubIntegrationConfig {
|
|
|
96
96
|
* replica-stable OAuth/install `state` secret (see `./config.ts`).
|
|
97
97
|
*/
|
|
98
98
|
webhookSecret?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Extra bot logins authorized to trigger author-gated PR notifications
|
|
101
|
+
* (reviews and comments). Merged over the built-in defaults, matched
|
|
102
|
+
* case-insensitively. Deployments running their own reviewer bots opt them
|
|
103
|
+
* in here; every other bot stays gated.
|
|
104
|
+
*/
|
|
105
|
+
authorizedBots?: string[];
|
|
99
106
|
}
|
|
100
107
|
export declare class GithubIntegration implements FactoryIntegration {
|
|
101
108
|
#private;
|
|
@@ -111,6 +118,8 @@ export declare class GithubIntegration implements FactoryIntegration {
|
|
|
111
118
|
constructor(config: GithubIntegrationConfig);
|
|
112
119
|
/** App slug — the URL name used to build the install URL. */
|
|
113
120
|
get slug(): string;
|
|
121
|
+
/** Extra bot logins authorized to trigger author-gated PR notifications. */
|
|
122
|
+
get authorizedBots(): readonly string[];
|
|
114
123
|
get genericStorage(): IntegrationContext['storage']['generic'];
|
|
115
124
|
get sourceControlStorage(): IntegrationContext['storage']['sourceControl'];
|
|
116
125
|
get integrationStorage(): GithubSubscriptionStorage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAGV,MAAM,EAKP,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAKV,cAAc,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAM3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAMjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAMpE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAErG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAGV,MAAM,EAKP,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAKV,cAAc,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAM3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAMjF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAMpE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAErG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAKD,qBAAa,iBAAkB,YAAW,kBAAkB;;IAC1D,uEAAuE;IACvE,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAoFrB;IACF,QAAQ,CAAC,cAAc,EAAE,cAAc,CAmErC;IACF;;;OAGG;IACH,QAAQ,CAAC,yBAAyB,QAAQ;gBAY9B,MAAM,EAAE,uBAAuB;IAkB3C,6DAA6D;IAC7D,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,4EAA4E;IAC5E,IAAI,cAAc,IAAI,SAAS,MAAM,EAAE,CAEtC;IAED,IAAI,cAAc,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAG7D;IAED,IAAI,oBAAoB,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAIzE;IAED,IAAI,kBAAkB,IAAI,yBAAyB,CAGlD;IA4BD,sEAAsE;IACtE,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;IAWD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAIvD,iFAAiF;IACjF,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI1C;;;OAGG;IACG,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpE;;;OAGG;IACG,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAY3E,4DAA4D;IACtD,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgB3E;;;OAGG;IACG,mCAAmC,CACvC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAelD;;;;;OAKG;IACG,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA+dpG,6EAA6E;IACvE,cAAc,CAClB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC;IAchB,sCAAsC;IAChC,gBAAgB,CACpB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAahB;;;;;OAKG;IACG,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,SAAS,CAAC;IA4BrB;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAMtC;;;OAGG;IACH,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAQjE,wDAAwD;IAClD,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwB3E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,QAAQ,EAAE;IAkB3C;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE;IA+BhD;;;OAGG;IACG,qBAAqB,CAAC,KAAK,EAAE;QACjC,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,yBAAyB,GAAG,SAAS,CAAC;IA2BlD;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IA+B5C;;;OAGG;IACH,YAAY,CAAC,EAAE,cAAc,EAAE,EAAE;QAAE,cAAc,EAAE,cAAc,CAAA;KAAE,GAAG,gBAAgB;IAIhF,gBAAgB,CAAC,EACrB,WAAW,EACX,cAAc,GACf,EAAE,UAAU,CAAC,WAAW,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrF,sEAAsE;IACtE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMvC"}
|
|
@@ -213,6 +213,7 @@ var GithubIntegration = class {
|
|
|
213
213
|
#clientSecret;
|
|
214
214
|
#slug;
|
|
215
215
|
#webhookSecret;
|
|
216
|
+
#authorizedBots;
|
|
216
217
|
#storage;
|
|
217
218
|
#sourceControlStorage;
|
|
218
219
|
constructor(config) {
|
|
@@ -224,11 +225,16 @@ var GithubIntegration = class {
|
|
|
224
225
|
this.#clientSecret = config.clientSecret;
|
|
225
226
|
this.#slug = config.slug;
|
|
226
227
|
this.#webhookSecret = config.webhookSecret || void 0;
|
|
228
|
+
this.#authorizedBots = (config.authorizedBots ?? []).map((bot) => bot.trim()).filter(Boolean);
|
|
227
229
|
}
|
|
228
230
|
/** App slug — the URL name used to build the install URL. */
|
|
229
231
|
get slug() {
|
|
230
232
|
return this.#slug;
|
|
231
233
|
}
|
|
234
|
+
/** Extra bot logins authorized to trigger author-gated PR notifications. */
|
|
235
|
+
get authorizedBots() {
|
|
236
|
+
return this.#authorizedBots;
|
|
237
|
+
}
|
|
232
238
|
get genericStorage() {
|
|
233
239
|
if (!this.#storage) throw new Error("GithubIntegration storage has not been initialized.");
|
|
234
240
|
return this.#storage.generic;
|
|
@@ -936,7 +942,8 @@ var GithubIntegration = class {
|
|
|
936
942
|
controller: ctx.controller,
|
|
937
943
|
emitAudit: ctx.hooks?.emitAudit,
|
|
938
944
|
projects: ctx.storage.projects,
|
|
939
|
-
ingestFactoryEvent
|
|
945
|
+
ingestFactoryEvent,
|
|
946
|
+
sessionRetirement: ctx.sessionRetirement
|
|
940
947
|
});
|
|
941
948
|
}
|
|
942
949
|
/**
|