@mastra/factory 0.2.2 → 0.2.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @mastra/factory
2
2
 
3
+ ## 0.2.3-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved contributor guidance for Factory backend development. ([#20327](https://github.com/mastra-ai/mastra/pull/20327))
8
+
9
+ - Fixed Factory losing repository access after a GitHub App is reinstalled with a new installation ID. ([#20348](https://github.com/mastra-ai/mastra/pull/20348))
10
+
11
+ - Updated dependencies [[`3f472b4`](https://github.com/mastra-ai/mastra/commit/3f472b468892a1ff14ccb43cc0343b86f7d8fd7d), [`35b929b`](https://github.com/mastra-ai/mastra/commit/35b929b7abc3d20d85c7985880960ac2d04a6c86), [`35b929b`](https://github.com/mastra-ai/mastra/commit/35b929b7abc3d20d85c7985880960ac2d04a6c86), [`9b3626a`](https://github.com/mastra-ai/mastra/commit/9b3626aeb1d16fcd34b0a8e94c114ddb80a3b240)]:
12
+ - @mastra/core@1.55.0-alpha.0
13
+ - @mastra/code-sdk@1.1.1-alpha.0
14
+
3
15
  ## 0.2.2
4
16
 
5
17
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../../src/integrations/platform/github/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAKpD,OAAO,KAAK,EAEV,MAAM,EAIP,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAwBV,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAC9F,OAAO,KAAK,EAEV,0BAA0B,EAC3B,MAAM,iDAAiD,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG9G,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAMvE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAQ/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAyH9D,qBAAa,yBAA0B,YAAW,kBAAkB;;IAClE,QAAQ,CAAC,EAAE,YAAY;IAavB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAsHrB;IAEF,QAAQ,CAAC,cAAc,EAAE,cAAc,CAoFrC;;IAWF,IAAI,OAAO,IAAI,0BAA0B,CAGxC;IAED,IAAI,oBAAoB,IAAI,0BAA0B,CAErD;IAED,IAAI,kBAAkB,IAAI,yBAAyB,CAKlD;IAuBD,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,wBAAwB,CAAA;KAAE,GAAG,IAAI;IAUpE,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,QAAQ,EAAE;IA+K3C,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,yBAAyB,EAAE;IAqB7D;;;;OAIG;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;IAoClD,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;IAWrF,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYhC,mCAAmC,CACvC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAoB5C,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA0BrE,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa9D,cAAc,CAClB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;CA6WzG"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../../src/integrations/platform/github/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAKpD,OAAO,KAAK,EAEV,MAAM,EAIP,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAwBV,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AAC9F,OAAO,KAAK,EAEV,0BAA0B,EAC3B,MAAM,iDAAiD,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG9G,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAMvE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAQ/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAyH9D,qBAAa,yBAA0B,YAAW,kBAAkB;;IAClE,QAAQ,CAAC,EAAE,YAAY;IAavB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAsHrB;IAEF,QAAQ,CAAC,cAAc,EAAE,cAAc,CA2HrC;;IAWF,IAAI,OAAO,IAAI,0BAA0B,CAGxC;IAED,IAAI,oBAAoB,IAAI,0BAA0B,CAErD;IAED,IAAI,kBAAkB,IAAI,yBAAyB,CAKlD;IAuBD,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,wBAAwB,CAAA;KAAE,GAAG,IAAI;IAUpE,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,QAAQ,EAAE;IA+K3C,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,yBAAyB,EAAE;IAqB7D;;;;OAIG;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;IAoClD,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;IAWrF,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYhC,mCAAmC,CACvC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAoB5C,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA0BrE,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa9D,cAAc,CAClB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;CA6WzG"}
@@ -214,21 +214,49 @@ var PlatformGithubIntegration = class {
214
214
  const installationId = parsePositiveInteger(installation.externalId);
215
215
  if (installationId === null) throw new Error("GitHub installation id is invalid.");
216
216
  const repositoryName = splitRepository(repository.slug).repo;
217
- const access = {
218
- cloneUrl,
219
- authorization: {
220
- scheme: "bearer",
221
- token: (await this.#client.request("POST", `${API_PREFIX}/github-app/installations/${installationId}/token`, {
222
- repositories: [repositoryName],
223
- permissions: REPOSITORY_TOKEN_PERMISSIONS
224
- })).token
225
- }
226
- };
227
- setBounded(this.#repositoryAccessCache, cacheKey, {
228
- access,
229
- expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS
230
- });
231
- return access;
217
+ try {
218
+ const access = {
219
+ cloneUrl,
220
+ authorization: {
221
+ scheme: "bearer",
222
+ token: (await this.#client.request("POST", `${API_PREFIX}/github-app/installations/${installationId}/token`, {
223
+ repositories: [repositoryName],
224
+ permissions: REPOSITORY_TOKEN_PERMISSIONS
225
+ })).token
226
+ }
227
+ };
228
+ setBounded(this.#repositoryAccessCache, cacheKey, {
229
+ access,
230
+ expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS
231
+ });
232
+ return access;
233
+ } catch (err) {
234
+ if (!isNotFound(err) || !installation.accountName) throw err;
235
+ const newInstallation = (await this.storage.installations.list({ orgId })).find((inst) => inst.accountName === installation.accountName && inst.id !== installation.id);
236
+ if (!newInstallation) throw err;
237
+ const newInstallationId = parsePositiveInteger(newInstallation.externalId);
238
+ if (newInstallationId === null) throw err;
239
+ await this.storage.repositories.migrateInstallation({
240
+ orgId,
241
+ id: repositoryId,
242
+ newInstallationId: newInstallation.id
243
+ });
244
+ const access = {
245
+ cloneUrl,
246
+ authorization: {
247
+ scheme: "bearer",
248
+ token: (await this.#client.request("POST", `${API_PREFIX}/github-app/installations/${newInstallationId}/token`, {
249
+ repositories: [repositoryName],
250
+ permissions: REPOSITORY_TOKEN_PERMISSIONS
251
+ })).token
252
+ }
253
+ };
254
+ setBounded(this.#repositoryAccessCache, cacheKey, {
255
+ access,
256
+ expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS
257
+ });
258
+ return access;
259
+ }
232
260
  },
233
261
  listPullRequests: (input) => this.#listPullRequests(input),
234
262
  getPullRequest: (input) => this.#getPullRequest(input),
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","names":["#client","#endpointHost","#pollingEnabled","#pollingIntervalMs","#reconcileEnabled","#installationReposCache","#repositoryAccessCache","#resolveIntakeDispatch","#listIssues","#listPullRequests","#getIssue","#createIssueComment","#updateIntakeIssue","#storage","#getPullRequest","#createPullRequest","#updatePullRequest","#mergePullRequest","#listComments","#createComment","#updateComment","#deleteComment","#listReviews","#getReview","#createReview","#updateReview","#submitReview","#dismissReview","#deletePendingReview","#listReviewComments","#createReviewComment","#updateReviewComment","#deleteReviewComment","#requestedReviewers","#integrationStorage","#statusRoute","#connectRoute","#connectUserRoute","#syncInstallations","#fetchUserConnection"],"sources":["../../../../src/integrations/platform/github/integration.ts"],"sourcesContent":["import type { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\nimport type { IntegrationConnection } from '../../../capabilities/connection.js';\nimport type {\n CreateIntakeCommentInput,\n Intake,\n IntakeIssue,\n IntakeIssueDetail,\n UpdateIntakeIssueInput,\n} from '../../../capabilities/intake.js';\nimport type {\n CreatePullRequestCommentInput,\n CreatePullRequestInput,\n CreateReviewCommentInput,\n CreateReviewInput,\n DeletePullRequestCommentInput,\n DismissReviewInput,\n ListPullRequestCommentsInput,\n ListPullRequestsInput,\n ListReviewCommentsInput,\n ListReviewsInput,\n MergePullRequestInput,\n PullRequest,\n PullRequestComment,\n PullRequestRef,\n RepositoryAccess,\n Review,\n ReviewComment,\n ReviewRef,\n SubmitReviewInput,\n UpdatePullRequestCommentInput,\n UpdatePullRequestInput,\n UpdateReviewInput,\n UpdateReviewersInput,\n VersionControl,\n} from '../../../capabilities/version-control.js';\nimport type { IntegrationStorageHandle } from '../../../storage/domains/integrations/base.js';\nimport type {\n SourceControlInstallation,\n SourceControlStorageHandle,\n} from '../../../storage/domains/source-control/base.js';\nimport type { FactoryIntegration, IntegrationContext, IntegrationTools } from '../../base.js';\nimport type { GithubIntegration, GithubRepositoryPermission, RepoSummary } from '../../github/integration.js';\nimport { buildGithubRoutes } from '../../github/routes.js';\nimport { attachGithubReconciler, attachGithubRules } from '../../github/rules.js';\nimport type { ReconcilePullRequestState } from '../../github/rules.js';\nimport {\n createGithubSubscriptionTools,\n parseCreatedPullRequest,\n subscribeCurrentSessionToPullRequest,\n} from '../../github/session-subscriptions.js';\nimport type { GithubSubscriptionStorage } from '../../github/subscriptions.js';\nimport {\n logPlatformInfo,\n logPlatformWarn,\n PlatformApiClient,\n PlatformApiError,\n platformApiClientConfigFromEnv,\n} from '../api-client.js';\nimport { PlatformGithubEventWorker } from './event-worker.js';\nimport type { PlatformGithubEventStorage } from './event-worker.js';\n\ntype GithubActor = { login: string; avatarUrl: string | null; htmlUrl: string | null } | null;\n\ntype PlatformGithubInstallation = {\n installationId: number;\n accountLogin: string;\n accountType: string;\n suspendedAt: string | null;\n usable: boolean;\n};\n\ntype PlatformGithubUserConnection = {\n connected: boolean;\n githubUsername: string | null;\n reason?: 'token-invalid' | 'no-accessible-installation' | 'missing-permissions' | 'verification-unavailable' | null;\n};\n\ntype GithubIssue = {\n number: number;\n state: 'open' | 'closed';\n title: string;\n body: string | null;\n htmlUrl: string;\n labels: string[];\n assignees: string[];\n commentCount: number;\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubComment = {\n id: number;\n body: string;\n htmlUrl: string;\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubPullRequest = {\n number: number;\n title: string;\n body: string | null;\n state: 'open' | 'closed';\n htmlUrl: string;\n merged: boolean;\n mergeable: boolean | null;\n draft: boolean;\n head: { ref: string; sha: string };\n base: { ref: string; repo: { id: number; fullName: string } };\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubReview = {\n id: number;\n htmlUrl: string | null;\n body: string | null;\n state: 'PENDING' | 'COMMENTED' | 'APPROVED' | 'CHANGES_REQUESTED' | 'DISMISSED';\n commitId: string | null;\n submittedAt: string | null;\n user: GithubActor;\n};\n\ntype GithubReviewComment = GithubComment & {\n path: string;\n line: number | null;\n side: 'LEFT' | 'RIGHT' | null;\n commitId: string;\n replyToId: number | null;\n};\n\nconst PAGE_SIZE = 30;\nconst API_PREFIX = '/v1/server';\n/**\n * How long an installation's repository listing may be reused. The repos\n * route and token minting both call it — often several times within one UI\n * interaction — and each call is a full Platform round trip.\n */\nconst INSTALLATION_REPOS_CACHE_TTL_MS = 30_000;\n/**\n * How long a minted repository-scoped token may be reused. GitHub\n * installation tokens live ~60 minutes; 5 minutes keeps a wide validity\n * margin while collapsing the per-session-materialization mint round trip.\n */\nconst REPOSITORY_ACCESS_CACHE_TTL_MS = 5 * 60_000;\n/**\n * Upper bound for both TTL caches. Entries expire lazily on re-access, so\n * without a hard cap keys that stop being queried would accumulate for the\n * integration's (long) lifetime. Insertion-order eviction — matches the\n * bounded verification cache in `@mastra/auth-studio`.\n */\nconst MAX_CACHE_ENTRIES = 1000;\n\nfunction setBounded<K, V>(cache: Map<K, V>, key: K, value: V): void {\n cache.delete(key);\n cache.set(key, value);\n if (cache.size > MAX_CACHE_ENTRIES) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n}\n\nconst REPOSITORY_TOKEN_PERMISSIONS = {\n contents: 'write',\n issues: 'write',\n pull_requests: 'write',\n} as const;\n\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\nfunction routeBaseUrl(ctx: IntegrationContext, requestUrl: string): string {\n return (ctx.baseUrl || new URL(requestUrl).origin).replace(/\\/+$/, '');\n}\n\nexport class PlatformGithubIntegration implements FactoryIntegration {\n readonly id = 'github';\n readonly #client: PlatformApiClient;\n readonly #endpointHost: string;\n readonly #pollingEnabled: boolean;\n readonly #pollingIntervalMs: number | undefined;\n readonly #reconcileEnabled: boolean;\n #storage: SourceControlStorageHandle | undefined;\n #integrationStorage: GithubSubscriptionStorage | undefined;\n /** installationId → cached repository listing (TTL-bounded). */\n readonly #installationReposCache = new Map<number, { repos: RepoSummary[]; expiresAt: number }>();\n /** `orgId:repositoryId` → cached repository access (TTL-bounded). */\n readonly #repositoryAccessCache = new Map<string, { access: RepositoryAccess; expiresAt: number }>();\n\n readonly intake: Intake = {\n resolveIntakeDispatch: input => this.#resolveIntakeDispatch(input),\n listSources: async ({ orgId, userId }) => {\n const installations = await this.#client.request<{\n installations: Array<{\n installationId: number;\n accountLogin: string;\n accountType: string;\n suspendedAt: string | null;\n usable: boolean;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations`);\n const usable = installations.installations.filter(\n installation => installation.usable && !installation.suspendedAt,\n );\n const repositories = await Promise.all(\n usable.map(async installation => {\n const storedInstallation = await this.versionControl.registerInstallation({\n orgId,\n userId,\n installation: {\n externalId: String(installation.installationId),\n accountName: installation.accountLogin,\n accountType: installation.accountType,\n },\n });\n const result = await this.#client.request<{\n repositories: Array<{\n id: number;\n fullName: string;\n private: boolean;\n defaultBranch: string;\n htmlUrl: string;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations/${installation.installationId}/repositories`);\n await this.versionControl.registerRepositories({\n orgId,\n installationId: storedInstallation.id,\n repositories: result.repositories.map(repository => ({\n externalId: String(repository.id),\n slug: repository.fullName,\n defaultBranch: repository.defaultBranch,\n metadata: { private: repository.private, url: repository.htmlUrl },\n })),\n });\n return result.repositories.map(repository => ({ repository, installation }));\n }),\n );\n return repositories.flat().map(({ repository, installation }) => ({\n id: repository.fullName,\n name: repository.fullName,\n type: 'repository',\n metadata: {\n installationId: installation.installationId,\n accountLogin: installation.accountLogin,\n accountType: installation.accountType,\n repositoryId: repository.id,\n defaultBranch: repository.defaultBranch,\n private: repository.private,\n url: repository.htmlUrl,\n },\n }));\n },\n listItems: async ({ sourceIds, cursor }) => {\n const page = parsePositiveCursor(cursor);\n const pages = await Promise.all(\n sourceIds.map(async sourceId => {\n const connection = { type: 'app-installation' as const, installationId: 1 };\n const [issues, pullRequests] = await Promise.all([\n this.#listIssues(connection, sourceId, page),\n this.#listPullRequests({ connection, sourceId, includeDrafts: false, cursor: String(page) }),\n ]);\n return {\n items: [\n ...issues.issues.map(issue => ({\n source: { type: 'issue', externalId: `${sourceId}:${issue.id}`, url: issue.url },\n sourceId,\n title: issue.title,\n status: issue.state ?? undefined,\n labels: issue.labels,\n assignee: issue.assignee,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n metadata: { repository: sourceId, number: Number(issue.id), author: issue.author },\n })),\n ...pullRequests.pullRequests.map(pullRequest => ({\n source: { type: 'pull-request', externalId: `${sourceId}:${pullRequest.id}`, url: pullRequest.url },\n sourceId,\n title: pullRequest.title,\n status: pullRequest.state,\n createdAt: pullRequest.createdAt,\n updatedAt: pullRequest.updatedAt,\n metadata: {\n repository: sourceId,\n number: Number(pullRequest.id),\n author: pullRequest.author,\n baseBranch: pullRequest.baseBranch,\n headBranch: pullRequest.headBranch,\n },\n })),\n ],\n hasNextPage: issues.nextCursor !== null || pullRequests.nextCursor !== null,\n };\n }),\n );\n return {\n items: pages.flatMap(result => result.items),\n nextCursor: pages.some(result => result.hasNextPage) ? String(page + 1) : null,\n };\n },\n listIssues: async input => {\n requireGithubConnection(input.connection);\n const sourceId = requireSingleSource(input.sourceIds, 'GitHub Intake requires exactly one repository source.');\n return this.#listIssues(input.connection, sourceId, parsePositiveCursor(input.cursor), input.labels);\n },\n getIssue: input => this.#getIssue(input.connection, input.sourceId, input.issueId),\n createComment: input => this.#createIssueComment(input),\n updateIssue: input => this.#updateIntakeIssue(input),\n };\n\n readonly versionControl: VersionControl = {\n initialize: ({ storage }) => {\n this.#storage = storage;\n },\n registerInstallation: ({ orgId, userId, installation }) =>\n this.storage.installations.upsert({\n orgId,\n connectedByUserId: userId,\n externalId: installation.externalId,\n accountName: installation.accountName,\n accountType: installation.accountType,\n providerMetadata: installation.metadata,\n }),\n registerRepositories: ({ orgId, installationId, repositories }) =>\n Promise.all(\n repositories.map(repository =>\n this.storage.repositories.upsert({\n orgId,\n input: {\n installationId,\n externalId: repository.externalId,\n slug: repository.slug,\n defaultBranch: repository.defaultBranch,\n providerMetadata: repository.metadata,\n },\n }),\n ),\n ),\n getRepositoryAccess: async ({ orgId, repositoryId }) => {\n // Every session materialization requests access; reuse a recent grant\n // instead of re-minting through the Platform each time. The TTL keeps\n // a wide margin under GitHub's ~60min installation-token lifetime.\n const cacheKey = `${orgId}:${repositoryId}`;\n const cached = this.#repositoryAccessCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.access;\n this.#repositoryAccessCache.delete(cacheKey);\n\n const repository = await this.storage.repositories.get({ orgId, id: repositoryId });\n if (!repository) throw new Error('Version-control repository not found.');\n const cloneUrl = `https://github.com/${repository.slug}.git`;\n const installation = await this.storage.installations.get({ orgId, id: repository.installationId });\n if (!installation) throw new Error('Version-control installation not found.');\n const installationId = parsePositiveInteger(installation.externalId);\n if (installationId === null) throw new Error('GitHub installation id is invalid.');\n const repositoryName = splitRepository(repository.slug).repo;\n const token = await this.#client.request<{ token: string }>(\n 'POST',\n `${API_PREFIX}/github-app/installations/${installationId}/token`,\n { repositories: [repositoryName], permissions: REPOSITORY_TOKEN_PERMISSIONS },\n );\n const access: RepositoryAccess = {\n cloneUrl,\n authorization: { scheme: 'bearer', token: token.token },\n };\n setBounded(this.#repositoryAccessCache, cacheKey, {\n access,\n expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS,\n });\n return access;\n },\n listPullRequests: input => this.#listPullRequests(input),\n getPullRequest: input => this.#getPullRequest(input),\n createPullRequest: input => this.#createPullRequest(input),\n updatePullRequest: input => this.#updatePullRequest(input),\n closePullRequest: input => this.#updatePullRequest({ ...input, state: 'closed' }),\n mergePullRequest: input => this.#mergePullRequest(input),\n listComments: input => this.#listComments(input),\n createComment: input => this.#createComment(input),\n updateComment: input => this.#updateComment(input),\n deleteComment: input => this.#deleteComment(input),\n listReviews: input => this.#listReviews(input),\n getReview: input => this.#getReview(input),\n createReview: input => this.#createReview(input),\n updateReview: input => this.#updateReview(input),\n submitReview: input => this.#submitReview(input),\n dismissReview: input => this.#dismissReview(input),\n deletePendingReview: input => this.#deletePendingReview(input),\n listReviewComments: input => this.#listReviewComments(input),\n createReviewComment: input => this.#createReviewComment(input),\n updateReviewComment: input => this.#updateReviewComment(input),\n deleteReviewComment: input => this.#deleteReviewComment(input),\n listRequestedReviewers: input => this.#requestedReviewers('GET', input),\n requestReviewers: input => this.#requestedReviewers('POST', input),\n removeRequestedReviewers: input => this.#requestedReviewers('DELETE', input),\n };\n\n constructor() {\n const config = platformApiClientConfigFromEnv();\n this.#client = new PlatformApiClient(config);\n this.#endpointHost = new URL(config.baseUrl).host;\n this.#pollingEnabled = process.env.MASTRA_PLATFORM_GITHUB_POLLING_ENABLED?.trim().toLowerCase() !== 'false';\n this.#pollingIntervalMs = optionalPositiveIntegerEnv('MASTRA_PLATFORM_GITHUB_POLLING_INTERVAL_MS');\n this.#reconcileEnabled = process.env.MASTRA_PLATFORM_GITHUB_RECONCILE_ENABLED?.trim().toLowerCase() !== 'false';\n }\n\n get storage(): SourceControlStorageHandle {\n if (!this.#storage) throw new Error('PlatformGithubIntegration source-control storage has not been initialized.');\n return this.#storage;\n }\n\n get sourceControlStorage(): SourceControlStorageHandle {\n return this.storage;\n }\n\n get integrationStorage(): GithubSubscriptionStorage {\n if (!this.#integrationStorage) {\n throw new Error('PlatformGithubIntegration generic storage has not been initialized.');\n }\n return this.#integrationStorage;\n }\n\n /** Resolve a stored GitHub locator without scanning installations or repositories. */\n async #resolveIntakeDispatch({\n orgId,\n externalSource,\n }: {\n orgId: string;\n externalSource: { type: string; externalId: string };\n }): Promise<{ connection: IntegrationConnection; sourceId: string; issueId: string } | null> {\n const target = parseGithubExternalTarget(externalSource.externalId);\n if (!target) return null;\n const repository = target.repository.includes('/')\n ? target.repository\n : (await this.storage.repositories.findByExternalId({ orgId, externalId: target.repository }))?.slug;\n if (!repository) return null;\n return {\n connection: { type: 'app-installation', installationId: 1 },\n sourceId: repository,\n issueId: target.issueId,\n };\n }\n\n initialize({ storage }: { storage: IntegrationStorageHandle }): void {\n this.#integrationStorage = storage as unknown as GithubSubscriptionStorage;\n logPlatformInfo('Platform GitHub integration initialized', {\n endpointHost: this.#endpointHost,\n pollingEnabled: this.#pollingEnabled,\n pollingIntervalMs: this.#pollingIntervalMs,\n reconcileEnabled: this.#reconcileEnabled,\n });\n }\n\n routes(ctx: IntegrationContext): ApiRoute[] {\n const ingestFactoryEvent = attachGithubRules(this, ctx);\n return [\n this.#statusRoute(ctx),\n this.#connectRoute(ctx),\n this.#connectUserRoute(ctx),\n ...buildGithubRoutes({\n auth: ctx.auth,\n fleet: ctx.fleet,\n storage: ctx.factoryStorage,\n github: this as unknown as GithubIntegration,\n stateSigner: ctx.stateSigner,\n baseUrl: ctx.baseUrl,\n controller: ctx.controller,\n projects: ctx.storage.projects,\n emitAudit: ctx.hooks?.emitAudit,\n ingestFactoryEvent,\n }).filter(\n route =>\n route.path !== '/web/github/status' &&\n route.path !== '/web/github/webhook' &&\n !route.path.startsWith('/auth/github/'),\n ),\n ];\n }\n\n #statusRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/web/github/status', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant) return c.json({ error: 'unauthorized', reason: 'auth_required' }, 401);\n if (!tenant.orgId) {\n return c.json({\n enabled: true,\n sandboxEnabled: ctx.fleet.enabled,\n organizationRequired: true,\n connected: false,\n installations: [],\n userConnected: false,\n userGithubUsername: null,\n reason: 'organization_required',\n diagnostics: this.diagnostics(),\n });\n }\n\n const [installations, userConnection] = await Promise.all([\n this.#syncInstallations(tenant.orgId, tenant.userId),\n this.#fetchUserConnection(tenant.userId),\n ]);\n return c.json({\n enabled: true,\n sandboxEnabled: ctx.fleet.enabled,\n connected: installations.length > 0,\n installations: installations.map(installation => ({\n installationId: Number(installation.externalId),\n accountLogin: installation.accountName,\n accountType: installation.accountType,\n })),\n userConnected: userConnection.connected,\n userGithubUsername: userConnection.githubUsername,\n reason: installations.length > 0 ? 'ready' : 'not_connected',\n diagnostics: this.diagnostics(),\n });\n },\n });\n }\n\n #connectRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/auth/github/connect', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant?.orgId) return c.json({ error: 'unauthorized' }, 401);\n\n const redirectTo = c.req.query('redirectTo') || c.req.query('return_to') || '/';\n const originator = routeBaseUrl(ctx, c.req.url);\n logPlatformInfo('Starting Platform GitHub connect flow', {\n orgId: tenant.orgId,\n redirectTo,\n originator,\n });\n const query = new URLSearchParams({\n action: 'install',\n redirectTo,\n originator,\n });\n const { url } = await this.#client.request<{ url: string }>(\n 'GET',\n `${API_PREFIX}/github-app/install-url?${query}`,\n );\n return c.redirect(url);\n },\n });\n }\n\n #connectUserRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/auth/github/connect-user', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant?.orgId) return c.json({ error: 'unauthorized' }, 401);\n\n const redirectTo = c.req.query('redirectTo') || c.req.query('return_to') || '/';\n const originator = routeBaseUrl(ctx, c.req.url);\n logPlatformInfo('Starting Platform GitHub user authorization flow', {\n orgId: tenant.orgId,\n redirectTo,\n originator,\n });\n const query = new URLSearchParams({\n userId: tenant.userId,\n redirectTo,\n originator,\n });\n const { url } = await this.#client.request<{ url: string }>(\n 'GET',\n `${API_PREFIX}/github-app/authenticate?${query}`,\n );\n return c.redirect(url);\n },\n });\n }\n\n /**\n * Personal GitHub connection status for the acting user. Returns\n * not-connected when the platform predates the user-connection endpoint.\n */\n async #fetchUserConnection(userId: string): Promise<PlatformGithubUserConnection> {\n try {\n const connection = await this.#client.request<PlatformGithubUserConnection>(\n 'GET',\n `${API_PREFIX}/github-app/user-connection?${new URLSearchParams({ userId })}`,\n );\n if (!connection.connected && connection.reason) {\n logPlatformWarn('Platform GitHub user connection verification failed', {\n userId,\n reason: connection.reason,\n });\n }\n return connection;\n } catch {\n return { connected: false, githubUsername: null };\n }\n }\n\n async #syncInstallations(orgId: string, userId: string): Promise<SourceControlInstallation[]> {\n const result = await this.#client.request<{ installations: PlatformGithubInstallation[] }>(\n 'GET',\n `${API_PREFIX}/github-app/installations`,\n );\n const usableInstallations = result.installations.filter(\n installation => installation.usable && !installation.suspendedAt,\n );\n return Promise.all(\n usableInstallations.map(installation =>\n this.versionControl.registerInstallation({\n orgId,\n userId,\n installation: {\n externalId: String(installation.installationId),\n accountName: installation.accountLogin,\n accountType: installation.accountType,\n },\n }),\n ),\n );\n }\n\n workers(ctx: IntegrationContext): PlatformGithubEventWorker[] {\n if (!this.#pollingEnabled && !this.#reconcileEnabled) return [];\n if (!ctx.controller) {\n throw new Error('Platform GitHub event polling requires the mounted Mastra Code controller.');\n }\n return [\n new PlatformGithubEventWorker({\n client: this.#client,\n controller: ctx.controller,\n github: this,\n storage: ctx.storage.generic as unknown as PlatformGithubEventStorage,\n ingestFactoryEvent: attachGithubRules(this, ctx),\n reconcileFactoryState: this.#reconcileEnabled\n ? attachGithubReconciler(this, ctx, input => this.fetchPullRequestState(input))\n : undefined,\n pollEventsEnabled: this.#pollingEnabled,\n intervalMs: this.#pollingIntervalMs,\n }),\n ];\n }\n\n /**\n * Reads live PR state through the Platform GitHub proxy for the merge\n * reconciler. Returns undefined when the PR cannot be resolved (missing,\n * proxy error) so a sweep never fabricates a merge.\n */\n async fetchPullRequestState(input: {\n installationId: number;\n repository: string;\n number: number;\n }): Promise<ReconcilePullRequestState | undefined> {\n let repository: { owner: string; repo: string };\n try {\n repository = splitRepository(input.repository);\n } catch {\n return undefined;\n }\n try {\n const result = await this.#client.request<{\n title?: string;\n html_url?: string;\n state?: string;\n merged?: boolean;\n created_at?: string;\n merged_by?: { login?: string } | null;\n head?: { ref?: string };\n base?: { ref?: string };\n }>(\n 'GET',\n `${API_PREFIX}/github/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.repo)}/pulls/${input.number}`,\n );\n return {\n title: result.title ?? `PR ${input.number}`,\n url: result.html_url ?? `https://github.com/${input.repository}/pull/${input.number}`,\n state: result.state === 'closed' ? 'closed' : 'open',\n merged: result.merged === true,\n headBranch: result.head?.ref ?? '',\n baseBranch: result.base?.ref ?? '',\n ...(result.created_at ? { createdAt: result.created_at } : {}),\n ...(result.merged_by?.login ? { mergedBy: result.merged_by.login } : {}),\n };\n } catch {\n return undefined;\n }\n }\n\n sessionTools({ requestContext }: { requestContext: RequestContext }): IntegrationTools {\n return createGithubSubscriptionTools(requestContext, this as unknown as GithubIntegration);\n }\n\n async postToolObserver({\n toolContext,\n requestContext,\n }: Parameters<NonNullable<FactoryIntegration['postToolObserver']>>[0]): Promise<void> {\n const pullRequestUrl = parseCreatedPullRequest(toolContext);\n if (!pullRequestUrl || !requestContext) return;\n await subscribeCurrentSessionToPullRequest(\n requestContext,\n pullRequestUrl,\n 'auto-gh-pr-create',\n this as unknown as GithubIntegration,\n );\n }\n\n diagnostics(): Record<string, unknown> {\n return {\n mode: 'platform',\n endpointHost: this.#endpointHost,\n polling: {\n enabled: this.#pollingEnabled,\n ...(this.#pollingIntervalMs === undefined ? {} : { intervalMs: this.#pollingIntervalMs }),\n },\n reconcile: { enabled: this.#reconcileEnabled },\n };\n }\n\n async getRepositoryCollaboratorPermission(\n _installationId: number,\n repoFullName: string,\n username: string,\n signal?: AbortSignal,\n ): Promise<GithubRepositoryPermission | undefined> {\n let repository: { owner: string; repo: string };\n try {\n repository = splitRepository(repoFullName);\n } catch {\n return undefined;\n }\n try {\n const result = await this.#client.request<{ permission: GithubRepositoryPermission }>(\n 'GET',\n `${API_PREFIX}/github/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.repo)}/collaborators/${encodeURIComponent(username)}/permission`,\n undefined,\n { signal },\n );\n return result.permission;\n } catch {\n return undefined;\n }\n }\n\n async listInstallationRepos(installationId: number): Promise<RepoSummary[]> {\n // Hot in two places — the repos route and token minting (which re-lists\n // only to validate the 1–10 repo rule). A short TTL collapses repeat\n // Platform round trips within one UI interaction.\n const cached = this.#installationReposCache.get(installationId);\n if (cached && cached.expiresAt > Date.now()) return cached.repos;\n this.#installationReposCache.delete(installationId);\n\n const result = await this.#client.request<{\n repositories: Array<{\n id: number;\n owner: string;\n name: string;\n fullName: string;\n private: boolean;\n defaultBranch: string;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations/${installationId}/repositories`);\n const repos = result.repositories.map(repository => ({ ...repository, installationId }));\n setBounded(this.#installationReposCache, installationId, {\n repos,\n expiresAt: Date.now() + INSTALLATION_REPOS_CACHE_TTL_MS,\n });\n return repos;\n }\n\n async mintInstallationToken(installationId: number): Promise<string> {\n const repositories = await this.listInstallationRepos(installationId);\n if (repositories.length === 0 || repositories.length > 10) {\n throw new Error('Platform GitHub token minting requires between one and ten installation repositories.');\n }\n const result = await this.#client.request<{ token: string }>(\n 'POST',\n `${API_PREFIX}/github-app/installations/${installationId}/token`,\n { repositories: repositories.map(repository => repository.name), permissions: REPOSITORY_TOKEN_PERMISSIONS },\n );\n return result.token;\n }\n\n async addIssueLabels(\n _installationId: number,\n sourceId: string,\n issueNumber: number,\n labels: string[],\n ): Promise<string[]> {\n const result = await this.#client.request<{ labels: string[] }>(\n 'POST',\n repositoryPath(sourceId, `issues/${issueNumber}/labels`),\n { labels },\n );\n return result.labels;\n }\n\n getInstallationOctokit(_installationId: number): ReturnType<GithubIntegration['getInstallationOctokit']> {\n return {\n pulls: {\n get: async ({ owner, repo, pull_number }: { owner: string; repo: string; pull_number: number }) => {\n const data = await this.#client.request<GithubPullRequest>(\n 'GET',\n repositoryPath(`${owner}/${repo}`, `pulls/${pull_number}`),\n );\n return { data: { base: { repo: { id: data.base.repo.id } } } };\n },\n },\n } as unknown as ReturnType<GithubIntegration['getInstallationOctokit']>;\n }\n\n async #listIssues(connection: IntegrationConnection, sourceId: string, page: number, labels?: string[]) {\n requireGithubConnection(connection);\n const path = repositoryPath(sourceId, 'issues');\n const query = new URLSearchParams({ state: 'open', page: String(page), per_page: String(PAGE_SIZE) });\n const normalizedLabels = normalizeLabels(labels);\n if (normalizedLabels.length > 0) query.set('label', normalizedLabels.join(','));\n const result = await this.#client.request<{ issues: GithubIssue[] }>('GET', `${path}?${query}`);\n return {\n issues: result.issues.map(issue => parseIntakeIssue(sourceId, issue)),\n nextCursor: result.issues.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getIssue(connection: IntegrationConnection, sourceId: string | undefined, issueId: string) {\n requireGithubConnection(connection);\n const repository = requireSource(sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(issueId, 'issue');\n try {\n const [issue, comments] = await Promise.all([\n this.#client.request<GithubIssue>('GET', repositoryPath(repository, `issues/${issueNumber}`)),\n this.#client.request<{ comments: GithubComment[] }>(\n 'GET',\n `${repositoryPath(repository, `issues/${issueNumber}/comments`)}?per_page=100`,\n ),\n ]);\n return parseIntakeIssueDetail(repository, issue, comments.comments);\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #updateIntakeIssue(input: UpdateIntakeIssueInput): Promise<IntakeIssue | null> {\n requireGithubConnection(input.connection);\n const repository = requireSource(input.sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(input.issueId, 'issue');\n if (input.state.kind === 'byName') {\n logPlatformWarn(`Platform GitHub: updateIssue byName is not supported (name=${input.state.name}); ignoring.`);\n return null;\n }\n const targetState: 'open' | 'closed' =\n input.state.stateType === 'unstarted' || input.state.stateType === 'started' ? 'open' : 'closed';\n const stateReason: 'completed' | 'not_planned' | null =\n targetState === 'closed' ? (input.state.stateType === 'canceled' ? 'not_planned' : 'completed') : null;\n // Reject PR targets: probe the pulls endpoint. A 200 means the number is a\n // pull request, not an issue. Factory does not close PRs via updateIssue —\n // PR merges/closes go through the version-control pipeline.\n try {\n await this.#client.request<GithubPullRequest>('GET', repositoryPath(repository, `pulls/${issueNumber}`));\n logPlatformWarn(`Platform GitHub: updateIssue rejected — target ${repository}#${issueNumber} is a pull request.`);\n return null;\n } catch (error) {\n if (!isNotFound(error)) throw error;\n // 404 on pulls means it's an issue (or nothing) — fall through to PATCH.\n }\n try {\n const issue = await this.#client.request<GithubIssue>(\n 'PATCH',\n repositoryPath(repository, `issues/${issueNumber}`),\n {\n state: targetState,\n ...(stateReason ? { state_reason: stateReason } : {}),\n },\n { actingUserId: input.actingUserId },\n );\n return parseIntakeIssue(repository, issue);\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createIssueComment(input: CreateIntakeCommentInput) {\n requireGithubConnection(input.connection);\n const repository = requireSource(input.sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(input.issueId, 'issue');\n try {\n const comment = await this.#client.request<GithubComment>(\n 'POST',\n repositoryPath(repository, `issues/${issueNumber}/comments`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return { id: String(comment.id), url: comment.htmlUrl };\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #listPullRequests(input: ListPullRequestsInput) {\n requireGithubConnection(input.connection);\n const page = parsePositiveCursor(input.cursor);\n const query = new URLSearchParams({\n state: input.state ?? 'open',\n page: String(page),\n per_page: String(PAGE_SIZE),\n });\n const result = await this.#client.request<{ pullRequests: GithubPullRequest[] }>(\n 'GET',\n `${repositoryPath(input.sourceId, 'pulls')}?${query}`,\n );\n return {\n pullRequests: result.pullRequests\n .filter(pullRequest => input.includeDrafts !== false || !pullRequest.draft)\n .map(parsePullRequest),\n nextCursor: result.pullRequests.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getPullRequest(input: PullRequestRef) {\n try {\n return parsePullRequest(\n await this.#client.request<GithubPullRequest>('GET', pullRequestPath(input, input.pullRequestId)),\n );\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createPullRequest(input: CreatePullRequestInput) {\n requireGithubConnection(input.connection);\n const result = await this.#client.request<GithubPullRequest>(\n 'POST',\n repositoryPath(input.sourceId, 'pulls'),\n {\n head: input.headBranch,\n base: input.baseBranch,\n title: input.title,\n body: input.body,\n draft: input.draft,\n },\n { actingUserId: input.actingUserId },\n );\n return parsePullRequest(result);\n }\n\n async #updatePullRequest(input: UpdatePullRequestInput) {\n const result = await this.#client.request<GithubPullRequest>(\n 'PATCH',\n pullRequestPath(input, input.pullRequestId),\n {\n title: input.title,\n body: input.body === null ? '' : input.body,\n base: input.baseBranch,\n state: input.state,\n },\n { actingUserId: input.actingUserId },\n );\n return parsePullRequest(result);\n }\n\n #mergePullRequest(input: MergePullRequestInput) {\n return this.#client.request<{ merged: boolean; message: string; sha: string | null }>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/merge`,\n { commitTitle: input.commitTitle, commitMessage: input.commitMessage, method: input.method },\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listComments(input: ListPullRequestCommentsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ comments: GithubComment[] }>(\n 'GET',\n `${repositoryPath(input.sourceId, `issues/${requirePositiveId(input.pullRequestId, 'pull request')}/comments`)}?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n comments: result.comments.map(parseComment),\n nextCursor: result.comments.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #createComment(input: CreatePullRequestCommentInput) {\n const comment = await this.#client.request<GithubComment>(\n 'POST',\n repositoryPath(input.sourceId, `issues/${requirePositiveId(input.pullRequestId, 'pull request')}/comments`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseComment(comment);\n }\n\n async #updateComment(input: UpdatePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n const comment = await this.#client.request<GithubComment>(\n 'PATCH',\n repositoryPath(input.sourceId, `issues/comments/${requirePositiveId(input.commentId, 'comment')}`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseComment(comment);\n }\n\n async #deleteComment(input: DeletePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n await this.#client.request<void>(\n 'DELETE',\n repositoryPath(input.sourceId, `issues/comments/${requirePositiveId(input.commentId, 'comment')}`),\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listReviews(input: ListReviewsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ reviews: GithubReview[] }>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/reviews?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n reviews: result.reviews.map(parseReview),\n nextCursor: result.reviews.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getReview(input: ReviewRef) {\n try {\n return parseReview(\n await this.#client.request<GithubReview>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n ),\n );\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createReview(input: CreateReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/reviews`,\n { body: input.body, commitId: input.commitId, event: input.event ? reviewEvent(input.event) : undefined },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #updateReview(input: UpdateReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #submitReview(input: SubmitReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}/events`,\n { body: input.body, event: reviewEvent(input.event) },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #dismissReview(input: DismissReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}/dismissals`,\n { message: input.message },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #deletePendingReview(input: ReviewRef) {\n await this.#client.request<void>(\n 'DELETE',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listReviewComments(input: ListReviewCommentsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ comments: GithubReviewComment[] }>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/comments?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n comments: result.comments.map(parseReviewComment),\n nextCursor: result.comments.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #createReviewComment(input: CreateReviewCommentInput) {\n let body: Record<string, unknown>;\n if (input.replyToId !== undefined) {\n body = { body: input.body, replyToId: requirePositiveId(input.replyToId, 'review comment') };\n } else {\n if (!input.commitId || !input.path || input.line === undefined || !input.side) {\n throw new Error('A review comment requires commitId, path, line, and side unless it is a reply.');\n }\n body = {\n body: input.body,\n commitId: input.commitId,\n path: input.path,\n line: input.line,\n side: input.side.toUpperCase(),\n startLine: input.startLine,\n startSide: input.startSide?.toUpperCase(),\n };\n }\n return parseReviewComment(\n await this.#client.request<GithubReviewComment>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/comments`,\n body,\n { actingUserId: input.actingUserId },\n ),\n );\n }\n\n async #updateReviewComment(input: UpdatePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n return parseReviewComment(\n await this.#client.request<GithubReviewComment>(\n 'PATCH',\n repositoryPath(input.sourceId, `pulls/comments/${requirePositiveId(input.commentId, 'review comment')}`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n ),\n );\n }\n\n async #deleteReviewComment(input: DeletePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n await this.#client.request<void>(\n 'DELETE',\n repositoryPath(input.sourceId, `pulls/comments/${requirePositiveId(input.commentId, 'review comment')}`),\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n #requestedReviewers(method: 'GET' | 'POST' | 'DELETE', input: UpdateReviewersInput) {\n requireGithubConnection(input.connection);\n return this.#client.request<{ users: string[]; teams: string[] }>(\n method,\n `${pullRequestPath(input, input.pullRequestId)}/requested-reviewers`,\n method === 'GET' ? undefined : { users: input.users, teams: input.teams },\n method === 'GET' ? undefined : { actingUserId: input.actingUserId },\n );\n }\n}\n\nfunction repositoryPath(sourceId: string, suffix: string): string {\n const { owner, repo } = splitRepository(sourceId);\n return `${API_PREFIX}/github/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${suffix}`;\n}\n\nfunction pullRequestPath(\n input: { connection: IntegrationConnection; sourceId: string },\n pullRequestId: string,\n): string {\n requireGithubConnection(input.connection);\n return repositoryPath(input.sourceId, `pulls/${requirePositiveId(pullRequestId, 'pull request')}`);\n}\n\nfunction splitRepository(sourceId: string): { owner: string; repo: string } {\n const slash = sourceId.indexOf('/');\n if (slash <= 0 || slash === sourceId.length - 1) {\n throw new Error('GitHub capabilities require an owner/repository source.');\n }\n return { owner: sourceId.slice(0, slash), repo: sourceId.slice(slash + 1) };\n}\n\nfunction parseIntakeIssue(sourceId: string, issue: GithubIssue): IntakeIssue {\n return {\n id: String(issue.number),\n identifier: `#${issue.number}`,\n title: issue.title,\n url: issue.htmlUrl,\n author: issue.user?.login ?? null,\n state: issue.state,\n stateType: issue.state,\n priority: null,\n assignee: issue.assignees[0] ?? null,\n source: sourceId,\n labels: issue.labels,\n commentCount: issue.commentCount,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n };\n}\n\nfunction parseIntakeIssueDetail(sourceId: string, issue: GithubIssue, comments: GithubComment[]): IntakeIssueDetail {\n return {\n ...parseIntakeIssue(sourceId, issue),\n description: issue.body?.trim() ? issue.body : null,\n comments: comments.map(comment => ({\n author: comment.user?.login ?? null,\n body: comment.body,\n createdAt: comment.createdAt,\n })),\n };\n}\n\nfunction parsePullRequest(pullRequest: GithubPullRequest): PullRequest {\n return {\n id: String(pullRequest.number),\n title: pullRequest.title,\n url: pullRequest.htmlUrl,\n author: pullRequest.user?.login ?? null,\n body: pullRequest.body?.trim() ? pullRequest.body : null,\n state: pullRequest.state,\n draft: pullRequest.draft,\n merged: pullRequest.merged,\n mergeable: pullRequest.mergeable,\n baseBranch: pullRequest.base.ref,\n headBranch: pullRequest.head.ref,\n headSha: pullRequest.head.sha,\n createdAt: pullRequest.createdAt,\n updatedAt: pullRequest.updatedAt,\n };\n}\n\nfunction parseComment(comment: GithubComment): PullRequestComment {\n return {\n id: String(comment.id),\n url: comment.htmlUrl,\n author: comment.user?.login ?? null,\n body: comment.body,\n createdAt: comment.createdAt,\n updatedAt: comment.updatedAt,\n };\n}\n\nfunction parseReview(review: GithubReview): Review {\n const states: Record<GithubReview['state'], Review['state']> = {\n PENDING: 'pending',\n COMMENTED: 'commented',\n APPROVED: 'approved',\n CHANGES_REQUESTED: 'changes-requested',\n DISMISSED: 'dismissed',\n };\n return {\n id: String(review.id),\n url: review.htmlUrl,\n author: review.user?.login ?? null,\n body: review.body?.trim() ? review.body : null,\n state: states[review.state],\n commitId: review.commitId,\n submittedAt: review.submittedAt,\n };\n}\n\nfunction parseReviewComment(comment: GithubReviewComment): ReviewComment {\n return {\n ...parseComment(comment),\n path: comment.path,\n line: comment.line,\n side: comment.side?.toLowerCase() as 'left' | 'right' | null,\n commitId: comment.commitId,\n replyToId: comment.replyToId === null ? null : String(comment.replyToId),\n };\n}\n\nfunction requireGithubConnection(connection: IntegrationConnection): void {\n if (connection.type !== 'app-installation' && connection.type !== 'oauth') {\n throw new Error('GitHub capabilities require a GitHub connection.');\n }\n}\n\nfunction requireSingleSource(sourceIds: string[], message: string): string {\n if (sourceIds.length !== 1) throw new Error(message);\n return sourceIds[0]!;\n}\n\nfunction requireSource(sourceId: string | undefined, message: string): string {\n if (!sourceId) throw new Error(message);\n return sourceId;\n}\n\nfunction normalizeLabels(labels: string[] | undefined): string[] {\n return [...new Set((labels ?? []).map(label => label.trim()).filter(Boolean))];\n}\n\nfunction parsePositiveCursor(cursor: string | undefined): number {\n if (cursor === undefined) return 1;\n const parsed = parsePositiveInteger(cursor);\n if (parsed === null) throw new Error('GitHub cursor must be a positive page number.');\n return parsed;\n}\n\nfunction parsePositiveInteger(value: string): number | null {\n if (!/^\\d+$/.test(value)) return null;\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction parseGithubExternalTarget(externalId: string): { repository: string; issueId: string } | null {\n const match =\n externalId.match(/^(.+\\/.+):(\\d+)$/) ??\n externalId.match(/^github:(\\d+):(?:issue|pull-request):(\\d+)$/) ??\n externalId.match(/^(\\d+):(\\d+)$/);\n if (!match?.[1] || !match[2] || parsePositiveInteger(match[2]) === null) return null;\n return { repository: match[1], issueId: match[2] };\n}\n\nfunction optionalPositiveIntegerEnv(name: 'MASTRA_PLATFORM_GITHUB_POLLING_INTERVAL_MS'): number | undefined {\n const value = process.env[name]?.trim();\n if (!value) return undefined;\n const parsed = parsePositiveInteger(value);\n if (parsed === null) throw new Error(`${name} must be a positive integer.`);\n return parsed;\n}\n\nfunction requirePositiveId(value: string, resource: string): number {\n const parsed = parsePositiveInteger(value);\n if (parsed === null) throw new Error(`GitHub ${resource} id must be a positive integer.`);\n return parsed;\n}\n\nfunction reviewEvent(event: 'approve' | 'request-changes' | 'comment') {\n if (event === 'approve') return 'APPROVE' as const;\n if (event === 'request-changes') return 'REQUEST_CHANGES' as const;\n return 'COMMENT' as const;\n}\n\nfunction isNotFound(error: unknown): boolean {\n return error instanceof PlatformApiError && error.status === 404;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"integration.js","names":["#client","#endpointHost","#pollingEnabled","#pollingIntervalMs","#reconcileEnabled","#installationReposCache","#repositoryAccessCache","#resolveIntakeDispatch","#listIssues","#listPullRequests","#getIssue","#createIssueComment","#updateIntakeIssue","#storage","#getPullRequest","#createPullRequest","#updatePullRequest","#mergePullRequest","#listComments","#createComment","#updateComment","#deleteComment","#listReviews","#getReview","#createReview","#updateReview","#submitReview","#dismissReview","#deletePendingReview","#listReviewComments","#createReviewComment","#updateReviewComment","#deleteReviewComment","#requestedReviewers","#integrationStorage","#statusRoute","#connectRoute","#connectUserRoute","#syncInstallations","#fetchUserConnection"],"sources":["../../../../src/integrations/platform/github/integration.ts"],"sourcesContent":["import type { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\nimport type { IntegrationConnection } from '../../../capabilities/connection.js';\nimport type {\n CreateIntakeCommentInput,\n Intake,\n IntakeIssue,\n IntakeIssueDetail,\n UpdateIntakeIssueInput,\n} from '../../../capabilities/intake.js';\nimport type {\n CreatePullRequestCommentInput,\n CreatePullRequestInput,\n CreateReviewCommentInput,\n CreateReviewInput,\n DeletePullRequestCommentInput,\n DismissReviewInput,\n ListPullRequestCommentsInput,\n ListPullRequestsInput,\n ListReviewCommentsInput,\n ListReviewsInput,\n MergePullRequestInput,\n PullRequest,\n PullRequestComment,\n PullRequestRef,\n RepositoryAccess,\n Review,\n ReviewComment,\n ReviewRef,\n SubmitReviewInput,\n UpdatePullRequestCommentInput,\n UpdatePullRequestInput,\n UpdateReviewInput,\n UpdateReviewersInput,\n VersionControl,\n} from '../../../capabilities/version-control.js';\nimport type { IntegrationStorageHandle } from '../../../storage/domains/integrations/base.js';\nimport type {\n SourceControlInstallation,\n SourceControlStorageHandle,\n} from '../../../storage/domains/source-control/base.js';\nimport type { FactoryIntegration, IntegrationContext, IntegrationTools } from '../../base.js';\nimport type { GithubIntegration, GithubRepositoryPermission, RepoSummary } from '../../github/integration.js';\nimport { buildGithubRoutes } from '../../github/routes.js';\nimport { attachGithubReconciler, attachGithubRules } from '../../github/rules.js';\nimport type { ReconcilePullRequestState } from '../../github/rules.js';\nimport {\n createGithubSubscriptionTools,\n parseCreatedPullRequest,\n subscribeCurrentSessionToPullRequest,\n} from '../../github/session-subscriptions.js';\nimport type { GithubSubscriptionStorage } from '../../github/subscriptions.js';\nimport {\n logPlatformInfo,\n logPlatformWarn,\n PlatformApiClient,\n PlatformApiError,\n platformApiClientConfigFromEnv,\n} from '../api-client.js';\nimport { PlatformGithubEventWorker } from './event-worker.js';\nimport type { PlatformGithubEventStorage } from './event-worker.js';\n\ntype GithubActor = { login: string; avatarUrl: string | null; htmlUrl: string | null } | null;\n\ntype PlatformGithubInstallation = {\n installationId: number;\n accountLogin: string;\n accountType: string;\n suspendedAt: string | null;\n usable: boolean;\n};\n\ntype PlatformGithubUserConnection = {\n connected: boolean;\n githubUsername: string | null;\n reason?: 'token-invalid' | 'no-accessible-installation' | 'missing-permissions' | 'verification-unavailable' | null;\n};\n\ntype GithubIssue = {\n number: number;\n state: 'open' | 'closed';\n title: string;\n body: string | null;\n htmlUrl: string;\n labels: string[];\n assignees: string[];\n commentCount: number;\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubComment = {\n id: number;\n body: string;\n htmlUrl: string;\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubPullRequest = {\n number: number;\n title: string;\n body: string | null;\n state: 'open' | 'closed';\n htmlUrl: string;\n merged: boolean;\n mergeable: boolean | null;\n draft: boolean;\n head: { ref: string; sha: string };\n base: { ref: string; repo: { id: number; fullName: string } };\n user: GithubActor;\n createdAt: string;\n updatedAt: string;\n};\n\ntype GithubReview = {\n id: number;\n htmlUrl: string | null;\n body: string | null;\n state: 'PENDING' | 'COMMENTED' | 'APPROVED' | 'CHANGES_REQUESTED' | 'DISMISSED';\n commitId: string | null;\n submittedAt: string | null;\n user: GithubActor;\n};\n\ntype GithubReviewComment = GithubComment & {\n path: string;\n line: number | null;\n side: 'LEFT' | 'RIGHT' | null;\n commitId: string;\n replyToId: number | null;\n};\n\nconst PAGE_SIZE = 30;\nconst API_PREFIX = '/v1/server';\n/**\n * How long an installation's repository listing may be reused. The repos\n * route and token minting both call it — often several times within one UI\n * interaction — and each call is a full Platform round trip.\n */\nconst INSTALLATION_REPOS_CACHE_TTL_MS = 30_000;\n/**\n * How long a minted repository-scoped token may be reused. GitHub\n * installation tokens live ~60 minutes; 5 minutes keeps a wide validity\n * margin while collapsing the per-session-materialization mint round trip.\n */\nconst REPOSITORY_ACCESS_CACHE_TTL_MS = 5 * 60_000;\n/**\n * Upper bound for both TTL caches. Entries expire lazily on re-access, so\n * without a hard cap keys that stop being queried would accumulate for the\n * integration's (long) lifetime. Insertion-order eviction — matches the\n * bounded verification cache in `@mastra/auth-studio`.\n */\nconst MAX_CACHE_ENTRIES = 1000;\n\nfunction setBounded<K, V>(cache: Map<K, V>, key: K, value: V): void {\n cache.delete(key);\n cache.set(key, value);\n if (cache.size > MAX_CACHE_ENTRIES) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n}\n\nconst REPOSITORY_TOKEN_PERMISSIONS = {\n contents: 'write',\n issues: 'write',\n pull_requests: 'write',\n} as const;\n\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\nfunction routeBaseUrl(ctx: IntegrationContext, requestUrl: string): string {\n return (ctx.baseUrl || new URL(requestUrl).origin).replace(/\\/+$/, '');\n}\n\nexport class PlatformGithubIntegration implements FactoryIntegration {\n readonly id = 'github';\n readonly #client: PlatformApiClient;\n readonly #endpointHost: string;\n readonly #pollingEnabled: boolean;\n readonly #pollingIntervalMs: number | undefined;\n readonly #reconcileEnabled: boolean;\n #storage: SourceControlStorageHandle | undefined;\n #integrationStorage: GithubSubscriptionStorage | undefined;\n /** installationId → cached repository listing (TTL-bounded). */\n readonly #installationReposCache = new Map<number, { repos: RepoSummary[]; expiresAt: number }>();\n /** `orgId:repositoryId` → cached repository access (TTL-bounded). */\n readonly #repositoryAccessCache = new Map<string, { access: RepositoryAccess; expiresAt: number }>();\n\n readonly intake: Intake = {\n resolveIntakeDispatch: input => this.#resolveIntakeDispatch(input),\n listSources: async ({ orgId, userId }) => {\n const installations = await this.#client.request<{\n installations: Array<{\n installationId: number;\n accountLogin: string;\n accountType: string;\n suspendedAt: string | null;\n usable: boolean;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations`);\n const usable = installations.installations.filter(\n installation => installation.usable && !installation.suspendedAt,\n );\n const repositories = await Promise.all(\n usable.map(async installation => {\n const storedInstallation = await this.versionControl.registerInstallation({\n orgId,\n userId,\n installation: {\n externalId: String(installation.installationId),\n accountName: installation.accountLogin,\n accountType: installation.accountType,\n },\n });\n const result = await this.#client.request<{\n repositories: Array<{\n id: number;\n fullName: string;\n private: boolean;\n defaultBranch: string;\n htmlUrl: string;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations/${installation.installationId}/repositories`);\n await this.versionControl.registerRepositories({\n orgId,\n installationId: storedInstallation.id,\n repositories: result.repositories.map(repository => ({\n externalId: String(repository.id),\n slug: repository.fullName,\n defaultBranch: repository.defaultBranch,\n metadata: { private: repository.private, url: repository.htmlUrl },\n })),\n });\n return result.repositories.map(repository => ({ repository, installation }));\n }),\n );\n return repositories.flat().map(({ repository, installation }) => ({\n id: repository.fullName,\n name: repository.fullName,\n type: 'repository',\n metadata: {\n installationId: installation.installationId,\n accountLogin: installation.accountLogin,\n accountType: installation.accountType,\n repositoryId: repository.id,\n defaultBranch: repository.defaultBranch,\n private: repository.private,\n url: repository.htmlUrl,\n },\n }));\n },\n listItems: async ({ sourceIds, cursor }) => {\n const page = parsePositiveCursor(cursor);\n const pages = await Promise.all(\n sourceIds.map(async sourceId => {\n const connection = { type: 'app-installation' as const, installationId: 1 };\n const [issues, pullRequests] = await Promise.all([\n this.#listIssues(connection, sourceId, page),\n this.#listPullRequests({ connection, sourceId, includeDrafts: false, cursor: String(page) }),\n ]);\n return {\n items: [\n ...issues.issues.map(issue => ({\n source: { type: 'issue', externalId: `${sourceId}:${issue.id}`, url: issue.url },\n sourceId,\n title: issue.title,\n status: issue.state ?? undefined,\n labels: issue.labels,\n assignee: issue.assignee,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n metadata: { repository: sourceId, number: Number(issue.id), author: issue.author },\n })),\n ...pullRequests.pullRequests.map(pullRequest => ({\n source: { type: 'pull-request', externalId: `${sourceId}:${pullRequest.id}`, url: pullRequest.url },\n sourceId,\n title: pullRequest.title,\n status: pullRequest.state,\n createdAt: pullRequest.createdAt,\n updatedAt: pullRequest.updatedAt,\n metadata: {\n repository: sourceId,\n number: Number(pullRequest.id),\n author: pullRequest.author,\n baseBranch: pullRequest.baseBranch,\n headBranch: pullRequest.headBranch,\n },\n })),\n ],\n hasNextPage: issues.nextCursor !== null || pullRequests.nextCursor !== null,\n };\n }),\n );\n return {\n items: pages.flatMap(result => result.items),\n nextCursor: pages.some(result => result.hasNextPage) ? String(page + 1) : null,\n };\n },\n listIssues: async input => {\n requireGithubConnection(input.connection);\n const sourceId = requireSingleSource(input.sourceIds, 'GitHub Intake requires exactly one repository source.');\n return this.#listIssues(input.connection, sourceId, parsePositiveCursor(input.cursor), input.labels);\n },\n getIssue: input => this.#getIssue(input.connection, input.sourceId, input.issueId),\n createComment: input => this.#createIssueComment(input),\n updateIssue: input => this.#updateIntakeIssue(input),\n };\n\n readonly versionControl: VersionControl = {\n initialize: ({ storage }) => {\n this.#storage = storage;\n },\n registerInstallation: ({ orgId, userId, installation }) =>\n this.storage.installations.upsert({\n orgId,\n connectedByUserId: userId,\n externalId: installation.externalId,\n accountName: installation.accountName,\n accountType: installation.accountType,\n providerMetadata: installation.metadata,\n }),\n registerRepositories: ({ orgId, installationId, repositories }) =>\n Promise.all(\n repositories.map(repository =>\n this.storage.repositories.upsert({\n orgId,\n input: {\n installationId,\n externalId: repository.externalId,\n slug: repository.slug,\n defaultBranch: repository.defaultBranch,\n providerMetadata: repository.metadata,\n },\n }),\n ),\n ),\n getRepositoryAccess: async ({ orgId, repositoryId }) => {\n // Every session materialization requests access; reuse a recent grant\n // instead of re-minting through the Platform each time. The TTL keeps\n // a wide margin under GitHub's ~60min installation-token lifetime.\n const cacheKey = `${orgId}:${repositoryId}`;\n const cached = this.#repositoryAccessCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.access;\n this.#repositoryAccessCache.delete(cacheKey);\n\n const repository = await this.storage.repositories.get({ orgId, id: repositoryId });\n if (!repository) throw new Error('Version-control repository not found.');\n const cloneUrl = `https://github.com/${repository.slug}.git`;\n const installation = await this.storage.installations.get({ orgId, id: repository.installationId });\n if (!installation) throw new Error('Version-control installation not found.');\n const installationId = parsePositiveInteger(installation.externalId);\n if (installationId === null) throw new Error('GitHub installation id is invalid.');\n const repositoryName = splitRepository(repository.slug).repo;\n\n try {\n const token = await this.#client.request<{ token: string }>(\n 'POST',\n `${API_PREFIX}/github-app/installations/${installationId}/token`,\n { repositories: [repositoryName], permissions: REPOSITORY_TOKEN_PERMISSIONS },\n );\n const access: RepositoryAccess = {\n cloneUrl,\n authorization: { scheme: 'bearer', token: token.token },\n };\n setBounded(this.#repositoryAccessCache, cacheKey, {\n access,\n expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS,\n });\n return access;\n } catch (err) {\n // Recover from stale installation: when a GitHub App is uninstalled and reinstalled,\n // GitHub assigns a new installation ID. Platform creates a new installation row,\n // and Factory's intake.listSources creates a new local installation row with the\n // new externalId. Try to find the new installation by accountName.\n if (!isNotFound(err) || !installation.accountName) throw err;\n const installations = await this.storage.installations.list({ orgId });\n const newInstallation = installations.find(\n inst => inst.accountName === installation.accountName && inst.id !== installation.id,\n );\n if (!newInstallation) throw err;\n const newInstallationId = parsePositiveInteger(newInstallation.externalId);\n if (newInstallationId === null) throw err;\n\n // Persist the migration so we don't hit the 404 path on every call.\n // This updates the repository's installation_id to the new installation.\n await this.storage.repositories.migrateInstallation({\n orgId,\n id: repositoryId,\n newInstallationId: newInstallation.id,\n });\n\n const token = await this.#client.request<{ token: string }>(\n 'POST',\n `${API_PREFIX}/github-app/installations/${newInstallationId}/token`,\n { repositories: [repositoryName], permissions: REPOSITORY_TOKEN_PERMISSIONS },\n );\n const access: RepositoryAccess = {\n cloneUrl,\n authorization: { scheme: 'bearer', token: token.token },\n };\n setBounded(this.#repositoryAccessCache, cacheKey, {\n access,\n expiresAt: Date.now() + REPOSITORY_ACCESS_CACHE_TTL_MS,\n });\n return access;\n }\n },\n listPullRequests: input => this.#listPullRequests(input),\n getPullRequest: input => this.#getPullRequest(input),\n createPullRequest: input => this.#createPullRequest(input),\n updatePullRequest: input => this.#updatePullRequest(input),\n closePullRequest: input => this.#updatePullRequest({ ...input, state: 'closed' }),\n mergePullRequest: input => this.#mergePullRequest(input),\n listComments: input => this.#listComments(input),\n createComment: input => this.#createComment(input),\n updateComment: input => this.#updateComment(input),\n deleteComment: input => this.#deleteComment(input),\n listReviews: input => this.#listReviews(input),\n getReview: input => this.#getReview(input),\n createReview: input => this.#createReview(input),\n updateReview: input => this.#updateReview(input),\n submitReview: input => this.#submitReview(input),\n dismissReview: input => this.#dismissReview(input),\n deletePendingReview: input => this.#deletePendingReview(input),\n listReviewComments: input => this.#listReviewComments(input),\n createReviewComment: input => this.#createReviewComment(input),\n updateReviewComment: input => this.#updateReviewComment(input),\n deleteReviewComment: input => this.#deleteReviewComment(input),\n listRequestedReviewers: input => this.#requestedReviewers('GET', input),\n requestReviewers: input => this.#requestedReviewers('POST', input),\n removeRequestedReviewers: input => this.#requestedReviewers('DELETE', input),\n };\n\n constructor() {\n const config = platformApiClientConfigFromEnv();\n this.#client = new PlatformApiClient(config);\n this.#endpointHost = new URL(config.baseUrl).host;\n this.#pollingEnabled = process.env.MASTRA_PLATFORM_GITHUB_POLLING_ENABLED?.trim().toLowerCase() !== 'false';\n this.#pollingIntervalMs = optionalPositiveIntegerEnv('MASTRA_PLATFORM_GITHUB_POLLING_INTERVAL_MS');\n this.#reconcileEnabled = process.env.MASTRA_PLATFORM_GITHUB_RECONCILE_ENABLED?.trim().toLowerCase() !== 'false';\n }\n\n get storage(): SourceControlStorageHandle {\n if (!this.#storage) throw new Error('PlatformGithubIntegration source-control storage has not been initialized.');\n return this.#storage;\n }\n\n get sourceControlStorage(): SourceControlStorageHandle {\n return this.storage;\n }\n\n get integrationStorage(): GithubSubscriptionStorage {\n if (!this.#integrationStorage) {\n throw new Error('PlatformGithubIntegration generic storage has not been initialized.');\n }\n return this.#integrationStorage;\n }\n\n /** Resolve a stored GitHub locator without scanning installations or repositories. */\n async #resolveIntakeDispatch({\n orgId,\n externalSource,\n }: {\n orgId: string;\n externalSource: { type: string; externalId: string };\n }): Promise<{ connection: IntegrationConnection; sourceId: string; issueId: string } | null> {\n const target = parseGithubExternalTarget(externalSource.externalId);\n if (!target) return null;\n const repository = target.repository.includes('/')\n ? target.repository\n : (await this.storage.repositories.findByExternalId({ orgId, externalId: target.repository }))?.slug;\n if (!repository) return null;\n return {\n connection: { type: 'app-installation', installationId: 1 },\n sourceId: repository,\n issueId: target.issueId,\n };\n }\n\n initialize({ storage }: { storage: IntegrationStorageHandle }): void {\n this.#integrationStorage = storage as unknown as GithubSubscriptionStorage;\n logPlatformInfo('Platform GitHub integration initialized', {\n endpointHost: this.#endpointHost,\n pollingEnabled: this.#pollingEnabled,\n pollingIntervalMs: this.#pollingIntervalMs,\n reconcileEnabled: this.#reconcileEnabled,\n });\n }\n\n routes(ctx: IntegrationContext): ApiRoute[] {\n const ingestFactoryEvent = attachGithubRules(this, ctx);\n return [\n this.#statusRoute(ctx),\n this.#connectRoute(ctx),\n this.#connectUserRoute(ctx),\n ...buildGithubRoutes({\n auth: ctx.auth,\n fleet: ctx.fleet,\n storage: ctx.factoryStorage,\n github: this as unknown as GithubIntegration,\n stateSigner: ctx.stateSigner,\n baseUrl: ctx.baseUrl,\n controller: ctx.controller,\n projects: ctx.storage.projects,\n emitAudit: ctx.hooks?.emitAudit,\n ingestFactoryEvent,\n }).filter(\n route =>\n route.path !== '/web/github/status' &&\n route.path !== '/web/github/webhook' &&\n !route.path.startsWith('/auth/github/'),\n ),\n ];\n }\n\n #statusRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/web/github/status', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant) return c.json({ error: 'unauthorized', reason: 'auth_required' }, 401);\n if (!tenant.orgId) {\n return c.json({\n enabled: true,\n sandboxEnabled: ctx.fleet.enabled,\n organizationRequired: true,\n connected: false,\n installations: [],\n userConnected: false,\n userGithubUsername: null,\n reason: 'organization_required',\n diagnostics: this.diagnostics(),\n });\n }\n\n const [installations, userConnection] = await Promise.all([\n this.#syncInstallations(tenant.orgId, tenant.userId),\n this.#fetchUserConnection(tenant.userId),\n ]);\n return c.json({\n enabled: true,\n sandboxEnabled: ctx.fleet.enabled,\n connected: installations.length > 0,\n installations: installations.map(installation => ({\n installationId: Number(installation.externalId),\n accountLogin: installation.accountName,\n accountType: installation.accountType,\n })),\n userConnected: userConnection.connected,\n userGithubUsername: userConnection.githubUsername,\n reason: installations.length > 0 ? 'ready' : 'not_connected',\n diagnostics: this.diagnostics(),\n });\n },\n });\n }\n\n #connectRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/auth/github/connect', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant?.orgId) return c.json({ error: 'unauthorized' }, 401);\n\n const redirectTo = c.req.query('redirectTo') || c.req.query('return_to') || '/';\n const originator = routeBaseUrl(ctx, c.req.url);\n logPlatformInfo('Starting Platform GitHub connect flow', {\n orgId: tenant.orgId,\n redirectTo,\n originator,\n });\n const query = new URLSearchParams({\n action: 'install',\n redirectTo,\n originator,\n });\n const { url } = await this.#client.request<{ url: string }>(\n 'GET',\n `${API_PREFIX}/github-app/install-url?${query}`,\n );\n return c.redirect(url);\n },\n });\n }\n\n #connectUserRoute(ctx: IntegrationContext): ApiRoute {\n return registerApiRoute('/auth/github/connect-user', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n await ctx.auth.ensureUser(loose(c));\n const tenant = ctx.auth.tenant(loose(c));\n if (!tenant?.orgId) return c.json({ error: 'unauthorized' }, 401);\n\n const redirectTo = c.req.query('redirectTo') || c.req.query('return_to') || '/';\n const originator = routeBaseUrl(ctx, c.req.url);\n logPlatformInfo('Starting Platform GitHub user authorization flow', {\n orgId: tenant.orgId,\n redirectTo,\n originator,\n });\n const query = new URLSearchParams({\n userId: tenant.userId,\n redirectTo,\n originator,\n });\n const { url } = await this.#client.request<{ url: string }>(\n 'GET',\n `${API_PREFIX}/github-app/authenticate?${query}`,\n );\n return c.redirect(url);\n },\n });\n }\n\n /**\n * Personal GitHub connection status for the acting user. Returns\n * not-connected when the platform predates the user-connection endpoint.\n */\n async #fetchUserConnection(userId: string): Promise<PlatformGithubUserConnection> {\n try {\n const connection = await this.#client.request<PlatformGithubUserConnection>(\n 'GET',\n `${API_PREFIX}/github-app/user-connection?${new URLSearchParams({ userId })}`,\n );\n if (!connection.connected && connection.reason) {\n logPlatformWarn('Platform GitHub user connection verification failed', {\n userId,\n reason: connection.reason,\n });\n }\n return connection;\n } catch {\n return { connected: false, githubUsername: null };\n }\n }\n\n async #syncInstallations(orgId: string, userId: string): Promise<SourceControlInstallation[]> {\n const result = await this.#client.request<{ installations: PlatformGithubInstallation[] }>(\n 'GET',\n `${API_PREFIX}/github-app/installations`,\n );\n const usableInstallations = result.installations.filter(\n installation => installation.usable && !installation.suspendedAt,\n );\n return Promise.all(\n usableInstallations.map(installation =>\n this.versionControl.registerInstallation({\n orgId,\n userId,\n installation: {\n externalId: String(installation.installationId),\n accountName: installation.accountLogin,\n accountType: installation.accountType,\n },\n }),\n ),\n );\n }\n\n workers(ctx: IntegrationContext): PlatformGithubEventWorker[] {\n if (!this.#pollingEnabled && !this.#reconcileEnabled) return [];\n if (!ctx.controller) {\n throw new Error('Platform GitHub event polling requires the mounted Mastra Code controller.');\n }\n return [\n new PlatformGithubEventWorker({\n client: this.#client,\n controller: ctx.controller,\n github: this,\n storage: ctx.storage.generic as unknown as PlatformGithubEventStorage,\n ingestFactoryEvent: attachGithubRules(this, ctx),\n reconcileFactoryState: this.#reconcileEnabled\n ? attachGithubReconciler(this, ctx, input => this.fetchPullRequestState(input))\n : undefined,\n pollEventsEnabled: this.#pollingEnabled,\n intervalMs: this.#pollingIntervalMs,\n }),\n ];\n }\n\n /**\n * Reads live PR state through the Platform GitHub proxy for the merge\n * reconciler. Returns undefined when the PR cannot be resolved (missing,\n * proxy error) so a sweep never fabricates a merge.\n */\n async fetchPullRequestState(input: {\n installationId: number;\n repository: string;\n number: number;\n }): Promise<ReconcilePullRequestState | undefined> {\n let repository: { owner: string; repo: string };\n try {\n repository = splitRepository(input.repository);\n } catch {\n return undefined;\n }\n try {\n const result = await this.#client.request<{\n title?: string;\n html_url?: string;\n state?: string;\n merged?: boolean;\n created_at?: string;\n merged_by?: { login?: string } | null;\n head?: { ref?: string };\n base?: { ref?: string };\n }>(\n 'GET',\n `${API_PREFIX}/github/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.repo)}/pulls/${input.number}`,\n );\n return {\n title: result.title ?? `PR ${input.number}`,\n url: result.html_url ?? `https://github.com/${input.repository}/pull/${input.number}`,\n state: result.state === 'closed' ? 'closed' : 'open',\n merged: result.merged === true,\n headBranch: result.head?.ref ?? '',\n baseBranch: result.base?.ref ?? '',\n ...(result.created_at ? { createdAt: result.created_at } : {}),\n ...(result.merged_by?.login ? { mergedBy: result.merged_by.login } : {}),\n };\n } catch {\n return undefined;\n }\n }\n\n sessionTools({ requestContext }: { requestContext: RequestContext }): IntegrationTools {\n return createGithubSubscriptionTools(requestContext, this as unknown as GithubIntegration);\n }\n\n async postToolObserver({\n toolContext,\n requestContext,\n }: Parameters<NonNullable<FactoryIntegration['postToolObserver']>>[0]): Promise<void> {\n const pullRequestUrl = parseCreatedPullRequest(toolContext);\n if (!pullRequestUrl || !requestContext) return;\n await subscribeCurrentSessionToPullRequest(\n requestContext,\n pullRequestUrl,\n 'auto-gh-pr-create',\n this as unknown as GithubIntegration,\n );\n }\n\n diagnostics(): Record<string, unknown> {\n return {\n mode: 'platform',\n endpointHost: this.#endpointHost,\n polling: {\n enabled: this.#pollingEnabled,\n ...(this.#pollingIntervalMs === undefined ? {} : { intervalMs: this.#pollingIntervalMs }),\n },\n reconcile: { enabled: this.#reconcileEnabled },\n };\n }\n\n async getRepositoryCollaboratorPermission(\n _installationId: number,\n repoFullName: string,\n username: string,\n signal?: AbortSignal,\n ): Promise<GithubRepositoryPermission | undefined> {\n let repository: { owner: string; repo: string };\n try {\n repository = splitRepository(repoFullName);\n } catch {\n return undefined;\n }\n try {\n const result = await this.#client.request<{ permission: GithubRepositoryPermission }>(\n 'GET',\n `${API_PREFIX}/github/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.repo)}/collaborators/${encodeURIComponent(username)}/permission`,\n undefined,\n { signal },\n );\n return result.permission;\n } catch {\n return undefined;\n }\n }\n\n async listInstallationRepos(installationId: number): Promise<RepoSummary[]> {\n // Hot in two places — the repos route and token minting (which re-lists\n // only to validate the 1–10 repo rule). A short TTL collapses repeat\n // Platform round trips within one UI interaction.\n const cached = this.#installationReposCache.get(installationId);\n if (cached && cached.expiresAt > Date.now()) return cached.repos;\n this.#installationReposCache.delete(installationId);\n\n const result = await this.#client.request<{\n repositories: Array<{\n id: number;\n owner: string;\n name: string;\n fullName: string;\n private: boolean;\n defaultBranch: string;\n }>;\n }>('GET', `${API_PREFIX}/github-app/installations/${installationId}/repositories`);\n const repos = result.repositories.map(repository => ({ ...repository, installationId }));\n setBounded(this.#installationReposCache, installationId, {\n repos,\n expiresAt: Date.now() + INSTALLATION_REPOS_CACHE_TTL_MS,\n });\n return repos;\n }\n\n async mintInstallationToken(installationId: number): Promise<string> {\n const repositories = await this.listInstallationRepos(installationId);\n if (repositories.length === 0 || repositories.length > 10) {\n throw new Error('Platform GitHub token minting requires between one and ten installation repositories.');\n }\n const result = await this.#client.request<{ token: string }>(\n 'POST',\n `${API_PREFIX}/github-app/installations/${installationId}/token`,\n { repositories: repositories.map(repository => repository.name), permissions: REPOSITORY_TOKEN_PERMISSIONS },\n );\n return result.token;\n }\n\n async addIssueLabels(\n _installationId: number,\n sourceId: string,\n issueNumber: number,\n labels: string[],\n ): Promise<string[]> {\n const result = await this.#client.request<{ labels: string[] }>(\n 'POST',\n repositoryPath(sourceId, `issues/${issueNumber}/labels`),\n { labels },\n );\n return result.labels;\n }\n\n getInstallationOctokit(_installationId: number): ReturnType<GithubIntegration['getInstallationOctokit']> {\n return {\n pulls: {\n get: async ({ owner, repo, pull_number }: { owner: string; repo: string; pull_number: number }) => {\n const data = await this.#client.request<GithubPullRequest>(\n 'GET',\n repositoryPath(`${owner}/${repo}`, `pulls/${pull_number}`),\n );\n return { data: { base: { repo: { id: data.base.repo.id } } } };\n },\n },\n } as unknown as ReturnType<GithubIntegration['getInstallationOctokit']>;\n }\n\n async #listIssues(connection: IntegrationConnection, sourceId: string, page: number, labels?: string[]) {\n requireGithubConnection(connection);\n const path = repositoryPath(sourceId, 'issues');\n const query = new URLSearchParams({ state: 'open', page: String(page), per_page: String(PAGE_SIZE) });\n const normalizedLabels = normalizeLabels(labels);\n if (normalizedLabels.length > 0) query.set('label', normalizedLabels.join(','));\n const result = await this.#client.request<{ issues: GithubIssue[] }>('GET', `${path}?${query}`);\n return {\n issues: result.issues.map(issue => parseIntakeIssue(sourceId, issue)),\n nextCursor: result.issues.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getIssue(connection: IntegrationConnection, sourceId: string | undefined, issueId: string) {\n requireGithubConnection(connection);\n const repository = requireSource(sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(issueId, 'issue');\n try {\n const [issue, comments] = await Promise.all([\n this.#client.request<GithubIssue>('GET', repositoryPath(repository, `issues/${issueNumber}`)),\n this.#client.request<{ comments: GithubComment[] }>(\n 'GET',\n `${repositoryPath(repository, `issues/${issueNumber}/comments`)}?per_page=100`,\n ),\n ]);\n return parseIntakeIssueDetail(repository, issue, comments.comments);\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #updateIntakeIssue(input: UpdateIntakeIssueInput): Promise<IntakeIssue | null> {\n requireGithubConnection(input.connection);\n const repository = requireSource(input.sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(input.issueId, 'issue');\n if (input.state.kind === 'byName') {\n logPlatformWarn(`Platform GitHub: updateIssue byName is not supported (name=${input.state.name}); ignoring.`);\n return null;\n }\n const targetState: 'open' | 'closed' =\n input.state.stateType === 'unstarted' || input.state.stateType === 'started' ? 'open' : 'closed';\n const stateReason: 'completed' | 'not_planned' | null =\n targetState === 'closed' ? (input.state.stateType === 'canceled' ? 'not_planned' : 'completed') : null;\n // Reject PR targets: probe the pulls endpoint. A 200 means the number is a\n // pull request, not an issue. Factory does not close PRs via updateIssue —\n // PR merges/closes go through the version-control pipeline.\n try {\n await this.#client.request<GithubPullRequest>('GET', repositoryPath(repository, `pulls/${issueNumber}`));\n logPlatformWarn(`Platform GitHub: updateIssue rejected — target ${repository}#${issueNumber} is a pull request.`);\n return null;\n } catch (error) {\n if (!isNotFound(error)) throw error;\n // 404 on pulls means it's an issue (or nothing) — fall through to PATCH.\n }\n try {\n const issue = await this.#client.request<GithubIssue>(\n 'PATCH',\n repositoryPath(repository, `issues/${issueNumber}`),\n {\n state: targetState,\n ...(stateReason ? { state_reason: stateReason } : {}),\n },\n { actingUserId: input.actingUserId },\n );\n return parseIntakeIssue(repository, issue);\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createIssueComment(input: CreateIntakeCommentInput) {\n requireGithubConnection(input.connection);\n const repository = requireSource(input.sourceId, 'GitHub Intake requires a repository source.');\n const issueNumber = requirePositiveId(input.issueId, 'issue');\n try {\n const comment = await this.#client.request<GithubComment>(\n 'POST',\n repositoryPath(repository, `issues/${issueNumber}/comments`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return { id: String(comment.id), url: comment.htmlUrl };\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #listPullRequests(input: ListPullRequestsInput) {\n requireGithubConnection(input.connection);\n const page = parsePositiveCursor(input.cursor);\n const query = new URLSearchParams({\n state: input.state ?? 'open',\n page: String(page),\n per_page: String(PAGE_SIZE),\n });\n const result = await this.#client.request<{ pullRequests: GithubPullRequest[] }>(\n 'GET',\n `${repositoryPath(input.sourceId, 'pulls')}?${query}`,\n );\n return {\n pullRequests: result.pullRequests\n .filter(pullRequest => input.includeDrafts !== false || !pullRequest.draft)\n .map(parsePullRequest),\n nextCursor: result.pullRequests.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getPullRequest(input: PullRequestRef) {\n try {\n return parsePullRequest(\n await this.#client.request<GithubPullRequest>('GET', pullRequestPath(input, input.pullRequestId)),\n );\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createPullRequest(input: CreatePullRequestInput) {\n requireGithubConnection(input.connection);\n const result = await this.#client.request<GithubPullRequest>(\n 'POST',\n repositoryPath(input.sourceId, 'pulls'),\n {\n head: input.headBranch,\n base: input.baseBranch,\n title: input.title,\n body: input.body,\n draft: input.draft,\n },\n { actingUserId: input.actingUserId },\n );\n return parsePullRequest(result);\n }\n\n async #updatePullRequest(input: UpdatePullRequestInput) {\n const result = await this.#client.request<GithubPullRequest>(\n 'PATCH',\n pullRequestPath(input, input.pullRequestId),\n {\n title: input.title,\n body: input.body === null ? '' : input.body,\n base: input.baseBranch,\n state: input.state,\n },\n { actingUserId: input.actingUserId },\n );\n return parsePullRequest(result);\n }\n\n #mergePullRequest(input: MergePullRequestInput) {\n return this.#client.request<{ merged: boolean; message: string; sha: string | null }>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/merge`,\n { commitTitle: input.commitTitle, commitMessage: input.commitMessage, method: input.method },\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listComments(input: ListPullRequestCommentsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ comments: GithubComment[] }>(\n 'GET',\n `${repositoryPath(input.sourceId, `issues/${requirePositiveId(input.pullRequestId, 'pull request')}/comments`)}?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n comments: result.comments.map(parseComment),\n nextCursor: result.comments.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #createComment(input: CreatePullRequestCommentInput) {\n const comment = await this.#client.request<GithubComment>(\n 'POST',\n repositoryPath(input.sourceId, `issues/${requirePositiveId(input.pullRequestId, 'pull request')}/comments`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseComment(comment);\n }\n\n async #updateComment(input: UpdatePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n const comment = await this.#client.request<GithubComment>(\n 'PATCH',\n repositoryPath(input.sourceId, `issues/comments/${requirePositiveId(input.commentId, 'comment')}`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseComment(comment);\n }\n\n async #deleteComment(input: DeletePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n await this.#client.request<void>(\n 'DELETE',\n repositoryPath(input.sourceId, `issues/comments/${requirePositiveId(input.commentId, 'comment')}`),\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listReviews(input: ListReviewsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ reviews: GithubReview[] }>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/reviews?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n reviews: result.reviews.map(parseReview),\n nextCursor: result.reviews.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #getReview(input: ReviewRef) {\n try {\n return parseReview(\n await this.#client.request<GithubReview>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n ),\n );\n } catch (error) {\n if (isNotFound(error)) return null;\n throw error;\n }\n }\n\n async #createReview(input: CreateReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/reviews`,\n { body: input.body, commitId: input.commitId, event: input.event ? reviewEvent(input.event) : undefined },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #updateReview(input: UpdateReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n { body: input.body },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #submitReview(input: SubmitReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}/events`,\n { body: input.body, event: reviewEvent(input.event) },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #dismissReview(input: DismissReviewInput) {\n const review = await this.#client.request<GithubReview>(\n 'PUT',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}/dismissals`,\n { message: input.message },\n { actingUserId: input.actingUserId },\n );\n return parseReview(review);\n }\n\n async #deletePendingReview(input: ReviewRef) {\n await this.#client.request<void>(\n 'DELETE',\n `${pullRequestPath(input, input.pullRequestId)}/reviews/${requirePositiveId(input.reviewId, 'review')}`,\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n async #listReviewComments(input: ListReviewCommentsInput) {\n const page = parsePositiveCursor(input.cursor);\n const result = await this.#client.request<{ comments: GithubReviewComment[] }>(\n 'GET',\n `${pullRequestPath(input, input.pullRequestId)}/comments?page=${page}&per_page=${PAGE_SIZE}`,\n );\n return {\n comments: result.comments.map(parseReviewComment),\n nextCursor: result.comments.length === PAGE_SIZE ? String(page + 1) : null,\n };\n }\n\n async #createReviewComment(input: CreateReviewCommentInput) {\n let body: Record<string, unknown>;\n if (input.replyToId !== undefined) {\n body = { body: input.body, replyToId: requirePositiveId(input.replyToId, 'review comment') };\n } else {\n if (!input.commitId || !input.path || input.line === undefined || !input.side) {\n throw new Error('A review comment requires commitId, path, line, and side unless it is a reply.');\n }\n body = {\n body: input.body,\n commitId: input.commitId,\n path: input.path,\n line: input.line,\n side: input.side.toUpperCase(),\n startLine: input.startLine,\n startSide: input.startSide?.toUpperCase(),\n };\n }\n return parseReviewComment(\n await this.#client.request<GithubReviewComment>(\n 'POST',\n `${pullRequestPath(input, input.pullRequestId)}/comments`,\n body,\n { actingUserId: input.actingUserId },\n ),\n );\n }\n\n async #updateReviewComment(input: UpdatePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n return parseReviewComment(\n await this.#client.request<GithubReviewComment>(\n 'PATCH',\n repositoryPath(input.sourceId, `pulls/comments/${requirePositiveId(input.commentId, 'review comment')}`),\n { body: input.body },\n { actingUserId: input.actingUserId },\n ),\n );\n }\n\n async #deleteReviewComment(input: DeletePullRequestCommentInput) {\n requireGithubConnection(input.connection);\n await this.#client.request<void>(\n 'DELETE',\n repositoryPath(input.sourceId, `pulls/comments/${requirePositiveId(input.commentId, 'review comment')}`),\n undefined,\n { actingUserId: input.actingUserId },\n );\n }\n\n #requestedReviewers(method: 'GET' | 'POST' | 'DELETE', input: UpdateReviewersInput) {\n requireGithubConnection(input.connection);\n return this.#client.request<{ users: string[]; teams: string[] }>(\n method,\n `${pullRequestPath(input, input.pullRequestId)}/requested-reviewers`,\n method === 'GET' ? undefined : { users: input.users, teams: input.teams },\n method === 'GET' ? undefined : { actingUserId: input.actingUserId },\n );\n }\n}\n\nfunction repositoryPath(sourceId: string, suffix: string): string {\n const { owner, repo } = splitRepository(sourceId);\n return `${API_PREFIX}/github/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${suffix}`;\n}\n\nfunction pullRequestPath(\n input: { connection: IntegrationConnection; sourceId: string },\n pullRequestId: string,\n): string {\n requireGithubConnection(input.connection);\n return repositoryPath(input.sourceId, `pulls/${requirePositiveId(pullRequestId, 'pull request')}`);\n}\n\nfunction splitRepository(sourceId: string): { owner: string; repo: string } {\n const slash = sourceId.indexOf('/');\n if (slash <= 0 || slash === sourceId.length - 1) {\n throw new Error('GitHub capabilities require an owner/repository source.');\n }\n return { owner: sourceId.slice(0, slash), repo: sourceId.slice(slash + 1) };\n}\n\nfunction parseIntakeIssue(sourceId: string, issue: GithubIssue): IntakeIssue {\n return {\n id: String(issue.number),\n identifier: `#${issue.number}`,\n title: issue.title,\n url: issue.htmlUrl,\n author: issue.user?.login ?? null,\n state: issue.state,\n stateType: issue.state,\n priority: null,\n assignee: issue.assignees[0] ?? null,\n source: sourceId,\n labels: issue.labels,\n commentCount: issue.commentCount,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n };\n}\n\nfunction parseIntakeIssueDetail(sourceId: string, issue: GithubIssue, comments: GithubComment[]): IntakeIssueDetail {\n return {\n ...parseIntakeIssue(sourceId, issue),\n description: issue.body?.trim() ? issue.body : null,\n comments: comments.map(comment => ({\n author: comment.user?.login ?? null,\n body: comment.body,\n createdAt: comment.createdAt,\n })),\n };\n}\n\nfunction parsePullRequest(pullRequest: GithubPullRequest): PullRequest {\n return {\n id: String(pullRequest.number),\n title: pullRequest.title,\n url: pullRequest.htmlUrl,\n author: pullRequest.user?.login ?? null,\n body: pullRequest.body?.trim() ? pullRequest.body : null,\n state: pullRequest.state,\n draft: pullRequest.draft,\n merged: pullRequest.merged,\n mergeable: pullRequest.mergeable,\n baseBranch: pullRequest.base.ref,\n headBranch: pullRequest.head.ref,\n headSha: pullRequest.head.sha,\n createdAt: pullRequest.createdAt,\n updatedAt: pullRequest.updatedAt,\n };\n}\n\nfunction parseComment(comment: GithubComment): PullRequestComment {\n return {\n id: String(comment.id),\n url: comment.htmlUrl,\n author: comment.user?.login ?? null,\n body: comment.body,\n createdAt: comment.createdAt,\n updatedAt: comment.updatedAt,\n };\n}\n\nfunction parseReview(review: GithubReview): Review {\n const states: Record<GithubReview['state'], Review['state']> = {\n PENDING: 'pending',\n COMMENTED: 'commented',\n APPROVED: 'approved',\n CHANGES_REQUESTED: 'changes-requested',\n DISMISSED: 'dismissed',\n };\n return {\n id: String(review.id),\n url: review.htmlUrl,\n author: review.user?.login ?? null,\n body: review.body?.trim() ? review.body : null,\n state: states[review.state],\n commitId: review.commitId,\n submittedAt: review.submittedAt,\n };\n}\n\nfunction parseReviewComment(comment: GithubReviewComment): ReviewComment {\n return {\n ...parseComment(comment),\n path: comment.path,\n line: comment.line,\n side: comment.side?.toLowerCase() as 'left' | 'right' | null,\n commitId: comment.commitId,\n replyToId: comment.replyToId === null ? null : String(comment.replyToId),\n };\n}\n\nfunction requireGithubConnection(connection: IntegrationConnection): void {\n if (connection.type !== 'app-installation' && connection.type !== 'oauth') {\n throw new Error('GitHub capabilities require a GitHub connection.');\n }\n}\n\nfunction requireSingleSource(sourceIds: string[], message: string): string {\n if (sourceIds.length !== 1) throw new Error(message);\n return sourceIds[0]!;\n}\n\nfunction requireSource(sourceId: string | undefined, message: string): string {\n if (!sourceId) throw new Error(message);\n return sourceId;\n}\n\nfunction normalizeLabels(labels: string[] | undefined): string[] {\n return [...new Set((labels ?? []).map(label => label.trim()).filter(Boolean))];\n}\n\nfunction parsePositiveCursor(cursor: string | undefined): number {\n if (cursor === undefined) return 1;\n const parsed = parsePositiveInteger(cursor);\n if (parsed === null) throw new Error('GitHub cursor must be a positive page number.');\n return parsed;\n}\n\nfunction parsePositiveInteger(value: string): number | null {\n if (!/^\\d+$/.test(value)) return null;\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction parseGithubExternalTarget(externalId: string): { repository: string; issueId: string } | null {\n const match =\n externalId.match(/^(.+\\/.+):(\\d+)$/) ??\n externalId.match(/^github:(\\d+):(?:issue|pull-request):(\\d+)$/) ??\n externalId.match(/^(\\d+):(\\d+)$/);\n if (!match?.[1] || !match[2] || parsePositiveInteger(match[2]) === null) return null;\n return { repository: match[1], issueId: match[2] };\n}\n\nfunction optionalPositiveIntegerEnv(name: 'MASTRA_PLATFORM_GITHUB_POLLING_INTERVAL_MS'): number | undefined {\n const value = process.env[name]?.trim();\n if (!value) return undefined;\n const parsed = parsePositiveInteger(value);\n if (parsed === null) throw new Error(`${name} must be a positive integer.`);\n return parsed;\n}\n\nfunction requirePositiveId(value: string, resource: string): number {\n const parsed = parsePositiveInteger(value);\n if (parsed === null) throw new Error(`GitHub ${resource} id must be a positive integer.`);\n return parsed;\n}\n\nfunction reviewEvent(event: 'approve' | 'request-changes' | 'comment') {\n if (event === 'approve') return 'APPROVE' as const;\n if (event === 'request-changes') return 'REQUEST_CHANGES' as const;\n return 'COMMENT' as const;\n}\n\nfunction isNotFound(error: unknown): boolean {\n return error instanceof PlatformApiError && error.status === 404;\n}\n"],"mappings":"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"}
@@ -179,6 +179,16 @@ export interface SourceControlStorageHandle {
179
179
  orgId: string;
180
180
  input: UpsertSourceControlRepositoryInput;
181
181
  }): Promise<SourceControlRepository>;
182
+ /**
183
+ * Migrate a repository and its dependent connections to a new installation.
184
+ * Used when a GitHub App is reinstalled with a new installation ID on the same account.
185
+ * Returns the repository under the new installation (either migrated or existing).
186
+ */
187
+ migrateInstallation(args: {
188
+ orgId: string;
189
+ id: string;
190
+ newInstallationId: string;
191
+ }): Promise<SourceControlRepository>;
182
192
  };
183
193
  readonly connections: {
184
194
  list(args: {
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAwB,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAWhF,eAAO,MAAM,sBAAsB,EAAE,gBAAgB,EA4JpD,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpE,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,6BAA6B,CAAC;IAChD,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oCAAoC;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,6BAA6B,CAAC;IAChD,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;CAClD;AAED,MAAM,WAAW,8BAA8B;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,yCAAyC;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AAED,6EAA6E;AAC7E,MAAM,WAAW,+BAA+B;IAC9C,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gCAAgC;IAC/C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE;QACtB,IAAI,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;QACpF,gBAAgB,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;QACzG,MAAM,CAAC,IAAI,EAAE,oCAAoC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACvF,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/D,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE;QACrB,IAAI,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;QAC1F,GAAG,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;QAClF,gBAAgB,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;QACvG,UAAU,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;QACnH,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,kCAAkC,CAAA;SAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC7G;;;;WAIG;QACH,mBAAmB,CAAC,IAAI,EAAE;YACxB,KAAK,EAAE,MAAM,CAAC;YACd,EAAE,EAAE,MAAM,CAAC;YACX,iBAAiB,EAAE,MAAM,CAAC;SAC3B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACtC,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE;QACpB,IAAI,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,gBAAgB,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAAC;QACnG,GAAG,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,EAAE,yCAAyC,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACjG,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/D,CAAC;IACF,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,IAAI,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAClF,wBAAwB,CAAC,IAAI,EAAE;YAC7B,sBAAsB,EAAE,MAAM,CAAC;YAC/B,oBAAoB,EAAE,MAAM,CAAC;SAC9B,GAAG,OAAO,CAAC,+BAA+B,EAAE,CAAC,CAAC;QAC/C;;;;WAIG;QACH,0BAA0B,IAAI,OAAO,CAAC,+BAA+B,EAAE,CAAC,CAAC;QACzE,GAAG,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;QAC5E,IAAI,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,4BAA4B,CAAA;SAAE,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;QACpH,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/D,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QAClB,WAAW,CAAC,IAAI,EAAE;YAAE,iBAAiB,EAAE,iBAAiB,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC/G,OAAO,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;QACxE;;;;WAIG;QACH,UAAU,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACxE,YAAY,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACrE,YAAY,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,gBAAgB,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QAClB,MAAM,CAAC,IAAI,EAAE,gCAAgC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAC9F,GAAG,CAAC,IAAI,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;QAClH,UAAU,CAAC,IAAI,EAAE;YACf,mBAAmB,EAAE,MAAM,CAAC;YAC5B,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,MAAM,CAAC;SACtB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9F,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB,IAAI,CAAC,IAAI,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAC7F,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;QACxE,YAAY,CAAC,IAAI,EAAE;YACjB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;SAChB,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC9E,UAAU,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClG,gBAAgB,CAAC,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACnC,CAAC;CACH;AAgLD,qBAAa,oBAAqB,SAAQ,oBAAoB;;IAKtD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAU1C,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,0BAA0B;CA8gBlE"}
@@ -464,6 +464,38 @@ var SourceControlStorage = class extends FactoryStorageDomain {
464
464
  created_at: now,
465
465
  updated_at: now
466
466
  }));
467
+ },
468
+ migrateInstallation: async ({ orgId, id, newInstallationId }) => {
469
+ const existing = await getRepository({
470
+ orgId,
471
+ id
472
+ });
473
+ if (!existing) throw new Error(`Repository ${id} not found in organization ${orgId}`);
474
+ await requireInstallation({
475
+ orgId,
476
+ id: newInstallationId
477
+ });
478
+ try {
479
+ await db().updateMany(REPOSITORIES, { id }, {
480
+ installation_id: newInstallationId,
481
+ updated_at: /* @__PURE__ */ new Date()
482
+ });
483
+ await db().updateMany(CONNECTIONS, { installation_id: existing.installationId }, { installation_id: newInstallationId });
484
+ const updated = await getRepository({
485
+ orgId,
486
+ id
487
+ });
488
+ if (!updated) throw new Error("Repository disappeared after update");
489
+ return updated;
490
+ } catch (error) {
491
+ if (!(error instanceof UniqueViolationError)) throw error;
492
+ const conflictRow = await db().findOne(REPOSITORIES, {
493
+ installation_id: newInstallationId,
494
+ external_id: existing.externalId
495
+ });
496
+ if (!conflictRow) throw error;
497
+ return toRepository(conflictRow);
498
+ }
467
499
  }
468
500
  },
469
501
  connections: {
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/source-control/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nconst FACTORY_PROJECTS = 'factory_projects';\nconst INSTALLATIONS = 'source_control_installations';\nconst REPOSITORIES = 'source_control_repositories';\nconst CONNECTIONS = 'factory_project_source_control_connections';\nconst PROJECT_REPOSITORIES = 'factory_project_repositories';\nconst SANDBOXES = 'source_control_project_repository_sandboxes';\nconst WORKTREES = 'source_control_worktrees';\nconst SESSIONS = 'source_control_sessions';\n\nexport const SOURCE_CONTROL_SCHEMAS: CollectionSchema[] = [\n {\n name: INSTALLATIONS,\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n connected_by_user_id: { type: 'text' },\n external_id: { type: 'text' },\n account_name: { type: 'text', nullable: true },\n account_type: { type: 'text', nullable: true },\n provider_metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_installations_integration_org_external_unique',\n columns: ['integration_id', 'org_id', 'external_id'],\n },\n ],\n },\n {\n name: REPOSITORIES,\n columns: {\n id: { type: 'uuid-pk' },\n installation_id: { type: 'text' },\n external_id: { type: 'text' },\n slug: { type: 'text' },\n default_branch: { type: 'text', default: 'main' },\n provider_metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_repositories_installation_external_unique',\n columns: ['installation_id', 'external_id'],\n },\n ],\n indexes: [\n {\n name: 'source_control_repositories_installation_slug_idx',\n columns: ['installation_id', 'slug'],\n },\n ],\n },\n {\n name: CONNECTIONS,\n columns: {\n id: { type: 'uuid-pk' },\n factory_project_id: { type: 'text' },\n integration_id: { type: 'text' },\n installation_id: { type: 'text' },\n created_by_user_id: { type: 'text' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'factory_project_source_control_connections_project_integration_installation_unique',\n columns: ['factory_project_id', 'integration_id', 'installation_id'],\n },\n ],\n indexes: [\n {\n name: 'factory_project_source_control_connections_project_idx',\n columns: ['factory_project_id'],\n },\n ],\n },\n {\n name: PROJECT_REPOSITORIES,\n columns: {\n id: { type: 'uuid-pk' },\n connection_id: { type: 'text' },\n repository_id: { type: 'text' },\n created_by_user_id: { type: 'text' },\n branch: { type: 'text', nullable: true },\n sandbox_provider: { type: 'text' },\n sandbox_workdir: { type: 'text' },\n setup_command: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'factory_project_repositories_connection_repository_unique',\n columns: ['connection_id', 'repository_id'],\n },\n ],\n indexes: [\n {\n name: 'factory_project_repositories_connection_idx',\n columns: ['connection_id'],\n },\n ],\n },\n {\n name: SANDBOXES,\n columns: {\n id: { type: 'uuid-pk' },\n project_repository_id: { type: 'text' },\n user_id: { type: 'text' },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text' },\n materialized_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_project_repository_sandboxes_link_user_unique',\n columns: ['project_repository_id', 'user_id'],\n },\n ],\n },\n {\n name: WORKTREES,\n columns: {\n id: { type: 'uuid-pk' },\n project_repository_id: { type: 'text' },\n user_id: { type: 'text' },\n branch: { type: 'text' },\n base_branch: { type: 'text' },\n worktree_path: { type: 'text' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_worktrees_project_repository_user_branch_unique',\n columns: ['project_repository_id', 'user_id', 'branch'],\n },\n ],\n },\n {\n name: SESSIONS,\n columns: {\n id: { type: 'uuid-pk' },\n session_id: { type: 'text' },\n project_repository_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n branch: { type: 'text' },\n base_branch: { type: 'text' },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text', nullable: true },\n materialized_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'source_control_sessions_session_id_unique', columns: ['session_id'] },\n {\n name: 'source_control_sessions_repository_user_branch_unique',\n columns: ['project_repository_id', 'user_id', 'branch'],\n },\n ],\n },\n];\n\nexport type SourceControlProviderMetadata = Record<string, unknown>;\n\nexport interface SourceControlInstallation {\n id: string;\n integrationId: string;\n orgId: string;\n connectedByUserId: string;\n externalId: string;\n accountName: string | null;\n accountType: string | null;\n providerMetadata: SourceControlProviderMetadata;\n createdAt: Date;\n}\n\nexport interface UpsertSourceControlInstallationInput {\n orgId: string;\n connectedByUserId: string;\n externalId: string;\n accountName?: string | null;\n accountType?: string | null;\n providerMetadata?: SourceControlProviderMetadata;\n}\n\nexport interface SourceControlRepository {\n id: string;\n installationId: string;\n externalId: string;\n slug: string;\n defaultBranch: string;\n providerMetadata: SourceControlProviderMetadata;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertSourceControlRepositoryInput {\n installationId: string;\n externalId: string;\n slug: string;\n defaultBranch: string;\n providerMetadata?: SourceControlProviderMetadata;\n}\n\nexport interface ProjectSourceControlConnection {\n id: string;\n factoryProjectId: string;\n integrationId: string;\n installationId: string;\n createdByUserId: string;\n createdAt: Date;\n}\n\nexport interface CreateProjectSourceControlConnectionInput {\n orgId: string;\n factoryProjectId: string;\n installationId: string;\n createdByUserId: string;\n}\n\nexport interface ProjectRepository {\n id: string;\n connectionId: string;\n repositoryId: string;\n createdByUserId: string;\n branch: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface ExternalRepositoryProjectTarget {\n orgId: string;\n factoryProjectId: string;\n projectRepository: ProjectRepository;\n}\n\n/** External id pair identifying a repository linked to a factory project. */\nexport interface ConfiguredExternalRepositoryKey {\n installationExternalId: string;\n repositoryExternalId: string;\n}\n\nexport interface LinkProjectRepositoryInput {\n orgId: string;\n connectionId: string;\n repositoryId: string;\n createdByUserId: string;\n branch?: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand?: string | null;\n}\n\nexport interface UpdateProjectRepositoryInput {\n branch?: string | null;\n sandboxProvider?: string;\n sandboxWorkdir?: string;\n setupCommand?: string | null;\n}\n\nexport interface ProjectRepositorySandbox {\n id: string;\n projectRepositoryId: string;\n userId: string;\n sandboxId: string | null;\n sandboxWorkdir: string;\n materializedAt: Date | null;\n createdAt: Date;\n}\n\nexport interface SourceControlWorktree {\n id: string;\n projectRepositoryId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n worktreePath: string;\n createdAt: Date;\n}\n\nexport interface UpsertSourceControlWorktreeInput {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n worktreePath: string;\n}\n\nexport interface SourceControlSession {\n id: string;\n sessionId: string;\n projectRepositoryId: string;\n orgId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n sandboxId: string | null;\n sandboxWorkdir: string | null;\n materializedAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateSourceControlSessionInput {\n sessionId: string;\n projectRepositoryId: string;\n orgId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n}\n\nexport interface SourceControlStorageHandle {\n readonly integrationId: string;\n readonly installations: {\n list(args: { orgId: string }): Promise<SourceControlInstallation[]>;\n get(args: { orgId: string; id: string }): Promise<SourceControlInstallation | null>;\n findByExternalId(args: { orgId: string; externalId: string }): Promise<SourceControlInstallation | null>;\n upsert(args: UpsertSourceControlInstallationInput): Promise<SourceControlInstallation>;\n delete(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly repositories: {\n list(args: { orgId: string; installationId: string }): Promise<SourceControlRepository[]>;\n get(args: { orgId: string; id: string }): Promise<SourceControlRepository | null>;\n findByExternalId(args: { orgId: string; externalId: string }): Promise<SourceControlRepository | null>;\n findBySlug(args: { orgId: string; installationId: string; slug: string }): Promise<SourceControlRepository | null>;\n upsert(args: { orgId: string; input: UpsertSourceControlRepositoryInput }): Promise<SourceControlRepository>;\n };\n readonly connections: {\n list(args: { orgId: string; factoryProjectId: string }): Promise<ProjectSourceControlConnection[]>;\n get(args: { orgId: string; id: string }): Promise<ProjectSourceControlConnection | null>;\n create(args: CreateProjectSourceControlConnectionInput): Promise<ProjectSourceControlConnection>;\n delete(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly projectRepositories: {\n list(args: { orgId: string; connectionId: string }): Promise<ProjectRepository[]>;\n listByExternalRepository(args: {\n installationExternalId: string;\n repositoryExternalId: string;\n }): Promise<ExternalRepositoryProjectTarget[]>;\n /**\n * Distinct external (installation, repository) id pairs linked to any\n * factory project. Lets sweeps scope work to configured repositories\n * without probing every repository an installation can see.\n */\n listConfiguredExternalKeys(): Promise<ConfiguredExternalRepositoryKey[]>;\n get(args: { orgId: string; id: string }): Promise<ProjectRepository | null>;\n link(args: LinkProjectRepositoryInput): Promise<ProjectRepository>;\n update(args: { orgId: string; id: string; input: UpdateProjectRepositoryInput }): Promise<ProjectRepository | null>;\n unlink(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly sandboxes: {\n getOrCreate(args: { projectRepository: ProjectRepository; userId: string }): Promise<ProjectRepositorySandbox>;\n getById(args: { id: string }): Promise<ProjectRepositorySandbox | null>;\n /**\n * Point the binding at a new workdir and clear `materializedAt` — a moved\n * workdir means the checkout must be re-cloned. Used to heal bindings whose\n * inherited workdir went stale (e.g. the sandbox provider changed).\n */\n setWorkdir(args: { id: string; sandboxWorkdir: string }): Promise<void>;\n setSandboxId(args: { id: string; sandboxId: string }): Promise<void>;\n clearBinding(args: { id: string }): Promise<void>;\n markMaterialized(args: { id: string }): Promise<void>;\n };\n readonly worktrees: {\n upsert(args: UpsertSourceControlWorktreeInput): Promise<void>;\n list(args: { projectRepositoryId: string; userId: string }): Promise<SourceControlWorktree[]>;\n get(args: { projectRepositoryId: string; userId: string; branch: string }): Promise<SourceControlWorktree | null>;\n findByPath(args: {\n projectRepositoryId: string;\n userId: string;\n worktreePath: string;\n }): Promise<SourceControlWorktree | null>;\n delete(args: { projectRepositoryId: string; userId: string; branch: string }): Promise<void>;\n };\n readonly sessions: {\n list(args: { projectRepositoryId: string; userId: string }): Promise<SourceControlSession[]>;\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n getForBranch(args: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlSession | null>;\n create(input: CreateSourceControlSessionInput): Promise<SourceControlSession>;\n setSandbox(args: { id: string; sandboxId: string | null; sandboxWorkdir: string }): Promise<void>;\n markMaterialized(args: { id: string }): Promise<void>;\n delete(id: string): Promise<void>;\n };\n}\n\ninterface InstallationDbRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n connected_by_user_id: string;\n external_id: string;\n account_name: string | null;\n account_type: string | null;\n provider_metadata: SourceControlProviderMetadata;\n created_at: Date;\n}\n\ninterface RepositoryDbRow extends Record<string, unknown> {\n id: string;\n installation_id: string;\n external_id: string;\n slug: string;\n default_branch: string;\n provider_metadata: SourceControlProviderMetadata;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface ConnectionDbRow extends Record<string, unknown> {\n id: string;\n factory_project_id: string;\n integration_id: string;\n installation_id: string;\n created_by_user_id: string;\n created_at: Date;\n}\n\ninterface ProjectRepositoryDbRow extends Record<string, unknown> {\n id: string;\n connection_id: string;\n repository_id: string;\n created_by_user_id: string;\n branch: string | null;\n sandbox_provider: string;\n sandbox_workdir: string;\n setup_command: string | null;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SandboxDbRow extends Record<string, unknown> {\n id: string;\n project_repository_id: string;\n user_id: string;\n sandbox_id: string | null;\n sandbox_workdir: string;\n materialized_at: Date | null;\n created_at: Date;\n}\n\ninterface WorktreeDbRow extends Record<string, unknown> {\n id: string;\n project_repository_id: string;\n user_id: string;\n branch: string;\n base_branch: string;\n worktree_path: string;\n created_at: Date;\n}\n\ninterface SessionDbRow extends Record<string, unknown> {\n id: string;\n session_id: string;\n project_repository_id: string;\n org_id: string;\n user_id: string;\n branch: string;\n base_branch: string;\n sandbox_id: string | null;\n sandbox_workdir: string | null;\n materialized_at: Date | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toInstallation(row: InstallationDbRow): SourceControlInstallation {\n return {\n id: row.id,\n integrationId: row.integration_id,\n orgId: row.org_id,\n connectedByUserId: row.connected_by_user_id,\n externalId: row.external_id,\n accountName: row.account_name,\n accountType: row.account_type,\n providerMetadata: row.provider_metadata,\n createdAt: row.created_at,\n };\n}\n\nfunction toRepository(row: RepositoryDbRow): SourceControlRepository {\n return {\n id: row.id,\n installationId: row.installation_id,\n externalId: row.external_id,\n slug: row.slug,\n defaultBranch: row.default_branch,\n providerMetadata: row.provider_metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction toConnection(row: ConnectionDbRow): ProjectSourceControlConnection {\n return {\n id: row.id,\n factoryProjectId: row.factory_project_id,\n integrationId: row.integration_id,\n installationId: row.installation_id,\n createdByUserId: row.created_by_user_id,\n createdAt: row.created_at,\n };\n}\n\nfunction toProjectRepository(row: ProjectRepositoryDbRow): ProjectRepository {\n return {\n id: row.id,\n connectionId: row.connection_id,\n repositoryId: row.repository_id,\n createdByUserId: row.created_by_user_id,\n branch: row.branch,\n sandboxProvider: row.sandbox_provider,\n sandboxWorkdir: row.sandbox_workdir,\n setupCommand: row.setup_command,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction toSandbox(row: SandboxDbRow): ProjectRepositorySandbox {\n return {\n id: row.id,\n projectRepositoryId: row.project_repository_id,\n userId: row.user_id,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n createdAt: row.created_at,\n };\n}\n\nfunction toWorktree(row: WorktreeDbRow): SourceControlWorktree {\n return {\n id: row.id,\n projectRepositoryId: row.project_repository_id,\n userId: row.user_id,\n branch: row.branch,\n baseBranch: row.base_branch,\n worktreePath: row.worktree_path,\n createdAt: row.created_at,\n };\n}\n\nfunction toSession(row: SessionDbRow): SourceControlSession {\n return {\n id: row.id,\n sessionId: row.session_id,\n projectRepositoryId: row.project_repository_id,\n orgId: row.org_id,\n userId: row.user_id,\n branch: row.branch,\n baseBranch: row.base_branch,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class SourceControlStorage extends FactoryStorageDomain {\n constructor() {\n super('source-control');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections(SOURCE_CONTROL_SCHEMAS);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany(SESSIONS, {});\n await this.ops.deleteMany(WORKTREES, {});\n await this.ops.deleteMany(SANDBOXES, {});\n await this.ops.deleteMany(PROJECT_REPOSITORIES, {});\n await this.ops.deleteMany(CONNECTIONS, {});\n await this.ops.deleteMany(REPOSITORIES, {});\n await this.ops.deleteMany(INSTALLATIONS, {});\n }\n\n forIntegration(integrationId: string): SourceControlStorageHandle {\n if (!integrationId.trim()) throw new Error('[SourceControlStorage] integrationId must not be empty.');\n const db = (): FactoryStorageOps => this.ops;\n\n const getInstallation = async (args: { orgId: string; id: string }): Promise<SourceControlInstallation | null> => {\n const row = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n id: args.id,\n integration_id: integrationId,\n org_id: args.orgId,\n });\n return row ? toInstallation(row) : null;\n };\n\n const requireInstallation = async (args: { orgId: string; id: string }): Promise<SourceControlInstallation> => {\n const installation = await getInstallation(args);\n if (!installation)\n throw new Error('Source-control installation not found for this organization and integration.');\n return installation;\n };\n\n const getRepository = async (args: { orgId: string; id: string }): Promise<SourceControlRepository | null> => {\n const row = await db().findOne<RepositoryDbRow>(REPOSITORIES, { id: args.id });\n if (!row || !(await getInstallation({ orgId: args.orgId, id: row.installation_id }))) return null;\n return toRepository(row);\n };\n\n const requireRepository = async (args: { orgId: string; id: string }): Promise<SourceControlRepository> => {\n const repository = await getRepository(args);\n if (!repository) throw new Error('Source-control repository not found for this organization and integration.');\n return repository;\n };\n\n const getConnection = async (args: {\n orgId: string;\n id: string;\n }): Promise<ProjectSourceControlConnection | null> => {\n const row = await db().findOne<ConnectionDbRow>(CONNECTIONS, { id: args.id, integration_id: integrationId });\n if (!row) return null;\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: row.factory_project_id,\n org_id: args.orgId,\n });\n if (!project || !(await getInstallation({ orgId: args.orgId, id: row.installation_id }))) return null;\n return toConnection(row);\n };\n\n const requireConnection = async (args: { orgId: string; id: string }): Promise<ProjectSourceControlConnection> => {\n const connection = await getConnection(args);\n if (!connection)\n throw new Error('Project source-control connection not found for this organization and integration.');\n return connection;\n };\n\n const getProjectRepository = async (args: { orgId: string; id: string }): Promise<ProjectRepository | null> => {\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { id: args.id });\n if (!row || !(await getConnection({ orgId: args.orgId, id: row.connection_id }))) return null;\n return toProjectRepository(row);\n };\n\n const getProjectRepositoryById = async (id: string): Promise<ProjectRepository | null> => {\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { id });\n if (!row) return null;\n const connection = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n id: row.connection_id,\n integration_id: integrationId,\n });\n return connection ? toProjectRepository(row) : null;\n };\n\n const requireProjectRepositoryById = async (id: string): Promise<ProjectRepository> => {\n const projectRepository = await getProjectRepositoryById(id);\n if (!projectRepository) throw new Error('Project repository not found for this integration.');\n return projectRepository;\n };\n\n const getSandbox = async (id: string): Promise<ProjectRepositorySandbox | null> => {\n const row = await db().findOne<SandboxDbRow>(SANDBOXES, { id });\n if (!row || !(await getProjectRepositoryById(row.project_repository_id))) return null;\n return toSandbox(row);\n };\n\n const requireSandbox = async (id: string): Promise<ProjectRepositorySandbox> => {\n const sandbox = await getSandbox(id);\n if (!sandbox) throw new Error('Project-repository sandbox not found for this integration.');\n return sandbox;\n };\n\n return {\n integrationId,\n installations: {\n list: async ({ orgId }) =>\n (\n await db().findMany<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n org_id: orgId,\n })\n ).map(toInstallation),\n get: getInstallation,\n findByExternalId: async ({ orgId, externalId }) => {\n const row = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n org_id: orgId,\n external_id: externalId,\n });\n return row ? toInstallation(row) : null;\n },\n upsert: async input => {\n const row = await db().upsertOne<InstallationDbRow>(\n INSTALLATIONS,\n ['integration_id', 'org_id', 'external_id'],\n {\n integration_id: integrationId,\n org_id: input.orgId,\n connected_by_user_id: input.connectedByUserId,\n external_id: input.externalId,\n account_name: input.accountName ?? null,\n account_type: input.accountType ?? null,\n provider_metadata: input.providerMetadata ?? {},\n created_at: new Date(),\n },\n );\n return toInstallation(row);\n },\n delete: async ({ orgId, id }) => {\n const installation = await getInstallation({ orgId, id });\n if (!installation) return false;\n await db().deleteMany(INSTALLATIONS, { id, integration_id: integrationId, org_id: orgId });\n return true;\n },\n },\n repositories: {\n list: async ({ orgId, installationId }) => {\n await requireInstallation({ orgId, id: installationId });\n return (await db().findMany<RepositoryDbRow>(REPOSITORIES, { installation_id: installationId })).map(\n toRepository,\n );\n },\n get: getRepository,\n findByExternalId: async ({ orgId, externalId }) => {\n const rows = await db().findMany<RepositoryDbRow>(REPOSITORIES, { external_id: externalId });\n for (const row of rows) {\n if (await getInstallation({ orgId, id: row.installation_id })) return toRepository(row);\n }\n return null;\n },\n findBySlug: async ({ orgId, installationId, slug }) => {\n await requireInstallation({ orgId, id: installationId });\n const row = await db().findOne<RepositoryDbRow>(REPOSITORIES, { installation_id: installationId, slug });\n return row ? toRepository(row) : null;\n },\n upsert: async ({ orgId, input }) => {\n await requireInstallation({ orgId, id: input.installationId });\n const now = new Date();\n const row = await db().upsertOne<RepositoryDbRow>(REPOSITORIES, ['installation_id', 'external_id'], {\n installation_id: input.installationId,\n external_id: input.externalId,\n slug: input.slug,\n default_branch: input.defaultBranch,\n provider_metadata: input.providerMetadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return toRepository(row);\n },\n },\n connections: {\n list: async ({ orgId, factoryProjectId }) => {\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: factoryProjectId,\n org_id: orgId,\n });\n if (!project) return [];\n return (\n await db().findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n })\n ).map(toConnection);\n },\n get: getConnection,\n create: async input => {\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: input.factoryProjectId,\n org_id: input.orgId,\n });\n if (!project) throw new Error('Factory project not found for this organization.');\n await requireInstallation({ orgId: input.orgId, id: input.installationId });\n try {\n const row = await db().insertOne<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: input.factoryProjectId,\n integration_id: integrationId,\n installation_id: input.installationId,\n created_by_user_id: input.createdByUserId,\n created_at: new Date(),\n });\n return toConnection(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: input.factoryProjectId,\n integration_id: integrationId,\n installation_id: input.installationId,\n });\n if (!row) throw error;\n return toConnection(row);\n }\n },\n delete: async ({ orgId, id }) => {\n const connection = await getConnection({ orgId, id });\n if (!connection) return false;\n const projectRepositories = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: id,\n });\n for (const projectRepository of projectRepositories) {\n await db().deleteMany(SESSIONS, { project_repository_id: projectRepository.id });\n await db().deleteMany(WORKTREES, { project_repository_id: projectRepository.id });\n await db().deleteMany(SANDBOXES, { project_repository_id: projectRepository.id });\n }\n await db().deleteMany(PROJECT_REPOSITORIES, { connection_id: id });\n await db().deleteMany(CONNECTIONS, { id, integration_id: integrationId });\n return true;\n },\n },\n projectRepositories: {\n list: async ({ orgId, connectionId }) => {\n await requireConnection({ orgId, id: connectionId });\n return (\n await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { connection_id: connectionId })\n ).map(toProjectRepository);\n },\n listConfiguredExternalKeys: async () => {\n const keys = new Map<string, ConfiguredExternalRepositoryKey>();\n const connections = await db().findMany<ConnectionDbRow>(CONNECTIONS, { integration_id: integrationId });\n for (const connection of connections) {\n const installation = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n id: connection.installation_id,\n integration_id: integrationId,\n });\n if (!installation) continue;\n const links = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: connection.id,\n });\n for (const link of links) {\n const repository = await db().findOne<RepositoryDbRow>(REPOSITORIES, { id: link.repository_id });\n if (!repository) continue;\n keys.set(`${installation.external_id}\\u0000${repository.external_id}`, {\n installationExternalId: installation.external_id,\n repositoryExternalId: repository.external_id,\n });\n }\n }\n return [...keys.values()];\n },\n listByExternalRepository: async ({ installationExternalId, repositoryExternalId }) => {\n const targets: ExternalRepositoryProjectTarget[] = [];\n const installations = await db().findMany<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n external_id: installationExternalId,\n });\n for (const installation of installations) {\n const repository = await db().findOne<RepositoryDbRow>(REPOSITORIES, {\n installation_id: installation.id,\n external_id: repositoryExternalId,\n });\n if (!repository) continue;\n const links = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n repository_id: repository.id,\n });\n for (const link of links) {\n const connection = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n id: link.connection_id,\n integration_id: integrationId,\n installation_id: installation.id,\n });\n if (!connection) continue;\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: connection.factory_project_id,\n org_id: installation.org_id,\n });\n if (!project) continue;\n targets.push({\n orgId: installation.org_id,\n factoryProjectId: connection.factory_project_id,\n projectRepository: toProjectRepository(link),\n });\n }\n }\n return targets;\n },\n get: getProjectRepository,\n link: async input => {\n const connection = await requireConnection({ orgId: input.orgId, id: input.connectionId });\n const repository = await requireRepository({ orgId: input.orgId, id: input.repositoryId });\n if (repository.installationId !== connection.installationId) {\n throw new Error('Repository does not belong to the connection installation.');\n }\n const now = new Date();\n const row = await db().upsertOne<ProjectRepositoryDbRow>(\n PROJECT_REPOSITORIES,\n ['connection_id', 'repository_id'],\n {\n connection_id: input.connectionId,\n repository_id: input.repositoryId,\n created_by_user_id: input.createdByUserId,\n branch: input.branch ?? null,\n sandbox_provider: input.sandboxProvider,\n sandbox_workdir: input.sandboxWorkdir,\n setup_command: input.setupCommand ?? null,\n created_at: now,\n updated_at: now,\n },\n );\n return toProjectRepository(row);\n },\n update: async ({ orgId, id, input }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return null;\n const patch: Record<string, unknown> = { updated_at: new Date() };\n if (input.branch !== undefined) patch.branch = input.branch;\n if (input.sandboxProvider !== undefined) patch.sandbox_provider = input.sandboxProvider;\n if (input.sandboxWorkdir !== undefined) patch.sandbox_workdir = input.sandboxWorkdir;\n if (input.setupCommand !== undefined) patch.setup_command = input.setupCommand;\n await db().updateMany(PROJECT_REPOSITORIES, { id }, patch);\n return getProjectRepository({ orgId, id });\n },\n unlink: async ({ orgId, id }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return false;\n await db().deleteMany(SESSIONS, { project_repository_id: id });\n await db().deleteMany(WORKTREES, { project_repository_id: id });\n await db().deleteMany(SANDBOXES, { project_repository_id: id });\n await db().deleteMany(PROJECT_REPOSITORIES, { id });\n return true;\n },\n },\n sandboxes: {\n getOrCreate: async ({ projectRepository, userId }) => {\n await requireProjectRepositoryById(projectRepository.id);\n const where = { project_repository_id: projectRepository.id, user_id: userId };\n const existing = await db().findOne<SandboxDbRow>(SANDBOXES, where);\n if (existing) return toSandbox(existing);\n try {\n const row = await db().insertOne<SandboxDbRow>(SANDBOXES, {\n ...where,\n sandbox_id: null,\n sandbox_workdir: projectRepository.sandboxWorkdir,\n materialized_at: null,\n created_at: new Date(),\n });\n return toSandbox(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<SandboxDbRow>(SANDBOXES, where);\n if (!row) throw error;\n return toSandbox(row);\n }\n },\n getById: ({ id }) => getSandbox(id),\n setWorkdir: async ({ id, sandboxWorkdir }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_workdir: sandboxWorkdir, materialized_at: null });\n },\n setSandboxId: async ({ id, sandboxId }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_id: sandboxId });\n },\n clearBinding: async ({ id }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_id: null, materialized_at: null });\n },\n markMaterialized: async ({ id }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { materialized_at: new Date() });\n },\n },\n worktrees: {\n upsert: async input => {\n await requireProjectRepositoryById(input.projectRepositoryId);\n await db().upsertOne<WorktreeDbRow>(WORKTREES, ['project_repository_id', 'user_id', 'branch'], {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n base_branch: input.baseBranch,\n worktree_path: input.worktreePath,\n created_at: new Date(),\n });\n },\n list: async ({ projectRepositoryId, userId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n const rows = await db().findMany<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n });\n return rows.map(toWorktree);\n },\n get: async ({ projectRepositoryId, userId, branch }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n return row ? toWorktree(row) : null;\n },\n findByPath: async ({ projectRepositoryId, userId, worktreePath }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n worktree_path: worktreePath,\n });\n return row ? toWorktree(row) : null;\n },\n delete: async ({ projectRepositoryId, userId, branch }) => {\n await requireProjectRepositoryById(projectRepositoryId);\n await db().deleteMany(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n },\n },\n sessions: {\n list: async ({ projectRepositoryId, userId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n return (\n await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n })\n ).map(toSession);\n },\n getBySessionId: async sessionId => {\n const row = await db().findOne<SessionDbRow>(SESSIONS, { session_id: sessionId });\n return row && (await getProjectRepositoryById(row.project_repository_id)) ? toSession(row) : null;\n },\n getForBranch: async ({ projectRepositoryId, userId, branch }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n return row ? toSession(row) : null;\n },\n create: async input => {\n await requireProjectRepositoryById(input.projectRepositoryId);\n const existing = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n });\n if (existing) return toSession(existing);\n const now = new Date();\n try {\n const row = await db().insertOne<SessionDbRow>(SESSIONS, {\n session_id: input.sessionId,\n project_repository_id: input.projectRepositoryId,\n org_id: input.orgId,\n user_id: input.userId,\n branch: input.branch,\n base_branch: input.baseBranch,\n sandbox_id: null,\n sandbox_workdir: null,\n materialized_at: null,\n created_at: now,\n updated_at: now,\n });\n return toSession(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n });\n if (!row) throw error;\n return toSession(row);\n }\n },\n setSandbox: async ({ id, sandboxId, sandboxWorkdir }) => {\n await db().updateMany(\n SESSIONS,\n { id },\n { sandbox_id: sandboxId, sandbox_workdir: sandboxWorkdir, updated_at: new Date() },\n );\n },\n markMaterialized: async ({ id }) => {\n await db().updateMany(SESSIONS, { id }, { materialized_at: new Date(), updated_at: new Date() });\n },\n delete: async id => {\n await db().deleteMany(SESSIONS, { id });\n },\n },\n };\n }\n}\n"],"mappings":";;AAGA,MAAM,mBAAmB;AACzB,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,uBAAuB;AAC7B,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,WAAW;AAEjB,MAAa,yBAA6C;CACxD;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,gBAAgB,EAAE,MAAM,OAAO;GAC/B,QAAQ,EAAE,MAAM,OAAO;GACvB,sBAAsB,EAAE,MAAM,OAAO;GACrC,aAAa,EAAE,MAAM,OAAO;GAC5B,cAAc;IAAE,MAAM;IAAQ,UAAU;GAAK;GAC7C,cAAc;IAAE,MAAM;IAAQ,UAAU;GAAK;GAC7C,mBAAmB,EAAE,MAAM,OAAO;GAClC,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS;IAAC;IAAkB;IAAU;GAAa;EACrD,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,iBAAiB,EAAE,MAAM,OAAO;GAChC,aAAa,EAAE,MAAM,OAAO;GAC5B,MAAM,EAAE,MAAM,OAAO;GACrB,gBAAgB;IAAE,MAAM;IAAQ,SAAS;GAAO;GAChD,mBAAmB,EAAE,MAAM,OAAO;GAClC,YAAY,EAAE,MAAM,YAAY;GAChC,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS,CAAC,mBAAmB,aAAa;EAC5C,CACF;EACA,SAAS,CACP;GACE,MAAM;GACN,SAAS,CAAC,mBAAmB,MAAM;EACrC,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,oBAAoB,EAAE,MAAM,OAAO;GACnC,gBAAgB,EAAE,MAAM,OAAO;GAC/B,iBAAiB,EAAE,MAAM,OAAO;GAChC,oBAAoB,EAAE,MAAM,OAAO;GACnC,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS;IAAC;IAAsB;IAAkB;GAAiB;EACrE,CACF;EACA,SAAS,CACP;GACE,MAAM;GACN,SAAS,CAAC,oBAAoB;EAChC,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,eAAe,EAAE,MAAM,OAAO;GAC9B,eAAe,EAAE,MAAM,OAAO;GAC9B,oBAAoB,EAAE,MAAM,OAAO;GACnC,QAAQ;IAAE,MAAM;IAAQ,UAAU;GAAK;GACvC,kBAAkB,EAAE,MAAM,OAAO;GACjC,iBAAiB,EAAE,MAAM,OAAO;GAChC,eAAe;IAAE,MAAM;IAAQ,UAAU;GAAK;GAC9C,YAAY,EAAE,MAAM,YAAY;GAChC,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS,CAAC,iBAAiB,eAAe;EAC5C,CACF;EACA,SAAS,CACP;GACE,MAAM;GACN,SAAS,CAAC,eAAe;EAC3B,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,uBAAuB,EAAE,MAAM,OAAO;GACtC,SAAS,EAAE,MAAM,OAAO;GACxB,YAAY;IAAE,MAAM;IAAQ,UAAU;GAAK;GAC3C,iBAAiB,EAAE,MAAM,OAAO;GAChC,iBAAiB;IAAE,MAAM;IAAa,UAAU;GAAK;GACrD,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS,CAAC,yBAAyB,SAAS;EAC9C,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,uBAAuB,EAAE,MAAM,OAAO;GACtC,SAAS,EAAE,MAAM,OAAO;GACxB,QAAQ,EAAE,MAAM,OAAO;GACvB,aAAa,EAAE,MAAM,OAAO;GAC5B,eAAe,EAAE,MAAM,OAAO;GAC9B,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GACE,MAAM;GACN,SAAS;IAAC;IAAyB;IAAW;GAAQ;EACxD,CACF;CACF;CACA;EACE,MAAM;EACN,SAAS;GACP,IAAI,EAAE,MAAM,UAAU;GACtB,YAAY,EAAE,MAAM,OAAO;GAC3B,uBAAuB,EAAE,MAAM,OAAO;GACtC,QAAQ,EAAE,MAAM,OAAO;GACvB,SAAS,EAAE,MAAM,OAAO;GACxB,QAAQ,EAAE,MAAM,OAAO;GACvB,aAAa,EAAE,MAAM,OAAO;GAC5B,YAAY;IAAE,MAAM;IAAQ,UAAU;GAAK;GAC3C,iBAAiB;IAAE,MAAM;IAAQ,UAAU;GAAK;GAChD,iBAAiB;IAAE,MAAM;IAAa,UAAU;GAAK;GACrD,YAAY,EAAE,MAAM,YAAY;GAChC,YAAY,EAAE,MAAM,YAAY;EAClC;EACA,eAAe,CACb;GAAE,MAAM;GAA6C,SAAS,CAAC,YAAY;EAAE,GAC7E;GACE,MAAM;GACN,SAAS;IAAC;IAAyB;IAAW;GAAQ;EACxD,CACF;CACF;AACF;AAyTA,SAAS,eAAe,KAAmD;CACzE,OAAO;EACL,IAAI,IAAI;EACR,eAAe,IAAI;EACnB,OAAO,IAAI;EACX,mBAAmB,IAAI;EACvB,YAAY,IAAI;EAChB,aAAa,IAAI;EACjB,aAAa,IAAI;EACjB,kBAAkB,IAAI;EACtB,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,aAAa,KAA+C;CACnE,OAAO;EACL,IAAI,IAAI;EACR,gBAAgB,IAAI;EACpB,YAAY,IAAI;EAChB,MAAM,IAAI;EACV,eAAe,IAAI;EACnB,kBAAkB,IAAI;EACtB,WAAW,IAAI;EACf,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,aAAa,KAAsD;CAC1E,OAAO;EACL,IAAI,IAAI;EACR,kBAAkB,IAAI;EACtB,eAAe,IAAI;EACnB,gBAAgB,IAAI;EACpB,iBAAiB,IAAI;EACrB,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,oBAAoB,KAAgD;CAC3E,OAAO;EACL,IAAI,IAAI;EACR,cAAc,IAAI;EAClB,cAAc,IAAI;EAClB,iBAAiB,IAAI;EACrB,QAAQ,IAAI;EACZ,iBAAiB,IAAI;EACrB,gBAAgB,IAAI;EACpB,cAAc,IAAI;EAClB,WAAW,IAAI;EACf,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,UAAU,KAA6C;CAC9D,OAAO;EACL,IAAI,IAAI;EACR,qBAAqB,IAAI;EACzB,QAAQ,IAAI;EACZ,WAAW,IAAI;EACf,gBAAgB,IAAI;EACpB,gBAAgB,IAAI;EACpB,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,WAAW,KAA2C;CAC7D,OAAO;EACL,IAAI,IAAI;EACR,qBAAqB,IAAI;EACzB,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,YAAY,IAAI;EAChB,cAAc,IAAI;EAClB,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,UAAU,KAAyC;CAC1D,OAAO;EACL,IAAI,IAAI;EACR,WAAW,IAAI;EACf,qBAAqB,IAAI;EACzB,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,YAAY,IAAI;EAChB,WAAW,IAAI;EACf,gBAAgB,IAAI;EACpB,gBAAgB,IAAI;EACpB,WAAW,IAAI;EACf,WAAW,IAAI;CACjB;AACF;AAEA,IAAa,uBAAb,cAA0C,qBAAqB;CAC7D,cAAc;EACZ,MAAM,gBAAgB;CACxB;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,sBAAsB;CACrD;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC,CAAC;EACtC,MAAM,KAAK,IAAI,WAAW,WAAW,CAAC,CAAC;EACvC,MAAM,KAAK,IAAI,WAAW,WAAW,CAAC,CAAC;EACvC,MAAM,KAAK,IAAI,WAAW,sBAAsB,CAAC,CAAC;EAClD,MAAM,KAAK,IAAI,WAAW,aAAa,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,WAAW,cAAc,CAAC,CAAC;EAC1C,MAAM,KAAK,IAAI,WAAW,eAAe,CAAC,CAAC;CAC7C;CAEA,eAAe,eAAmD;EAChE,IAAI,CAAC,cAAc,KAAK,GAAG,MAAM,IAAI,MAAM,yDAAyD;EACpG,MAAM,WAA8B,KAAK;EAEzC,MAAM,kBAAkB,OAAO,SAAmF;GAChH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAA2B,eAAe;IAC/D,IAAI,KAAK;IACT,gBAAgB;IAChB,QAAQ,KAAK;GACf,CAAC;GACD,OAAO,MAAM,eAAe,GAAG,IAAI;EACrC;EAEA,MAAM,sBAAsB,OAAO,SAA4E;GAC7G,MAAM,eAAe,MAAM,gBAAgB,IAAI;GAC/C,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,8EAA8E;GAChG,OAAO;EACT;EAEA,MAAM,gBAAgB,OAAO,SAAiF;GAC5G,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAyB,cAAc,EAAE,IAAI,KAAK,GAAG,CAAC;GAC7E,IAAI,CAAC,OAAO,CAAE,MAAM,gBAAgB;IAAE,OAAO,KAAK;IAAO,IAAI,IAAI;GAAgB,CAAC,GAAI,OAAO;GAC7F,OAAO,aAAa,GAAG;EACzB;EAEA,MAAM,oBAAoB,OAAO,SAA0E;GACzG,MAAM,aAAa,MAAM,cAAc,IAAI;GAC3C,IAAI,CAAC,YAAY,MAAM,IAAI,MAAM,4EAA4E;GAC7G,OAAO;EACT;EAEA,MAAM,gBAAgB,OAAO,SAGyB;GACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAyB,aAAa;IAAE,IAAI,KAAK;IAAI,gBAAgB;GAAc,CAAC;GAC3G,IAAI,CAAC,KAAK,OAAO;GAKjB,IAAI,CAAC,MAJiB,GAAG,CAAC,CAAC,QAAiC,kBAAkB;IAC5E,IAAI,IAAI;IACR,QAAQ,KAAK;GACf,CAAC,KACe,CAAE,MAAM,gBAAgB;IAAE,OAAO,KAAK;IAAO,IAAI,IAAI;GAAgB,CAAC,GAAI,OAAO;GACjG,OAAO,aAAa,GAAG;EACzB;EAEA,MAAM,oBAAoB,OAAO,SAAiF;GAChH,MAAM,aAAa,MAAM,cAAc,IAAI;GAC3C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,oFAAoF;GACtG,OAAO;EACT;EAEA,MAAM,uBAAuB,OAAO,SAA2E;GAC7G,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAgC,sBAAsB,EAAE,IAAI,KAAK,GAAG,CAAC;GAC5F,IAAI,CAAC,OAAO,CAAE,MAAM,cAAc;IAAE,OAAO,KAAK;IAAO,IAAI,IAAI;GAAc,CAAC,GAAI,OAAO;GACzF,OAAO,oBAAoB,GAAG;EAChC;EAEA,MAAM,2BAA2B,OAAO,OAAkD;GACxF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAgC,sBAAsB,EAAE,GAAG,CAAC;GACnF,IAAI,CAAC,KAAK,OAAO;GAKjB,OAAO,MAJkB,GAAG,CAAC,CAAC,QAAyB,aAAa;IAClE,IAAI,IAAI;IACR,gBAAgB;GAClB,CAAC,IACmB,oBAAoB,GAAG,IAAI;EACjD;EAEA,MAAM,+BAA+B,OAAO,OAA2C;GACrF,MAAM,oBAAoB,MAAM,yBAAyB,EAAE;GAC3D,IAAI,CAAC,mBAAmB,MAAM,IAAI,MAAM,oDAAoD;GAC5F,OAAO;EACT;EAEA,MAAM,aAAa,OAAO,OAAyD;GACjF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAsB,WAAW,EAAE,GAAG,CAAC;GAC9D,IAAI,CAAC,OAAO,CAAE,MAAM,yBAAyB,IAAI,qBAAqB,GAAI,OAAO;GACjF,OAAO,UAAU,GAAG;EACtB;EAEA,MAAM,iBAAiB,OAAO,OAAkD;GAC9E,MAAM,UAAU,MAAM,WAAW,EAAE;GACnC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,4DAA4D;GAC1F,OAAO;EACT;EAEA,OAAO;GACL;GACA,eAAe;IACb,MAAM,OAAO,EAAE,aAEX,MAAM,GAAG,CAAC,CAAC,SAA4B,eAAe;KACpD,gBAAgB;KAChB,QAAQ;IACV,CAAC,EAAA,CACD,IAAI,cAAc;IACtB,KAAK;IACL,kBAAkB,OAAO,EAAE,OAAO,iBAAiB;KACjD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAA2B,eAAe;MAC/D,gBAAgB;MAChB,QAAQ;MACR,aAAa;KACf,CAAC;KACD,OAAO,MAAM,eAAe,GAAG,IAAI;IACrC;IACA,QAAQ,OAAM,UAAS;KAerB,OAAO,eAAe,MAdJ,GAAG,CAAC,CAAC,UACrB,eACA;MAAC;MAAkB;MAAU;KAAa,GAC1C;MACE,gBAAgB;MAChB,QAAQ,MAAM;MACd,sBAAsB,MAAM;MAC5B,aAAa,MAAM;MACnB,cAAc,MAAM,eAAe;MACnC,cAAc,MAAM,eAAe;MACnC,mBAAmB,MAAM,oBAAoB,CAAC;MAC9C,4BAAY,IAAI,KAAK;KACvB,CACF,CACyB;IAC3B;IACA,QAAQ,OAAO,EAAE,OAAO,SAAS;KAE/B,IAAI,CAAC,MADsB,gBAAgB;MAAE;MAAO;KAAG,CAAC,GACrC,OAAO;KAC1B,MAAM,GAAG,CAAC,CAAC,WAAW,eAAe;MAAE;MAAI,gBAAgB;MAAe,QAAQ;KAAM,CAAC;KACzF,OAAO;IACT;GACF;GACA,cAAc;IACZ,MAAM,OAAO,EAAE,OAAO,qBAAqB;KACzC,MAAM,oBAAoB;MAAE;MAAO,IAAI;KAAe,CAAC;KACvD,QAAQ,MAAM,GAAG,CAAC,CAAC,SAA0B,cAAc,EAAE,iBAAiB,eAAe,CAAC,EAAA,CAAG,IAC/F,YACF;IACF;IACA,KAAK;IACL,kBAAkB,OAAO,EAAE,OAAO,iBAAiB;KACjD,MAAM,OAAO,MAAM,GAAG,CAAC,CAAC,SAA0B,cAAc,EAAE,aAAa,WAAW,CAAC;KAC3F,KAAK,MAAM,OAAO,MAChB,IAAI,MAAM,gBAAgB;MAAE;MAAO,IAAI,IAAI;KAAgB,CAAC,GAAG,OAAO,aAAa,GAAG;KAExF,OAAO;IACT;IACA,YAAY,OAAO,EAAE,OAAO,gBAAgB,WAAW;KACrD,MAAM,oBAAoB;MAAE;MAAO,IAAI;KAAe,CAAC;KACvD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAyB,cAAc;MAAE,iBAAiB;MAAgB;KAAK,CAAC;KACvG,OAAO,MAAM,aAAa,GAAG,IAAI;IACnC;IACA,QAAQ,OAAO,EAAE,OAAO,YAAY;KAClC,MAAM,oBAAoB;MAAE;MAAO,IAAI,MAAM;KAAe,CAAC;KAC7D,MAAM,sBAAM,IAAI,KAAK;KAUrB,OAAO,aAAa,MATF,GAAG,CAAC,CAAC,UAA2B,cAAc,CAAC,mBAAmB,aAAa,GAAG;MAClG,iBAAiB,MAAM;MACvB,aAAa,MAAM;MACnB,MAAM,MAAM;MACZ,gBAAgB,MAAM;MACtB,mBAAmB,MAAM,oBAAoB,CAAC;MAC9C,YAAY;MACZ,YAAY;KACd,CAAC,CACsB;IACzB;GACF;GACA,aAAa;IACX,MAAM,OAAO,EAAE,OAAO,uBAAuB;KAK3C,IAAI,CAAC,MAJiB,GAAG,CAAC,CAAC,QAAiC,kBAAkB;MAC5E,IAAI;MACJ,QAAQ;KACV,CAAC,GACa,OAAO,CAAC;KACtB,QACE,MAAM,GAAG,CAAC,CAAC,SAA0B,aAAa;MAChD,oBAAoB;MACpB,gBAAgB;KAClB,CAAC,EAAA,CACD,IAAI,YAAY;IACpB;IACA,KAAK;IACL,QAAQ,OAAM,UAAS;KAKrB,IAAI,CAAC,MAJiB,GAAG,CAAC,CAAC,QAAiC,kBAAkB;MAC5E,IAAI,MAAM;MACV,QAAQ,MAAM;KAChB,CAAC,GACa,MAAM,IAAI,MAAM,kDAAkD;KAChF,MAAM,oBAAoB;MAAE,OAAO,MAAM;MAAO,IAAI,MAAM;KAAe,CAAC;KAC1E,IAAI;MAQF,OAAO,aAAa,MAPF,GAAG,CAAC,CAAC,UAA2B,aAAa;OAC7D,oBAAoB,MAAM;OAC1B,gBAAgB;OAChB,iBAAiB,MAAM;OACvB,oBAAoB,MAAM;OAC1B,4BAAY,IAAI,KAAK;MACvB,CAAC,CACsB;KACzB,SAAS,OAAO;MACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;MACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAyB,aAAa;OAC3D,oBAAoB,MAAM;OAC1B,gBAAgB;OAChB,iBAAiB,MAAM;MACzB,CAAC;MACD,IAAI,CAAC,KAAK,MAAM;MAChB,OAAO,aAAa,GAAG;KACzB;IACF;IACA,QAAQ,OAAO,EAAE,OAAO,SAAS;KAE/B,IAAI,CAAC,MADoB,cAAc;MAAE;MAAO;KAAG,CAAC,GACnC,OAAO;KACxB,MAAM,sBAAsB,MAAM,GAAG,CAAC,CAAC,SAAiC,sBAAsB,EAC5F,eAAe,GACjB,CAAC;KACD,KAAK,MAAM,qBAAqB,qBAAqB;MACnD,MAAM,GAAG,CAAC,CAAC,WAAW,UAAU,EAAE,uBAAuB,kBAAkB,GAAG,CAAC;MAC/E,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,uBAAuB,kBAAkB,GAAG,CAAC;MAChF,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,uBAAuB,kBAAkB,GAAG,CAAC;KAClF;KACA,MAAM,GAAG,CAAC,CAAC,WAAW,sBAAsB,EAAE,eAAe,GAAG,CAAC;KACjE,MAAM,GAAG,CAAC,CAAC,WAAW,aAAa;MAAE;MAAI,gBAAgB;KAAc,CAAC;KACxE,OAAO;IACT;GACF;GACA,qBAAqB;IACnB,MAAM,OAAO,EAAE,OAAO,mBAAmB;KACvC,MAAM,kBAAkB;MAAE;MAAO,IAAI;KAAa,CAAC;KACnD,QACE,MAAM,GAAG,CAAC,CAAC,SAAiC,sBAAsB,EAAE,eAAe,aAAa,CAAC,EAAA,CACjG,IAAI,mBAAmB;IAC3B;IACA,4BAA4B,YAAY;KACtC,MAAM,uBAAO,IAAI,IAA6C;KAC9D,MAAM,cAAc,MAAM,GAAG,CAAC,CAAC,SAA0B,aAAa,EAAE,gBAAgB,cAAc,CAAC;KACvG,KAAK,MAAM,cAAc,aAAa;MACpC,MAAM,eAAe,MAAM,GAAG,CAAC,CAAC,QAA2B,eAAe;OACxE,IAAI,WAAW;OACf,gBAAgB;MAClB,CAAC;MACD,IAAI,CAAC,cAAc;MACnB,MAAM,QAAQ,MAAM,GAAG,CAAC,CAAC,SAAiC,sBAAsB,EAC9E,eAAe,WAAW,GAC5B,CAAC;MACD,KAAK,MAAM,QAAQ,OAAO;OACxB,MAAM,aAAa,MAAM,GAAG,CAAC,CAAC,QAAyB,cAAc,EAAE,IAAI,KAAK,cAAc,CAAC;OAC/F,IAAI,CAAC,YAAY;OACjB,KAAK,IAAI,GAAG,aAAa,YAAY,QAAQ,WAAW,eAAe;QACrE,wBAAwB,aAAa;QACrC,sBAAsB,WAAW;OACnC,CAAC;MACH;KACF;KACA,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC;IAC1B;IACA,0BAA0B,OAAO,EAAE,wBAAwB,2BAA2B;KACpF,MAAM,UAA6C,CAAC;KACpD,MAAM,gBAAgB,MAAM,GAAG,CAAC,CAAC,SAA4B,eAAe;MAC1E,gBAAgB;MAChB,aAAa;KACf,CAAC;KACD,KAAK,MAAM,gBAAgB,eAAe;MACxC,MAAM,aAAa,MAAM,GAAG,CAAC,CAAC,QAAyB,cAAc;OACnE,iBAAiB,aAAa;OAC9B,aAAa;MACf,CAAC;MACD,IAAI,CAAC,YAAY;MACjB,MAAM,QAAQ,MAAM,GAAG,CAAC,CAAC,SAAiC,sBAAsB,EAC9E,eAAe,WAAW,GAC5B,CAAC;MACD,KAAK,MAAM,QAAQ,OAAO;OACxB,MAAM,aAAa,MAAM,GAAG,CAAC,CAAC,QAAyB,aAAa;QAClE,IAAI,KAAK;QACT,gBAAgB;QAChB,iBAAiB,aAAa;OAChC,CAAC;OACD,IAAI,CAAC,YAAY;OAKjB,IAAI,CAAC,MAJiB,GAAG,CAAC,CAAC,QAAiC,kBAAkB;QAC5E,IAAI,WAAW;QACf,QAAQ,aAAa;OACvB,CAAC,GACa;OACd,QAAQ,KAAK;QACX,OAAO,aAAa;QACpB,kBAAkB,WAAW;QAC7B,mBAAmB,oBAAoB,IAAI;OAC7C,CAAC;MACH;KACF;KACA,OAAO;IACT;IACA,KAAK;IACL,MAAM,OAAM,UAAS;KACnB,MAAM,aAAa,MAAM,kBAAkB;MAAE,OAAO,MAAM;MAAO,IAAI,MAAM;KAAa,CAAC;KAEzF,KAAI,MADqB,kBAAkB;MAAE,OAAO,MAAM;MAAO,IAAI,MAAM;KAAa,CAAC,EAAA,CAC1E,mBAAmB,WAAW,gBAC3C,MAAM,IAAI,MAAM,4DAA4D;KAE9E,MAAM,sBAAM,IAAI,KAAK;KAgBrB,OAAO,oBAAoB,MAfT,GAAG,CAAC,CAAC,UACrB,sBACA,CAAC,iBAAiB,eAAe,GACjC;MACE,eAAe,MAAM;MACrB,eAAe,MAAM;MACrB,oBAAoB,MAAM;MAC1B,QAAQ,MAAM,UAAU;MACxB,kBAAkB,MAAM;MACxB,iBAAiB,MAAM;MACvB,eAAe,MAAM,gBAAgB;MACrC,YAAY;MACZ,YAAY;KACd,CACF,CAC8B;IAChC;IACA,QAAQ,OAAO,EAAE,OAAO,IAAI,YAAY;KAEtC,IAAI,CAAC,MADkB,qBAAqB;MAAE;MAAO;KAAG,CAAC,GAC1C,OAAO;KACtB,MAAM,QAAiC,EAAE,4BAAY,IAAI,KAAK,EAAE;KAChE,IAAI,MAAM,WAAW,KAAA,GAAW,MAAM,SAAS,MAAM;KACrD,IAAI,MAAM,oBAAoB,KAAA,GAAW,MAAM,mBAAmB,MAAM;KACxE,IAAI,MAAM,mBAAmB,KAAA,GAAW,MAAM,kBAAkB,MAAM;KACtE,IAAI,MAAM,iBAAiB,KAAA,GAAW,MAAM,gBAAgB,MAAM;KAClE,MAAM,GAAG,CAAC,CAAC,WAAW,sBAAsB,EAAE,GAAG,GAAG,KAAK;KACzD,OAAO,qBAAqB;MAAE;MAAO;KAAG,CAAC;IAC3C;IACA,QAAQ,OAAO,EAAE,OAAO,SAAS;KAE/B,IAAI,CAAC,MADkB,qBAAqB;MAAE;MAAO;KAAG,CAAC,GAC1C,OAAO;KACtB,MAAM,GAAG,CAAC,CAAC,WAAW,UAAU,EAAE,uBAAuB,GAAG,CAAC;KAC7D,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,uBAAuB,GAAG,CAAC;KAC9D,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,uBAAuB,GAAG,CAAC;KAC9D,MAAM,GAAG,CAAC,CAAC,WAAW,sBAAsB,EAAE,GAAG,CAAC;KAClD,OAAO;IACT;GACF;GACA,WAAW;IACT,aAAa,OAAO,EAAE,mBAAmB,aAAa;KACpD,MAAM,6BAA6B,kBAAkB,EAAE;KACvD,MAAM,QAAQ;MAAE,uBAAuB,kBAAkB;MAAI,SAAS;KAAO;KAC7E,MAAM,WAAW,MAAM,GAAG,CAAC,CAAC,QAAsB,WAAW,KAAK;KAClE,IAAI,UAAU,OAAO,UAAU,QAAQ;KACvC,IAAI;MAQF,OAAO,UAAU,MAPC,GAAG,CAAC,CAAC,UAAwB,WAAW;OACxD,GAAG;OACH,YAAY;OACZ,iBAAiB,kBAAkB;OACnC,iBAAiB;OACjB,4BAAY,IAAI,KAAK;MACvB,CAAC,CACmB;KACtB,SAAS,OAAO;MACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;MACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAsB,WAAW,KAAK;MAC7D,IAAI,CAAC,KAAK,MAAM;MAChB,OAAO,UAAU,GAAG;KACtB;IACF;IACA,UAAU,EAAE,SAAS,WAAW,EAAE;IAClC,YAAY,OAAO,EAAE,IAAI,qBAAqB;KAC5C,MAAM,eAAe,EAAE;KACvB,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,GAAG,GAAG;MAAE,iBAAiB;MAAgB,iBAAiB;KAAK,CAAC;IACrG;IACA,cAAc,OAAO,EAAE,IAAI,gBAAgB;KACzC,MAAM,eAAe,EAAE;KACvB,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,GAAG,GAAG,EAAE,YAAY,UAAU,CAAC;IACpE;IACA,cAAc,OAAO,EAAE,SAAS;KAC9B,MAAM,eAAe,EAAE;KACvB,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,GAAG,GAAG;MAAE,YAAY;MAAM,iBAAiB;KAAK,CAAC;IACtF;IACA,kBAAkB,OAAO,EAAE,SAAS;KAClC,MAAM,eAAe,EAAE;KACvB,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW,EAAE,GAAG,GAAG,EAAE,iCAAiB,IAAI,KAAK,EAAE,CAAC;IAC1E;GACF;GACA,WAAW;IACT,QAAQ,OAAM,UAAS;KACrB,MAAM,6BAA6B,MAAM,mBAAmB;KAC5D,MAAM,GAAG,CAAC,CAAC,UAAyB,WAAW;MAAC;MAAyB;MAAW;KAAQ,GAAG;MAC7F,uBAAuB,MAAM;MAC7B,SAAS,MAAM;MACf,QAAQ,MAAM;MACd,aAAa,MAAM;MACnB,eAAe,MAAM;MACrB,4BAAY,IAAI,KAAK;KACvB,CAAC;IACH;IACA,MAAM,OAAO,EAAE,qBAAqB,aAAa;KAC/C,IAAI,CAAE,MAAM,yBAAyB,mBAAmB,GAAI,OAAO,CAAC;KAKpE,QAAO,MAJY,GAAG,CAAC,CAAC,SAAwB,WAAW;MACzD,uBAAuB;MACvB,SAAS;KACX,CAAC,EAAA,CACW,IAAI,UAAU;IAC5B;IACA,KAAK,OAAO,EAAE,qBAAqB,QAAQ,aAAa;KACtD,IAAI,CAAE,MAAM,yBAAyB,mBAAmB,GAAI,OAAO;KACnE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAuB,WAAW;MACvD,uBAAuB;MACvB,SAAS;MACT;KACF,CAAC;KACD,OAAO,MAAM,WAAW,GAAG,IAAI;IACjC;IACA,YAAY,OAAO,EAAE,qBAAqB,QAAQ,mBAAmB;KACnE,IAAI,CAAE,MAAM,yBAAyB,mBAAmB,GAAI,OAAO;KACnE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAuB,WAAW;MACvD,uBAAuB;MACvB,SAAS;MACT,eAAe;KACjB,CAAC;KACD,OAAO,MAAM,WAAW,GAAG,IAAI;IACjC;IACA,QAAQ,OAAO,EAAE,qBAAqB,QAAQ,aAAa;KACzD,MAAM,6BAA6B,mBAAmB;KACtD,MAAM,GAAG,CAAC,CAAC,WAAW,WAAW;MAC/B,uBAAuB;MACvB,SAAS;MACT;KACF,CAAC;IACH;GACF;GACA,UAAU;IACR,MAAM,OAAO,EAAE,qBAAqB,aAAa;KAC/C,IAAI,CAAE,MAAM,yBAAyB,mBAAmB,GAAI,OAAO,CAAC;KACpE,QACE,MAAM,GAAG,CAAC,CAAC,SAAuB,UAAU;MAC1C,uBAAuB;MACvB,SAAS;KACX,CAAC,EAAA,CACD,IAAI,SAAS;IACjB;IACA,gBAAgB,OAAM,cAAa;KACjC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAsB,UAAU,EAAE,YAAY,UAAU,CAAC;KAChF,OAAO,OAAQ,MAAM,yBAAyB,IAAI,qBAAqB,IAAK,UAAU,GAAG,IAAI;IAC/F;IACA,cAAc,OAAO,EAAE,qBAAqB,QAAQ,aAAa;KAC/D,IAAI,CAAE,MAAM,yBAAyB,mBAAmB,GAAI,OAAO;KACnE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAsB,UAAU;MACrD,uBAAuB;MACvB,SAAS;MACT;KACF,CAAC;KACD,OAAO,MAAM,UAAU,GAAG,IAAI;IAChC;IACA,QAAQ,OAAM,UAAS;KACrB,MAAM,6BAA6B,MAAM,mBAAmB;KAC5D,MAAM,WAAW,MAAM,GAAG,CAAC,CAAC,QAAsB,UAAU;MAC1D,uBAAuB,MAAM;MAC7B,SAAS,MAAM;MACf,QAAQ,MAAM;KAChB,CAAC;KACD,IAAI,UAAU,OAAO,UAAU,QAAQ;KACvC,MAAM,sBAAM,IAAI,KAAK;KACrB,IAAI;MAcF,OAAO,UAAU,MAbC,GAAG,CAAC,CAAC,UAAwB,UAAU;OACvD,YAAY,MAAM;OAClB,uBAAuB,MAAM;OAC7B,QAAQ,MAAM;OACd,SAAS,MAAM;OACf,QAAQ,MAAM;OACd,aAAa,MAAM;OACnB,YAAY;OACZ,iBAAiB;OACjB,iBAAiB;OACjB,YAAY;OACZ,YAAY;MACd,CAAC,CACmB;KACtB,SAAS,OAAO;MACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;MACpD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,QAAsB,UAAU;OACrD,uBAAuB,MAAM;OAC7B,SAAS,MAAM;OACf,QAAQ,MAAM;MAChB,CAAC;MACD,IAAI,CAAC,KAAK,MAAM;MAChB,OAAO,UAAU,GAAG;KACtB;IACF;IACA,YAAY,OAAO,EAAE,IAAI,WAAW,qBAAqB;KACvD,MAAM,GAAG,CAAC,CAAC,WACT,UACA,EAAE,GAAG,GACL;MAAE,YAAY;MAAW,iBAAiB;MAAgB,4BAAY,IAAI,KAAK;KAAE,CACnF;IACF;IACA,kBAAkB,OAAO,EAAE,SAAS;KAClC,MAAM,GAAG,CAAC,CAAC,WAAW,UAAU,EAAE,GAAG,GAAG;MAAE,iCAAiB,IAAI,KAAK;MAAG,4BAAY,IAAI,KAAK;KAAE,CAAC;IACjG;IACA,QAAQ,OAAM,OAAM;KAClB,MAAM,GAAG,CAAC,CAAC,WAAW,UAAU,EAAE,GAAG,CAAC;IACxC;GACF;EACF;CACF;AACF"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/source-control/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nconst FACTORY_PROJECTS = 'factory_projects';\nconst INSTALLATIONS = 'source_control_installations';\nconst REPOSITORIES = 'source_control_repositories';\nconst CONNECTIONS = 'factory_project_source_control_connections';\nconst PROJECT_REPOSITORIES = 'factory_project_repositories';\nconst SANDBOXES = 'source_control_project_repository_sandboxes';\nconst WORKTREES = 'source_control_worktrees';\nconst SESSIONS = 'source_control_sessions';\n\nexport const SOURCE_CONTROL_SCHEMAS: CollectionSchema[] = [\n {\n name: INSTALLATIONS,\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n connected_by_user_id: { type: 'text' },\n external_id: { type: 'text' },\n account_name: { type: 'text', nullable: true },\n account_type: { type: 'text', nullable: true },\n provider_metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_installations_integration_org_external_unique',\n columns: ['integration_id', 'org_id', 'external_id'],\n },\n ],\n },\n {\n name: REPOSITORIES,\n columns: {\n id: { type: 'uuid-pk' },\n installation_id: { type: 'text' },\n external_id: { type: 'text' },\n slug: { type: 'text' },\n default_branch: { type: 'text', default: 'main' },\n provider_metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_repositories_installation_external_unique',\n columns: ['installation_id', 'external_id'],\n },\n ],\n indexes: [\n {\n name: 'source_control_repositories_installation_slug_idx',\n columns: ['installation_id', 'slug'],\n },\n ],\n },\n {\n name: CONNECTIONS,\n columns: {\n id: { type: 'uuid-pk' },\n factory_project_id: { type: 'text' },\n integration_id: { type: 'text' },\n installation_id: { type: 'text' },\n created_by_user_id: { type: 'text' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'factory_project_source_control_connections_project_integration_installation_unique',\n columns: ['factory_project_id', 'integration_id', 'installation_id'],\n },\n ],\n indexes: [\n {\n name: 'factory_project_source_control_connections_project_idx',\n columns: ['factory_project_id'],\n },\n ],\n },\n {\n name: PROJECT_REPOSITORIES,\n columns: {\n id: { type: 'uuid-pk' },\n connection_id: { type: 'text' },\n repository_id: { type: 'text' },\n created_by_user_id: { type: 'text' },\n branch: { type: 'text', nullable: true },\n sandbox_provider: { type: 'text' },\n sandbox_workdir: { type: 'text' },\n setup_command: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'factory_project_repositories_connection_repository_unique',\n columns: ['connection_id', 'repository_id'],\n },\n ],\n indexes: [\n {\n name: 'factory_project_repositories_connection_idx',\n columns: ['connection_id'],\n },\n ],\n },\n {\n name: SANDBOXES,\n columns: {\n id: { type: 'uuid-pk' },\n project_repository_id: { type: 'text' },\n user_id: { type: 'text' },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text' },\n materialized_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_project_repository_sandboxes_link_user_unique',\n columns: ['project_repository_id', 'user_id'],\n },\n ],\n },\n {\n name: WORKTREES,\n columns: {\n id: { type: 'uuid-pk' },\n project_repository_id: { type: 'text' },\n user_id: { type: 'text' },\n branch: { type: 'text' },\n base_branch: { type: 'text' },\n worktree_path: { type: 'text' },\n created_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_worktrees_project_repository_user_branch_unique',\n columns: ['project_repository_id', 'user_id', 'branch'],\n },\n ],\n },\n {\n name: SESSIONS,\n columns: {\n id: { type: 'uuid-pk' },\n session_id: { type: 'text' },\n project_repository_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n branch: { type: 'text' },\n base_branch: { type: 'text' },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text', nullable: true },\n materialized_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'source_control_sessions_session_id_unique', columns: ['session_id'] },\n {\n name: 'source_control_sessions_repository_user_branch_unique',\n columns: ['project_repository_id', 'user_id', 'branch'],\n },\n ],\n },\n];\n\nexport type SourceControlProviderMetadata = Record<string, unknown>;\n\nexport interface SourceControlInstallation {\n id: string;\n integrationId: string;\n orgId: string;\n connectedByUserId: string;\n externalId: string;\n accountName: string | null;\n accountType: string | null;\n providerMetadata: SourceControlProviderMetadata;\n createdAt: Date;\n}\n\nexport interface UpsertSourceControlInstallationInput {\n orgId: string;\n connectedByUserId: string;\n externalId: string;\n accountName?: string | null;\n accountType?: string | null;\n providerMetadata?: SourceControlProviderMetadata;\n}\n\nexport interface SourceControlRepository {\n id: string;\n installationId: string;\n externalId: string;\n slug: string;\n defaultBranch: string;\n providerMetadata: SourceControlProviderMetadata;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertSourceControlRepositoryInput {\n installationId: string;\n externalId: string;\n slug: string;\n defaultBranch: string;\n providerMetadata?: SourceControlProviderMetadata;\n}\n\nexport interface ProjectSourceControlConnection {\n id: string;\n factoryProjectId: string;\n integrationId: string;\n installationId: string;\n createdByUserId: string;\n createdAt: Date;\n}\n\nexport interface CreateProjectSourceControlConnectionInput {\n orgId: string;\n factoryProjectId: string;\n installationId: string;\n createdByUserId: string;\n}\n\nexport interface ProjectRepository {\n id: string;\n connectionId: string;\n repositoryId: string;\n createdByUserId: string;\n branch: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface ExternalRepositoryProjectTarget {\n orgId: string;\n factoryProjectId: string;\n projectRepository: ProjectRepository;\n}\n\n/** External id pair identifying a repository linked to a factory project. */\nexport interface ConfiguredExternalRepositoryKey {\n installationExternalId: string;\n repositoryExternalId: string;\n}\n\nexport interface LinkProjectRepositoryInput {\n orgId: string;\n connectionId: string;\n repositoryId: string;\n createdByUserId: string;\n branch?: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand?: string | null;\n}\n\nexport interface UpdateProjectRepositoryInput {\n branch?: string | null;\n sandboxProvider?: string;\n sandboxWorkdir?: string;\n setupCommand?: string | null;\n}\n\nexport interface ProjectRepositorySandbox {\n id: string;\n projectRepositoryId: string;\n userId: string;\n sandboxId: string | null;\n sandboxWorkdir: string;\n materializedAt: Date | null;\n createdAt: Date;\n}\n\nexport interface SourceControlWorktree {\n id: string;\n projectRepositoryId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n worktreePath: string;\n createdAt: Date;\n}\n\nexport interface UpsertSourceControlWorktreeInput {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n worktreePath: string;\n}\n\nexport interface SourceControlSession {\n id: string;\n sessionId: string;\n projectRepositoryId: string;\n orgId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n sandboxId: string | null;\n sandboxWorkdir: string | null;\n materializedAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateSourceControlSessionInput {\n sessionId: string;\n projectRepositoryId: string;\n orgId: string;\n userId: string;\n branch: string;\n baseBranch: string;\n}\n\nexport interface SourceControlStorageHandle {\n readonly integrationId: string;\n readonly installations: {\n list(args: { orgId: string }): Promise<SourceControlInstallation[]>;\n get(args: { orgId: string; id: string }): Promise<SourceControlInstallation | null>;\n findByExternalId(args: { orgId: string; externalId: string }): Promise<SourceControlInstallation | null>;\n upsert(args: UpsertSourceControlInstallationInput): Promise<SourceControlInstallation>;\n delete(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly repositories: {\n list(args: { orgId: string; installationId: string }): Promise<SourceControlRepository[]>;\n get(args: { orgId: string; id: string }): Promise<SourceControlRepository | null>;\n findByExternalId(args: { orgId: string; externalId: string }): Promise<SourceControlRepository | null>;\n findBySlug(args: { orgId: string; installationId: string; slug: string }): Promise<SourceControlRepository | null>;\n upsert(args: { orgId: string; input: UpsertSourceControlRepositoryInput }): Promise<SourceControlRepository>;\n /**\n * Migrate a repository and its dependent connections to a new installation.\n * Used when a GitHub App is reinstalled with a new installation ID on the same account.\n * Returns the repository under the new installation (either migrated or existing).\n */\n migrateInstallation(args: {\n orgId: string;\n id: string;\n newInstallationId: string;\n }): Promise<SourceControlRepository>;\n };\n readonly connections: {\n list(args: { orgId: string; factoryProjectId: string }): Promise<ProjectSourceControlConnection[]>;\n get(args: { orgId: string; id: string }): Promise<ProjectSourceControlConnection | null>;\n create(args: CreateProjectSourceControlConnectionInput): Promise<ProjectSourceControlConnection>;\n delete(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly projectRepositories: {\n list(args: { orgId: string; connectionId: string }): Promise<ProjectRepository[]>;\n listByExternalRepository(args: {\n installationExternalId: string;\n repositoryExternalId: string;\n }): Promise<ExternalRepositoryProjectTarget[]>;\n /**\n * Distinct external (installation, repository) id pairs linked to any\n * factory project. Lets sweeps scope work to configured repositories\n * without probing every repository an installation can see.\n */\n listConfiguredExternalKeys(): Promise<ConfiguredExternalRepositoryKey[]>;\n get(args: { orgId: string; id: string }): Promise<ProjectRepository | null>;\n link(args: LinkProjectRepositoryInput): Promise<ProjectRepository>;\n update(args: { orgId: string; id: string; input: UpdateProjectRepositoryInput }): Promise<ProjectRepository | null>;\n unlink(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly sandboxes: {\n getOrCreate(args: { projectRepository: ProjectRepository; userId: string }): Promise<ProjectRepositorySandbox>;\n getById(args: { id: string }): Promise<ProjectRepositorySandbox | null>;\n /**\n * Point the binding at a new workdir and clear `materializedAt` — a moved\n * workdir means the checkout must be re-cloned. Used to heal bindings whose\n * inherited workdir went stale (e.g. the sandbox provider changed).\n */\n setWorkdir(args: { id: string; sandboxWorkdir: string }): Promise<void>;\n setSandboxId(args: { id: string; sandboxId: string }): Promise<void>;\n clearBinding(args: { id: string }): Promise<void>;\n markMaterialized(args: { id: string }): Promise<void>;\n };\n readonly worktrees: {\n upsert(args: UpsertSourceControlWorktreeInput): Promise<void>;\n list(args: { projectRepositoryId: string; userId: string }): Promise<SourceControlWorktree[]>;\n get(args: { projectRepositoryId: string; userId: string; branch: string }): Promise<SourceControlWorktree | null>;\n findByPath(args: {\n projectRepositoryId: string;\n userId: string;\n worktreePath: string;\n }): Promise<SourceControlWorktree | null>;\n delete(args: { projectRepositoryId: string; userId: string; branch: string }): Promise<void>;\n };\n readonly sessions: {\n list(args: { projectRepositoryId: string; userId: string }): Promise<SourceControlSession[]>;\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n getForBranch(args: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlSession | null>;\n create(input: CreateSourceControlSessionInput): Promise<SourceControlSession>;\n setSandbox(args: { id: string; sandboxId: string | null; sandboxWorkdir: string }): Promise<void>;\n markMaterialized(args: { id: string }): Promise<void>;\n delete(id: string): Promise<void>;\n };\n}\n\ninterface InstallationDbRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n connected_by_user_id: string;\n external_id: string;\n account_name: string | null;\n account_type: string | null;\n provider_metadata: SourceControlProviderMetadata;\n created_at: Date;\n}\n\ninterface RepositoryDbRow extends Record<string, unknown> {\n id: string;\n installation_id: string;\n external_id: string;\n slug: string;\n default_branch: string;\n provider_metadata: SourceControlProviderMetadata;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface ConnectionDbRow extends Record<string, unknown> {\n id: string;\n factory_project_id: string;\n integration_id: string;\n installation_id: string;\n created_by_user_id: string;\n created_at: Date;\n}\n\ninterface ProjectRepositoryDbRow extends Record<string, unknown> {\n id: string;\n connection_id: string;\n repository_id: string;\n created_by_user_id: string;\n branch: string | null;\n sandbox_provider: string;\n sandbox_workdir: string;\n setup_command: string | null;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SandboxDbRow extends Record<string, unknown> {\n id: string;\n project_repository_id: string;\n user_id: string;\n sandbox_id: string | null;\n sandbox_workdir: string;\n materialized_at: Date | null;\n created_at: Date;\n}\n\ninterface WorktreeDbRow extends Record<string, unknown> {\n id: string;\n project_repository_id: string;\n user_id: string;\n branch: string;\n base_branch: string;\n worktree_path: string;\n created_at: Date;\n}\n\ninterface SessionDbRow extends Record<string, unknown> {\n id: string;\n session_id: string;\n project_repository_id: string;\n org_id: string;\n user_id: string;\n branch: string;\n base_branch: string;\n sandbox_id: string | null;\n sandbox_workdir: string | null;\n materialized_at: Date | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toInstallation(row: InstallationDbRow): SourceControlInstallation {\n return {\n id: row.id,\n integrationId: row.integration_id,\n orgId: row.org_id,\n connectedByUserId: row.connected_by_user_id,\n externalId: row.external_id,\n accountName: row.account_name,\n accountType: row.account_type,\n providerMetadata: row.provider_metadata,\n createdAt: row.created_at,\n };\n}\n\nfunction toRepository(row: RepositoryDbRow): SourceControlRepository {\n return {\n id: row.id,\n installationId: row.installation_id,\n externalId: row.external_id,\n slug: row.slug,\n defaultBranch: row.default_branch,\n providerMetadata: row.provider_metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction toConnection(row: ConnectionDbRow): ProjectSourceControlConnection {\n return {\n id: row.id,\n factoryProjectId: row.factory_project_id,\n integrationId: row.integration_id,\n installationId: row.installation_id,\n createdByUserId: row.created_by_user_id,\n createdAt: row.created_at,\n };\n}\n\nfunction toProjectRepository(row: ProjectRepositoryDbRow): ProjectRepository {\n return {\n id: row.id,\n connectionId: row.connection_id,\n repositoryId: row.repository_id,\n createdByUserId: row.created_by_user_id,\n branch: row.branch,\n sandboxProvider: row.sandbox_provider,\n sandboxWorkdir: row.sandbox_workdir,\n setupCommand: row.setup_command,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction toSandbox(row: SandboxDbRow): ProjectRepositorySandbox {\n return {\n id: row.id,\n projectRepositoryId: row.project_repository_id,\n userId: row.user_id,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n createdAt: row.created_at,\n };\n}\n\nfunction toWorktree(row: WorktreeDbRow): SourceControlWorktree {\n return {\n id: row.id,\n projectRepositoryId: row.project_repository_id,\n userId: row.user_id,\n branch: row.branch,\n baseBranch: row.base_branch,\n worktreePath: row.worktree_path,\n createdAt: row.created_at,\n };\n}\n\nfunction toSession(row: SessionDbRow): SourceControlSession {\n return {\n id: row.id,\n sessionId: row.session_id,\n projectRepositoryId: row.project_repository_id,\n orgId: row.org_id,\n userId: row.user_id,\n branch: row.branch,\n baseBranch: row.base_branch,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class SourceControlStorage extends FactoryStorageDomain {\n constructor() {\n super('source-control');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections(SOURCE_CONTROL_SCHEMAS);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany(SESSIONS, {});\n await this.ops.deleteMany(WORKTREES, {});\n await this.ops.deleteMany(SANDBOXES, {});\n await this.ops.deleteMany(PROJECT_REPOSITORIES, {});\n await this.ops.deleteMany(CONNECTIONS, {});\n await this.ops.deleteMany(REPOSITORIES, {});\n await this.ops.deleteMany(INSTALLATIONS, {});\n }\n\n forIntegration(integrationId: string): SourceControlStorageHandle {\n if (!integrationId.trim()) throw new Error('[SourceControlStorage] integrationId must not be empty.');\n const db = (): FactoryStorageOps => this.ops;\n\n const getInstallation = async (args: { orgId: string; id: string }): Promise<SourceControlInstallation | null> => {\n const row = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n id: args.id,\n integration_id: integrationId,\n org_id: args.orgId,\n });\n return row ? toInstallation(row) : null;\n };\n\n const requireInstallation = async (args: { orgId: string; id: string }): Promise<SourceControlInstallation> => {\n const installation = await getInstallation(args);\n if (!installation)\n throw new Error('Source-control installation not found for this organization and integration.');\n return installation;\n };\n\n const getRepository = async (args: { orgId: string; id: string }): Promise<SourceControlRepository | null> => {\n const row = await db().findOne<RepositoryDbRow>(REPOSITORIES, { id: args.id });\n if (!row || !(await getInstallation({ orgId: args.orgId, id: row.installation_id }))) return null;\n return toRepository(row);\n };\n\n const requireRepository = async (args: { orgId: string; id: string }): Promise<SourceControlRepository> => {\n const repository = await getRepository(args);\n if (!repository) throw new Error('Source-control repository not found for this organization and integration.');\n return repository;\n };\n\n const getConnection = async (args: {\n orgId: string;\n id: string;\n }): Promise<ProjectSourceControlConnection | null> => {\n const row = await db().findOne<ConnectionDbRow>(CONNECTIONS, { id: args.id, integration_id: integrationId });\n if (!row) return null;\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: row.factory_project_id,\n org_id: args.orgId,\n });\n if (!project || !(await getInstallation({ orgId: args.orgId, id: row.installation_id }))) return null;\n return toConnection(row);\n };\n\n const requireConnection = async (args: { orgId: string; id: string }): Promise<ProjectSourceControlConnection> => {\n const connection = await getConnection(args);\n if (!connection)\n throw new Error('Project source-control connection not found for this organization and integration.');\n return connection;\n };\n\n const getProjectRepository = async (args: { orgId: string; id: string }): Promise<ProjectRepository | null> => {\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { id: args.id });\n if (!row || !(await getConnection({ orgId: args.orgId, id: row.connection_id }))) return null;\n return toProjectRepository(row);\n };\n\n const getProjectRepositoryById = async (id: string): Promise<ProjectRepository | null> => {\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { id });\n if (!row) return null;\n const connection = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n id: row.connection_id,\n integration_id: integrationId,\n });\n return connection ? toProjectRepository(row) : null;\n };\n\n const requireProjectRepositoryById = async (id: string): Promise<ProjectRepository> => {\n const projectRepository = await getProjectRepositoryById(id);\n if (!projectRepository) throw new Error('Project repository not found for this integration.');\n return projectRepository;\n };\n\n const getSandbox = async (id: string): Promise<ProjectRepositorySandbox | null> => {\n const row = await db().findOne<SandboxDbRow>(SANDBOXES, { id });\n if (!row || !(await getProjectRepositoryById(row.project_repository_id))) return null;\n return toSandbox(row);\n };\n\n const requireSandbox = async (id: string): Promise<ProjectRepositorySandbox> => {\n const sandbox = await getSandbox(id);\n if (!sandbox) throw new Error('Project-repository sandbox not found for this integration.');\n return sandbox;\n };\n\n return {\n integrationId,\n installations: {\n list: async ({ orgId }) =>\n (\n await db().findMany<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n org_id: orgId,\n })\n ).map(toInstallation),\n get: getInstallation,\n findByExternalId: async ({ orgId, externalId }) => {\n const row = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n org_id: orgId,\n external_id: externalId,\n });\n return row ? toInstallation(row) : null;\n },\n upsert: async input => {\n const row = await db().upsertOne<InstallationDbRow>(\n INSTALLATIONS,\n ['integration_id', 'org_id', 'external_id'],\n {\n integration_id: integrationId,\n org_id: input.orgId,\n connected_by_user_id: input.connectedByUserId,\n external_id: input.externalId,\n account_name: input.accountName ?? null,\n account_type: input.accountType ?? null,\n provider_metadata: input.providerMetadata ?? {},\n created_at: new Date(),\n },\n );\n return toInstallation(row);\n },\n delete: async ({ orgId, id }) => {\n const installation = await getInstallation({ orgId, id });\n if (!installation) return false;\n await db().deleteMany(INSTALLATIONS, { id, integration_id: integrationId, org_id: orgId });\n return true;\n },\n },\n repositories: {\n list: async ({ orgId, installationId }) => {\n await requireInstallation({ orgId, id: installationId });\n return (await db().findMany<RepositoryDbRow>(REPOSITORIES, { installation_id: installationId })).map(\n toRepository,\n );\n },\n get: getRepository,\n findByExternalId: async ({ orgId, externalId }) => {\n const rows = await db().findMany<RepositoryDbRow>(REPOSITORIES, { external_id: externalId });\n for (const row of rows) {\n if (await getInstallation({ orgId, id: row.installation_id })) return toRepository(row);\n }\n return null;\n },\n findBySlug: async ({ orgId, installationId, slug }) => {\n await requireInstallation({ orgId, id: installationId });\n const row = await db().findOne<RepositoryDbRow>(REPOSITORIES, { installation_id: installationId, slug });\n return row ? toRepository(row) : null;\n },\n upsert: async ({ orgId, input }) => {\n await requireInstallation({ orgId, id: input.installationId });\n const now = new Date();\n const row = await db().upsertOne<RepositoryDbRow>(REPOSITORIES, ['installation_id', 'external_id'], {\n installation_id: input.installationId,\n external_id: input.externalId,\n slug: input.slug,\n default_branch: input.defaultBranch,\n provider_metadata: input.providerMetadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return toRepository(row);\n },\n migrateInstallation: async ({ orgId, id, newInstallationId }) => {\n const existing = await getRepository({ orgId, id });\n if (!existing) {\n throw new Error(`Repository ${id} not found in organization ${orgId}`);\n }\n await requireInstallation({ orgId, id: newInstallationId });\n try {\n await db().updateMany(REPOSITORIES, { id }, { installation_id: newInstallationId, updated_at: new Date() });\n // Migrate dependent connections to the new installation\n await db().updateMany(\n CONNECTIONS,\n { installation_id: existing.installationId },\n { installation_id: newInstallationId },\n );\n // Return the updated repository\n const updated = await getRepository({ orgId, id });\n if (!updated) throw new Error('Repository disappeared after update');\n return updated;\n } catch (error) {\n // Unique constraint violation: repository already exists under the new installation\n if (!(error instanceof UniqueViolationError)) throw error;\n // Find and return the existing repository under the new installation\n const conflictRow = await db().findOne<RepositoryDbRow>(REPOSITORIES, {\n installation_id: newInstallationId,\n external_id: existing.externalId,\n });\n if (!conflictRow) throw error; // Should never happen if we got a unique violation\n return toRepository(conflictRow);\n }\n },\n },\n connections: {\n list: async ({ orgId, factoryProjectId }) => {\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: factoryProjectId,\n org_id: orgId,\n });\n if (!project) return [];\n return (\n await db().findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n })\n ).map(toConnection);\n },\n get: getConnection,\n create: async input => {\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: input.factoryProjectId,\n org_id: input.orgId,\n });\n if (!project) throw new Error('Factory project not found for this organization.');\n await requireInstallation({ orgId: input.orgId, id: input.installationId });\n try {\n const row = await db().insertOne<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: input.factoryProjectId,\n integration_id: integrationId,\n installation_id: input.installationId,\n created_by_user_id: input.createdByUserId,\n created_at: new Date(),\n });\n return toConnection(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: input.factoryProjectId,\n integration_id: integrationId,\n installation_id: input.installationId,\n });\n if (!row) throw error;\n return toConnection(row);\n }\n },\n delete: async ({ orgId, id }) => {\n const connection = await getConnection({ orgId, id });\n if (!connection) return false;\n const projectRepositories = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: id,\n });\n for (const projectRepository of projectRepositories) {\n await db().deleteMany(SESSIONS, { project_repository_id: projectRepository.id });\n await db().deleteMany(WORKTREES, { project_repository_id: projectRepository.id });\n await db().deleteMany(SANDBOXES, { project_repository_id: projectRepository.id });\n }\n await db().deleteMany(PROJECT_REPOSITORIES, { connection_id: id });\n await db().deleteMany(CONNECTIONS, { id, integration_id: integrationId });\n return true;\n },\n },\n projectRepositories: {\n list: async ({ orgId, connectionId }) => {\n await requireConnection({ orgId, id: connectionId });\n return (\n await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, { connection_id: connectionId })\n ).map(toProjectRepository);\n },\n listConfiguredExternalKeys: async () => {\n const keys = new Map<string, ConfiguredExternalRepositoryKey>();\n const connections = await db().findMany<ConnectionDbRow>(CONNECTIONS, { integration_id: integrationId });\n for (const connection of connections) {\n const installation = await db().findOne<InstallationDbRow>(INSTALLATIONS, {\n id: connection.installation_id,\n integration_id: integrationId,\n });\n if (!installation) continue;\n const links = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: connection.id,\n });\n for (const link of links) {\n const repository = await db().findOne<RepositoryDbRow>(REPOSITORIES, { id: link.repository_id });\n if (!repository) continue;\n keys.set(`${installation.external_id}\\u0000${repository.external_id}`, {\n installationExternalId: installation.external_id,\n repositoryExternalId: repository.external_id,\n });\n }\n }\n return [...keys.values()];\n },\n listByExternalRepository: async ({ installationExternalId, repositoryExternalId }) => {\n const targets: ExternalRepositoryProjectTarget[] = [];\n const installations = await db().findMany<InstallationDbRow>(INSTALLATIONS, {\n integration_id: integrationId,\n external_id: installationExternalId,\n });\n for (const installation of installations) {\n const repository = await db().findOne<RepositoryDbRow>(REPOSITORIES, {\n installation_id: installation.id,\n external_id: repositoryExternalId,\n });\n if (!repository) continue;\n const links = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n repository_id: repository.id,\n });\n for (const link of links) {\n const connection = await db().findOne<ConnectionDbRow>(CONNECTIONS, {\n id: link.connection_id,\n integration_id: integrationId,\n installation_id: installation.id,\n });\n if (!connection) continue;\n const project = await db().findOne<Record<string, unknown>>(FACTORY_PROJECTS, {\n id: connection.factory_project_id,\n org_id: installation.org_id,\n });\n if (!project) continue;\n targets.push({\n orgId: installation.org_id,\n factoryProjectId: connection.factory_project_id,\n projectRepository: toProjectRepository(link),\n });\n }\n }\n return targets;\n },\n get: getProjectRepository,\n link: async input => {\n const connection = await requireConnection({ orgId: input.orgId, id: input.connectionId });\n const repository = await requireRepository({ orgId: input.orgId, id: input.repositoryId });\n if (repository.installationId !== connection.installationId) {\n throw new Error('Repository does not belong to the connection installation.');\n }\n const now = new Date();\n const row = await db().upsertOne<ProjectRepositoryDbRow>(\n PROJECT_REPOSITORIES,\n ['connection_id', 'repository_id'],\n {\n connection_id: input.connectionId,\n repository_id: input.repositoryId,\n created_by_user_id: input.createdByUserId,\n branch: input.branch ?? null,\n sandbox_provider: input.sandboxProvider,\n sandbox_workdir: input.sandboxWorkdir,\n setup_command: input.setupCommand ?? null,\n created_at: now,\n updated_at: now,\n },\n );\n return toProjectRepository(row);\n },\n update: async ({ orgId, id, input }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return null;\n const patch: Record<string, unknown> = { updated_at: new Date() };\n if (input.branch !== undefined) patch.branch = input.branch;\n if (input.sandboxProvider !== undefined) patch.sandbox_provider = input.sandboxProvider;\n if (input.sandboxWorkdir !== undefined) patch.sandbox_workdir = input.sandboxWorkdir;\n if (input.setupCommand !== undefined) patch.setup_command = input.setupCommand;\n await db().updateMany(PROJECT_REPOSITORIES, { id }, patch);\n return getProjectRepository({ orgId, id });\n },\n unlink: async ({ orgId, id }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return false;\n await db().deleteMany(SESSIONS, { project_repository_id: id });\n await db().deleteMany(WORKTREES, { project_repository_id: id });\n await db().deleteMany(SANDBOXES, { project_repository_id: id });\n await db().deleteMany(PROJECT_REPOSITORIES, { id });\n return true;\n },\n },\n sandboxes: {\n getOrCreate: async ({ projectRepository, userId }) => {\n await requireProjectRepositoryById(projectRepository.id);\n const where = { project_repository_id: projectRepository.id, user_id: userId };\n const existing = await db().findOne<SandboxDbRow>(SANDBOXES, where);\n if (existing) return toSandbox(existing);\n try {\n const row = await db().insertOne<SandboxDbRow>(SANDBOXES, {\n ...where,\n sandbox_id: null,\n sandbox_workdir: projectRepository.sandboxWorkdir,\n materialized_at: null,\n created_at: new Date(),\n });\n return toSandbox(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<SandboxDbRow>(SANDBOXES, where);\n if (!row) throw error;\n return toSandbox(row);\n }\n },\n getById: ({ id }) => getSandbox(id),\n setWorkdir: async ({ id, sandboxWorkdir }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_workdir: sandboxWorkdir, materialized_at: null });\n },\n setSandboxId: async ({ id, sandboxId }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_id: sandboxId });\n },\n clearBinding: async ({ id }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { sandbox_id: null, materialized_at: null });\n },\n markMaterialized: async ({ id }) => {\n await requireSandbox(id);\n await db().updateMany(SANDBOXES, { id }, { materialized_at: new Date() });\n },\n },\n worktrees: {\n upsert: async input => {\n await requireProjectRepositoryById(input.projectRepositoryId);\n await db().upsertOne<WorktreeDbRow>(WORKTREES, ['project_repository_id', 'user_id', 'branch'], {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n base_branch: input.baseBranch,\n worktree_path: input.worktreePath,\n created_at: new Date(),\n });\n },\n list: async ({ projectRepositoryId, userId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n const rows = await db().findMany<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n });\n return rows.map(toWorktree);\n },\n get: async ({ projectRepositoryId, userId, branch }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n return row ? toWorktree(row) : null;\n },\n findByPath: async ({ projectRepositoryId, userId, worktreePath }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<WorktreeDbRow>(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n worktree_path: worktreePath,\n });\n return row ? toWorktree(row) : null;\n },\n delete: async ({ projectRepositoryId, userId, branch }) => {\n await requireProjectRepositoryById(projectRepositoryId);\n await db().deleteMany(WORKTREES, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n },\n },\n sessions: {\n list: async ({ projectRepositoryId, userId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n return (\n await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n })\n ).map(toSession);\n },\n getBySessionId: async sessionId => {\n const row = await db().findOne<SessionDbRow>(SESSIONS, { session_id: sessionId });\n return row && (await getProjectRepositoryById(row.project_repository_id)) ? toSession(row) : null;\n },\n getForBranch: async ({ projectRepositoryId, userId, branch }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return null;\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n user_id: userId,\n branch,\n });\n return row ? toSession(row) : null;\n },\n create: async input => {\n await requireProjectRepositoryById(input.projectRepositoryId);\n const existing = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n });\n if (existing) return toSession(existing);\n const now = new Date();\n try {\n const row = await db().insertOne<SessionDbRow>(SESSIONS, {\n session_id: input.sessionId,\n project_repository_id: input.projectRepositoryId,\n org_id: input.orgId,\n user_id: input.userId,\n branch: input.branch,\n base_branch: input.baseBranch,\n sandbox_id: null,\n sandbox_workdir: null,\n materialized_at: null,\n created_at: now,\n updated_at: now,\n });\n return toSession(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n });\n if (!row) throw error;\n return toSession(row);\n }\n },\n setSandbox: async ({ id, sandboxId, sandboxWorkdir }) => {\n await db().updateMany(\n SESSIONS,\n { id },\n { sandbox_id: sandboxId, sandbox_workdir: sandboxWorkdir, updated_at: new Date() },\n );\n },\n markMaterialized: async ({ id }) => {\n await db().updateMany(SESSIONS, { id }, { materialized_at: new Date(), updated_at: new Date() });\n },\n delete: async id => {\n await db().deleteMany(SESSIONS, { id });\n },\n },\n };\n }\n}\n"],"mappings":"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"}
@@ -51,6 +51,11 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
51
51
  orgId: string;
52
52
  input: UpsertSourceControlRepositoryInput;
53
53
  }) => Promise<SourceControlRepository>;
54
+ migrateInstallation: ({ orgId, id, newInstallationId, }: {
55
+ orgId: string;
56
+ id: string;
57
+ newInstallationId: string;
58
+ }) => Promise<SourceControlRepository>;
54
59
  };
55
60
  readonly connections: {
56
61
  list: ({ factoryProjectId }: {
@@ -1 +1 @@
1
- {"version":3,"file":"inmemory.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/inmemory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inmemory.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/inmemory.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,23 @@ var SourceControlStorageInMemory = class {
104
104
  };
105
105
  this.repositoriesRows.push(created);
106
106
  return created;
107
+ },
108
+ migrateInstallation: async ({ orgId, id, newInstallationId }) => {
109
+ const existing = await this.repositories.get({
110
+ orgId,
111
+ id
112
+ });
113
+ if (!existing) throw new Error(`Repository ${id} not found in organization ${orgId}`);
114
+ if (!await this.installations.get({
115
+ orgId,
116
+ id: newInstallationId
117
+ })) throw new Error("Source-control installation not found");
118
+ const conflict = this.repositoriesRows.find((row) => row.installationId === newInstallationId && row.externalId === existing.externalId);
119
+ if (conflict) return conflict;
120
+ existing.installationId = newInstallationId;
121
+ existing.updatedAt = /* @__PURE__ */ new Date();
122
+ for (const conn of this.connectionsRows) if (conn.installationId === existing.installationId) conn.installationId = newInstallationId;
123
+ return existing;
107
124
  }
108
125
  };
109
126
  connections = {
@@ -1 +1 @@
1
- {"version":3,"file":"inmemory.js","names":[],"sources":["../../../../src/storage/domains/source-control/inmemory.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n ConfiguredExternalRepositoryKey,\n CreateProjectSourceControlConnectionInput,\n CreateSourceControlSessionInput,\n ExternalRepositoryProjectTarget,\n LinkProjectRepositoryInput,\n ProjectRepository,\n ProjectRepositorySandbox,\n ProjectSourceControlConnection,\n SourceControlInstallation,\n SourceControlRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n SourceControlWorktree,\n UpdateProjectRepositoryInput,\n UpsertSourceControlInstallationInput,\n UpsertSourceControlRepositoryInput,\n UpsertSourceControlWorktreeInput,\n} from './base.js';\n\n/** In-memory provider-scoped source-control handle for route tests. */\nexport class SourceControlStorageInMemory implements SourceControlStorageHandle {\n readonly integrationId: string;\n installationsRows: SourceControlInstallation[] = [];\n repositoriesRows: SourceControlRepository[] = [];\n connectionsRows: ProjectSourceControlConnection[] = [];\n projectRepositoriesRows: ProjectRepository[] = [];\n sandboxesRows: ProjectRepositorySandbox[] = [];\n worktreesRows: SourceControlWorktree[] = [];\n sessionsRows: SourceControlSession[] = [];\n\n constructor(integrationId = 'github') {\n this.integrationId = integrationId;\n }\n\n readonly installations = {\n list: async ({ orgId }: { orgId: string }): Promise<SourceControlInstallation[]> =>\n this.installationsRows.filter(row => row.orgId === orgId),\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<SourceControlInstallation | null> =>\n this.installationsRows.find(row => row.orgId === orgId && row.id === id) ?? null,\n findByExternalId: async ({\n orgId,\n externalId,\n }: {\n orgId: string;\n externalId: string;\n }): Promise<SourceControlInstallation | null> =>\n this.installationsRows.find(row => row.orgId === orgId && row.externalId === externalId) ?? null,\n upsert: async (input: UpsertSourceControlInstallationInput): Promise<SourceControlInstallation> => {\n const existing = this.installationsRows.find(\n row => row.orgId === input.orgId && row.externalId === input.externalId,\n );\n if (existing) {\n Object.assign(existing, {\n connectedByUserId: input.connectedByUserId,\n accountName: input.accountName ?? null,\n accountType: input.accountType ?? null,\n providerMetadata: input.providerMetadata ?? {},\n });\n return existing;\n }\n const created: SourceControlInstallation = {\n id: randomUUID(),\n integrationId: this.integrationId,\n orgId: input.orgId,\n connectedByUserId: input.connectedByUserId,\n externalId: input.externalId,\n accountName: input.accountName ?? null,\n accountType: input.accountType ?? null,\n providerMetadata: input.providerMetadata ?? {},\n createdAt: new Date(),\n };\n this.installationsRows.push(created);\n return created;\n },\n delete: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n const index = this.installationsRows.findIndex(row => row.orgId === orgId && row.id === id);\n if (index < 0) return false;\n this.installationsRows.splice(index, 1);\n return true;\n },\n };\n\n readonly repositories = {\n list: async ({ orgId, installationId }: { orgId: string; installationId: string }) => {\n const installation = await this.installations.get({ orgId, id: installationId });\n return installation ? this.repositoriesRows.filter(row => row.installationId === installationId) : [];\n },\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<SourceControlRepository | null> => {\n const row = this.repositoriesRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.installations.get({ orgId, id: row.installationId })) ? row : null;\n },\n findByExternalId: async ({\n orgId,\n installationId,\n externalId,\n }: {\n orgId: string;\n installationId: string;\n externalId: string;\n }) => {\n const rows = await this.repositories.list({ orgId, installationId });\n return rows.find(row => row.externalId === externalId) ?? null;\n },\n findBySlug: async ({ orgId, installationId, slug }: { orgId: string; installationId: string; slug: string }) => {\n const rows = await this.repositories.list({ orgId, installationId });\n return rows.find(row => row.slug === slug) ?? null;\n },\n upsert: async ({\n orgId,\n input,\n }: {\n orgId: string;\n input: UpsertSourceControlRepositoryInput;\n }): Promise<SourceControlRepository> => {\n if (!(await this.installations.get({ orgId, id: input.installationId }))) {\n throw new Error('Source-control installation not found');\n }\n const existing = this.repositoriesRows.find(\n row => row.installationId === input.installationId && row.externalId === input.externalId,\n );\n const now = new Date();\n if (existing) {\n Object.assign(existing, {\n slug: input.slug,\n defaultBranch: input.defaultBranch,\n providerMetadata: input.providerMetadata ?? {},\n updatedAt: now,\n });\n return existing;\n }\n const created: SourceControlRepository = {\n id: randomUUID(),\n installationId: input.installationId,\n externalId: input.externalId,\n slug: input.slug,\n defaultBranch: input.defaultBranch,\n providerMetadata: input.providerMetadata ?? {},\n createdAt: now,\n updatedAt: now,\n };\n this.repositoriesRows.push(created);\n return created;\n },\n };\n\n readonly connections = {\n list: async ({ factoryProjectId }: { orgId: string; factoryProjectId: string }) =>\n this.connectionsRows.filter(row => row.factoryProjectId === factoryProjectId),\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectSourceControlConnection | null> => {\n const row = this.connectionsRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.installations.get({ orgId, id: row.installationId })) ? row : null;\n },\n create: async (input: CreateProjectSourceControlConnectionInput): Promise<ProjectSourceControlConnection> => {\n if (!(await this.installations.get({ orgId: input.orgId, id: input.installationId }))) {\n throw new Error('Source-control installation not found');\n }\n const existing = this.connectionsRows.find(\n row =>\n row.factoryProjectId === input.factoryProjectId &&\n row.integrationId === this.integrationId &&\n row.installationId === input.installationId,\n );\n if (existing) return existing;\n const created: ProjectSourceControlConnection = {\n id: randomUUID(),\n factoryProjectId: input.factoryProjectId,\n integrationId: this.integrationId,\n installationId: input.installationId,\n createdByUserId: input.createdByUserId,\n createdAt: new Date(),\n };\n this.connectionsRows.push(created);\n return created;\n },\n delete: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n if (!(await this.connections.get({ orgId, id }))) return false;\n this.connectionsRows.splice(0, this.connectionsRows.length, ...this.connectionsRows.filter(row => row.id !== id));\n return true;\n },\n };\n\n readonly projectRepositories = {\n list: async ({ orgId, connectionId }: { orgId: string; connectionId: string }) =>\n (await this.connections.get({ orgId, id: connectionId }))\n ? this.projectRepositoriesRows.filter(row => row.connectionId === connectionId)\n : [],\n listConfiguredExternalKeys: async (): Promise<ConfiguredExternalRepositoryKey[]> => {\n const keys = new Map<string, ConfiguredExternalRepositoryKey>();\n for (const connection of this.connectionsRows.filter(row => row.integrationId === this.integrationId)) {\n const installation = this.installationsRows.find(row => row.id === connection.installationId);\n if (!installation) continue;\n for (const link of this.projectRepositoriesRows.filter(row => row.connectionId === connection.id)) {\n const repository = this.repositoriesRows.find(row => row.id === link.repositoryId);\n if (!repository) continue;\n keys.set(`${installation.externalId}\\u0000${repository.externalId}`, {\n installationExternalId: installation.externalId,\n repositoryExternalId: repository.externalId,\n });\n }\n }\n return [...keys.values()];\n },\n listByExternalRepository: async ({\n installationExternalId,\n repositoryExternalId,\n }: {\n installationExternalId: string;\n repositoryExternalId: string;\n }): Promise<ExternalRepositoryProjectTarget[]> => {\n const targets: ExternalRepositoryProjectTarget[] = [];\n for (const installation of this.installationsRows.filter(row => row.externalId === installationExternalId)) {\n const repository = this.repositoriesRows.find(\n row => row.installationId === installation.id && row.externalId === repositoryExternalId,\n );\n if (!repository) continue;\n for (const projectRepository of this.projectRepositoriesRows.filter(\n row => row.repositoryId === repository.id,\n )) {\n const connection = this.connectionsRows.find(\n row =>\n row.id === projectRepository.connectionId &&\n row.installationId === installation.id &&\n row.integrationId === this.integrationId,\n );\n if (!connection) continue;\n targets.push({\n orgId: installation.orgId,\n factoryProjectId: connection.factoryProjectId,\n projectRepository,\n });\n }\n }\n return targets;\n },\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectRepository | null> => {\n const row = this.projectRepositoriesRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.connections.get({ orgId, id: row.connectionId })) ? row : null;\n },\n link: async (input: LinkProjectRepositoryInput): Promise<ProjectRepository> => {\n const connection = await this.connections.get({ orgId: input.orgId, id: input.connectionId });\n const repository = await this.repositories.get({ orgId: input.orgId, id: input.repositoryId });\n if (!connection || !repository || repository.installationId !== connection.installationId) {\n throw new Error('Source-control connection or repository not found');\n }\n const existing = this.projectRepositoriesRows.find(\n row => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId,\n );\n if (existing) return existing;\n const now = new Date();\n const created: ProjectRepository = {\n id: randomUUID(),\n connectionId: input.connectionId,\n repositoryId: input.repositoryId,\n createdByUserId: input.createdByUserId,\n branch: input.branch ?? null,\n sandboxProvider: input.sandboxProvider,\n sandboxWorkdir: input.sandboxWorkdir,\n setupCommand: input.setupCommand ?? null,\n createdAt: now,\n updatedAt: now,\n };\n this.projectRepositoriesRows.push(created);\n return created;\n },\n update: async ({\n orgId,\n id,\n input,\n }: {\n orgId: string;\n id: string;\n input: UpdateProjectRepositoryInput;\n }): Promise<ProjectRepository | null> => {\n const row = await this.projectRepositories.get({ orgId, id });\n if (!row) return null;\n Object.assign(row, input, { updatedAt: new Date() });\n return row;\n },\n unlink: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n if (!(await this.projectRepositories.get({ orgId, id }))) return false;\n this.projectRepositoriesRows.splice(\n 0,\n this.projectRepositoriesRows.length,\n ...this.projectRepositoriesRows.filter(row => row.id !== id),\n );\n return true;\n },\n };\n\n readonly sandboxes = {\n getOrCreate: async ({\n projectRepository,\n userId,\n }: {\n projectRepository: ProjectRepository;\n userId: string;\n }): Promise<ProjectRepositorySandbox> => {\n const existing = this.sandboxesRows.find(\n row => row.projectRepositoryId === projectRepository.id && row.userId === userId,\n );\n if (existing) return existing;\n const created: ProjectRepositorySandbox = {\n id: randomUUID(),\n projectRepositoryId: projectRepository.id,\n userId,\n sandboxId: null,\n sandboxWorkdir: projectRepository.sandboxWorkdir,\n materializedAt: null,\n createdAt: new Date(),\n };\n this.sandboxesRows.push(created);\n return created;\n },\n getById: async ({ id }: { id: string }): Promise<ProjectRepositorySandbox | null> =>\n this.sandboxesRows.find(row => row.id === id) ?? null,\n setWorkdir: async ({ id, sandboxWorkdir }: { id: string; sandboxWorkdir: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxWorkdir, materializedAt: null });\n },\n setSandboxId: async ({ id, sandboxId }: { id: string; sandboxId: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) row.sandboxId = sandboxId;\n },\n clearBinding: async ({ id }: { id: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxId: null, materializedAt: null });\n },\n markMaterialized: async ({ id }: { id: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) row.materializedAt = new Date();\n },\n };\n\n readonly worktrees = {\n upsert: async (input: UpsertSourceControlWorktreeInput): Promise<void> => {\n const existing = this.worktreesRows.find(\n row =>\n row.projectRepositoryId === input.projectRepositoryId &&\n row.userId === input.userId &&\n row.branch === input.branch,\n );\n if (existing) {\n existing.baseBranch = input.baseBranch;\n existing.worktreePath = input.worktreePath;\n return;\n }\n this.worktreesRows.push({ id: randomUUID(), createdAt: new Date(), ...input });\n },\n list: async ({\n projectRepositoryId,\n userId,\n }: {\n projectRepositoryId: string;\n userId: string;\n }): Promise<SourceControlWorktree[]> =>\n this.worktreesRows.filter(row => row.projectRepositoryId === projectRepositoryId && row.userId === userId),\n get: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlWorktree | null> =>\n this.worktreesRows.find(\n row => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch,\n ) ?? null,\n findByPath: async ({\n projectRepositoryId,\n userId,\n worktreePath,\n }: {\n projectRepositoryId: string;\n userId: string;\n worktreePath: string;\n }): Promise<SourceControlWorktree | null> =>\n this.worktreesRows.find(\n row =>\n row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.worktreePath === worktreePath,\n ) ?? null,\n delete: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<void> => {\n this.worktreesRows.splice(\n 0,\n this.worktreesRows.length,\n ...this.worktreesRows.filter(\n row => !(row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch),\n ),\n );\n },\n };\n\n readonly sessions = {\n list: async ({ projectRepositoryId, userId }: { projectRepositoryId: string; userId: string }) =>\n this.sessionsRows.filter(row => row.projectRepositoryId === projectRepositoryId && row.userId === userId),\n getBySessionId: async (sessionId: string): Promise<SourceControlSession | null> =>\n this.sessionsRows.find(row => row.sessionId === sessionId) ?? null,\n getForBranch: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlSession | null> =>\n this.sessionsRows.find(\n row => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch,\n ) ?? null,\n create: async (input: CreateSourceControlSessionInput): Promise<SourceControlSession> => {\n const existing = await this.sessions.getForBranch(input);\n if (existing) return existing;\n const now = new Date();\n const session: SourceControlSession = {\n id: randomUUID(),\n ...input,\n sandboxId: null,\n sandboxWorkdir: null,\n materializedAt: null,\n createdAt: now,\n updatedAt: now,\n };\n this.sessionsRows.push(session);\n return session;\n },\n setSandbox: async ({\n id,\n sandboxId,\n sandboxWorkdir,\n }: {\n id: string;\n sandboxId: string | null;\n sandboxWorkdir: string;\n }) => {\n const row = this.sessionsRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxId, sandboxWorkdir, updatedAt: new Date() });\n },\n markMaterialized: async ({ id }: { id: string }) => {\n const row = this.sessionsRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { materializedAt: new Date(), updatedAt: new Date() });\n },\n delete: async (id: string) => {\n this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter(row => row.id !== id));\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"inmemory.js","names":[],"sources":["../../../../src/storage/domains/source-control/inmemory.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n ConfiguredExternalRepositoryKey,\n CreateProjectSourceControlConnectionInput,\n CreateSourceControlSessionInput,\n ExternalRepositoryProjectTarget,\n LinkProjectRepositoryInput,\n ProjectRepository,\n ProjectRepositorySandbox,\n ProjectSourceControlConnection,\n SourceControlInstallation,\n SourceControlRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n SourceControlWorktree,\n UpdateProjectRepositoryInput,\n UpsertSourceControlInstallationInput,\n UpsertSourceControlRepositoryInput,\n UpsertSourceControlWorktreeInput,\n} from './base.js';\n\n/** In-memory provider-scoped source-control handle for route tests. */\nexport class SourceControlStorageInMemory implements SourceControlStorageHandle {\n readonly integrationId: string;\n installationsRows: SourceControlInstallation[] = [];\n repositoriesRows: SourceControlRepository[] = [];\n connectionsRows: ProjectSourceControlConnection[] = [];\n projectRepositoriesRows: ProjectRepository[] = [];\n sandboxesRows: ProjectRepositorySandbox[] = [];\n worktreesRows: SourceControlWorktree[] = [];\n sessionsRows: SourceControlSession[] = [];\n\n constructor(integrationId = 'github') {\n this.integrationId = integrationId;\n }\n\n readonly installations = {\n list: async ({ orgId }: { orgId: string }): Promise<SourceControlInstallation[]> =>\n this.installationsRows.filter(row => row.orgId === orgId),\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<SourceControlInstallation | null> =>\n this.installationsRows.find(row => row.orgId === orgId && row.id === id) ?? null,\n findByExternalId: async ({\n orgId,\n externalId,\n }: {\n orgId: string;\n externalId: string;\n }): Promise<SourceControlInstallation | null> =>\n this.installationsRows.find(row => row.orgId === orgId && row.externalId === externalId) ?? null,\n upsert: async (input: UpsertSourceControlInstallationInput): Promise<SourceControlInstallation> => {\n const existing = this.installationsRows.find(\n row => row.orgId === input.orgId && row.externalId === input.externalId,\n );\n if (existing) {\n Object.assign(existing, {\n connectedByUserId: input.connectedByUserId,\n accountName: input.accountName ?? null,\n accountType: input.accountType ?? null,\n providerMetadata: input.providerMetadata ?? {},\n });\n return existing;\n }\n const created: SourceControlInstallation = {\n id: randomUUID(),\n integrationId: this.integrationId,\n orgId: input.orgId,\n connectedByUserId: input.connectedByUserId,\n externalId: input.externalId,\n accountName: input.accountName ?? null,\n accountType: input.accountType ?? null,\n providerMetadata: input.providerMetadata ?? {},\n createdAt: new Date(),\n };\n this.installationsRows.push(created);\n return created;\n },\n delete: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n const index = this.installationsRows.findIndex(row => row.orgId === orgId && row.id === id);\n if (index < 0) return false;\n this.installationsRows.splice(index, 1);\n return true;\n },\n };\n\n readonly repositories = {\n list: async ({ orgId, installationId }: { orgId: string; installationId: string }) => {\n const installation = await this.installations.get({ orgId, id: installationId });\n return installation ? this.repositoriesRows.filter(row => row.installationId === installationId) : [];\n },\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<SourceControlRepository | null> => {\n const row = this.repositoriesRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.installations.get({ orgId, id: row.installationId })) ? row : null;\n },\n findByExternalId: async ({\n orgId,\n installationId,\n externalId,\n }: {\n orgId: string;\n installationId: string;\n externalId: string;\n }) => {\n const rows = await this.repositories.list({ orgId, installationId });\n return rows.find(row => row.externalId === externalId) ?? null;\n },\n findBySlug: async ({ orgId, installationId, slug }: { orgId: string; installationId: string; slug: string }) => {\n const rows = await this.repositories.list({ orgId, installationId });\n return rows.find(row => row.slug === slug) ?? null;\n },\n upsert: async ({\n orgId,\n input,\n }: {\n orgId: string;\n input: UpsertSourceControlRepositoryInput;\n }): Promise<SourceControlRepository> => {\n if (!(await this.installations.get({ orgId, id: input.installationId }))) {\n throw new Error('Source-control installation not found');\n }\n const existing = this.repositoriesRows.find(\n row => row.installationId === input.installationId && row.externalId === input.externalId,\n );\n const now = new Date();\n if (existing) {\n Object.assign(existing, {\n slug: input.slug,\n defaultBranch: input.defaultBranch,\n providerMetadata: input.providerMetadata ?? {},\n updatedAt: now,\n });\n return existing;\n }\n const created: SourceControlRepository = {\n id: randomUUID(),\n installationId: input.installationId,\n externalId: input.externalId,\n slug: input.slug,\n defaultBranch: input.defaultBranch,\n providerMetadata: input.providerMetadata ?? {},\n createdAt: now,\n updatedAt: now,\n };\n this.repositoriesRows.push(created);\n return created;\n },\n migrateInstallation: async ({\n orgId,\n id,\n newInstallationId,\n }: {\n orgId: string;\n id: string;\n newInstallationId: string;\n }) => {\n const existing = await this.repositories.get({ orgId, id });\n if (!existing) {\n throw new Error(`Repository ${id} not found in organization ${orgId}`);\n }\n if (!(await this.installations.get({ orgId, id: newInstallationId }))) {\n throw new Error('Source-control installation not found');\n }\n // Check if a repository with the same external_id exists under the new installation\n const conflict = this.repositoriesRows.find(\n row => row.installationId === newInstallationId && row.externalId === existing.externalId,\n );\n if (conflict) {\n // Return the existing repository under the new installation\n return conflict;\n }\n // Update the repository's installation\n existing.installationId = newInstallationId;\n existing.updatedAt = new Date();\n // Migrate dependent connections to the new installation\n for (const conn of this.connectionsRows) {\n if (conn.installationId === existing.installationId) {\n conn.installationId = newInstallationId;\n }\n }\n return existing;\n },\n };\n\n readonly connections = {\n list: async ({ factoryProjectId }: { orgId: string; factoryProjectId: string }) =>\n this.connectionsRows.filter(row => row.factoryProjectId === factoryProjectId),\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectSourceControlConnection | null> => {\n const row = this.connectionsRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.installations.get({ orgId, id: row.installationId })) ? row : null;\n },\n create: async (input: CreateProjectSourceControlConnectionInput): Promise<ProjectSourceControlConnection> => {\n if (!(await this.installations.get({ orgId: input.orgId, id: input.installationId }))) {\n throw new Error('Source-control installation not found');\n }\n const existing = this.connectionsRows.find(\n row =>\n row.factoryProjectId === input.factoryProjectId &&\n row.integrationId === this.integrationId &&\n row.installationId === input.installationId,\n );\n if (existing) return existing;\n const created: ProjectSourceControlConnection = {\n id: randomUUID(),\n factoryProjectId: input.factoryProjectId,\n integrationId: this.integrationId,\n installationId: input.installationId,\n createdByUserId: input.createdByUserId,\n createdAt: new Date(),\n };\n this.connectionsRows.push(created);\n return created;\n },\n delete: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n if (!(await this.connections.get({ orgId, id }))) return false;\n this.connectionsRows.splice(0, this.connectionsRows.length, ...this.connectionsRows.filter(row => row.id !== id));\n return true;\n },\n };\n\n readonly projectRepositories = {\n list: async ({ orgId, connectionId }: { orgId: string; connectionId: string }) =>\n (await this.connections.get({ orgId, id: connectionId }))\n ? this.projectRepositoriesRows.filter(row => row.connectionId === connectionId)\n : [],\n listConfiguredExternalKeys: async (): Promise<ConfiguredExternalRepositoryKey[]> => {\n const keys = new Map<string, ConfiguredExternalRepositoryKey>();\n for (const connection of this.connectionsRows.filter(row => row.integrationId === this.integrationId)) {\n const installation = this.installationsRows.find(row => row.id === connection.installationId);\n if (!installation) continue;\n for (const link of this.projectRepositoriesRows.filter(row => row.connectionId === connection.id)) {\n const repository = this.repositoriesRows.find(row => row.id === link.repositoryId);\n if (!repository) continue;\n keys.set(`${installation.externalId}\\u0000${repository.externalId}`, {\n installationExternalId: installation.externalId,\n repositoryExternalId: repository.externalId,\n });\n }\n }\n return [...keys.values()];\n },\n listByExternalRepository: async ({\n installationExternalId,\n repositoryExternalId,\n }: {\n installationExternalId: string;\n repositoryExternalId: string;\n }): Promise<ExternalRepositoryProjectTarget[]> => {\n const targets: ExternalRepositoryProjectTarget[] = [];\n for (const installation of this.installationsRows.filter(row => row.externalId === installationExternalId)) {\n const repository = this.repositoriesRows.find(\n row => row.installationId === installation.id && row.externalId === repositoryExternalId,\n );\n if (!repository) continue;\n for (const projectRepository of this.projectRepositoriesRows.filter(\n row => row.repositoryId === repository.id,\n )) {\n const connection = this.connectionsRows.find(\n row =>\n row.id === projectRepository.connectionId &&\n row.installationId === installation.id &&\n row.integrationId === this.integrationId,\n );\n if (!connection) continue;\n targets.push({\n orgId: installation.orgId,\n factoryProjectId: connection.factoryProjectId,\n projectRepository,\n });\n }\n }\n return targets;\n },\n get: async ({ orgId, id }: { orgId: string; id: string }): Promise<ProjectRepository | null> => {\n const row = this.projectRepositoriesRows.find(candidate => candidate.id === id);\n if (!row) return null;\n return (await this.connections.get({ orgId, id: row.connectionId })) ? row : null;\n },\n link: async (input: LinkProjectRepositoryInput): Promise<ProjectRepository> => {\n const connection = await this.connections.get({ orgId: input.orgId, id: input.connectionId });\n const repository = await this.repositories.get({ orgId: input.orgId, id: input.repositoryId });\n if (!connection || !repository || repository.installationId !== connection.installationId) {\n throw new Error('Source-control connection or repository not found');\n }\n const existing = this.projectRepositoriesRows.find(\n row => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId,\n );\n if (existing) return existing;\n const now = new Date();\n const created: ProjectRepository = {\n id: randomUUID(),\n connectionId: input.connectionId,\n repositoryId: input.repositoryId,\n createdByUserId: input.createdByUserId,\n branch: input.branch ?? null,\n sandboxProvider: input.sandboxProvider,\n sandboxWorkdir: input.sandboxWorkdir,\n setupCommand: input.setupCommand ?? null,\n createdAt: now,\n updatedAt: now,\n };\n this.projectRepositoriesRows.push(created);\n return created;\n },\n update: async ({\n orgId,\n id,\n input,\n }: {\n orgId: string;\n id: string;\n input: UpdateProjectRepositoryInput;\n }): Promise<ProjectRepository | null> => {\n const row = await this.projectRepositories.get({ orgId, id });\n if (!row) return null;\n Object.assign(row, input, { updatedAt: new Date() });\n return row;\n },\n unlink: async ({ orgId, id }: { orgId: string; id: string }): Promise<boolean> => {\n if (!(await this.projectRepositories.get({ orgId, id }))) return false;\n this.projectRepositoriesRows.splice(\n 0,\n this.projectRepositoriesRows.length,\n ...this.projectRepositoriesRows.filter(row => row.id !== id),\n );\n return true;\n },\n };\n\n readonly sandboxes = {\n getOrCreate: async ({\n projectRepository,\n userId,\n }: {\n projectRepository: ProjectRepository;\n userId: string;\n }): Promise<ProjectRepositorySandbox> => {\n const existing = this.sandboxesRows.find(\n row => row.projectRepositoryId === projectRepository.id && row.userId === userId,\n );\n if (existing) return existing;\n const created: ProjectRepositorySandbox = {\n id: randomUUID(),\n projectRepositoryId: projectRepository.id,\n userId,\n sandboxId: null,\n sandboxWorkdir: projectRepository.sandboxWorkdir,\n materializedAt: null,\n createdAt: new Date(),\n };\n this.sandboxesRows.push(created);\n return created;\n },\n getById: async ({ id }: { id: string }): Promise<ProjectRepositorySandbox | null> =>\n this.sandboxesRows.find(row => row.id === id) ?? null,\n setWorkdir: async ({ id, sandboxWorkdir }: { id: string; sandboxWorkdir: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxWorkdir, materializedAt: null });\n },\n setSandboxId: async ({ id, sandboxId }: { id: string; sandboxId: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) row.sandboxId = sandboxId;\n },\n clearBinding: async ({ id }: { id: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxId: null, materializedAt: null });\n },\n markMaterialized: async ({ id }: { id: string }): Promise<void> => {\n const row = this.sandboxesRows.find(candidate => candidate.id === id);\n if (row) row.materializedAt = new Date();\n },\n };\n\n readonly worktrees = {\n upsert: async (input: UpsertSourceControlWorktreeInput): Promise<void> => {\n const existing = this.worktreesRows.find(\n row =>\n row.projectRepositoryId === input.projectRepositoryId &&\n row.userId === input.userId &&\n row.branch === input.branch,\n );\n if (existing) {\n existing.baseBranch = input.baseBranch;\n existing.worktreePath = input.worktreePath;\n return;\n }\n this.worktreesRows.push({ id: randomUUID(), createdAt: new Date(), ...input });\n },\n list: async ({\n projectRepositoryId,\n userId,\n }: {\n projectRepositoryId: string;\n userId: string;\n }): Promise<SourceControlWorktree[]> =>\n this.worktreesRows.filter(row => row.projectRepositoryId === projectRepositoryId && row.userId === userId),\n get: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlWorktree | null> =>\n this.worktreesRows.find(\n row => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch,\n ) ?? null,\n findByPath: async ({\n projectRepositoryId,\n userId,\n worktreePath,\n }: {\n projectRepositoryId: string;\n userId: string;\n worktreePath: string;\n }): Promise<SourceControlWorktree | null> =>\n this.worktreesRows.find(\n row =>\n row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.worktreePath === worktreePath,\n ) ?? null,\n delete: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<void> => {\n this.worktreesRows.splice(\n 0,\n this.worktreesRows.length,\n ...this.worktreesRows.filter(\n row => !(row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch),\n ),\n );\n },\n };\n\n readonly sessions = {\n list: async ({ projectRepositoryId, userId }: { projectRepositoryId: string; userId: string }) =>\n this.sessionsRows.filter(row => row.projectRepositoryId === projectRepositoryId && row.userId === userId),\n getBySessionId: async (sessionId: string): Promise<SourceControlSession | null> =>\n this.sessionsRows.find(row => row.sessionId === sessionId) ?? null,\n getForBranch: async ({\n projectRepositoryId,\n userId,\n branch,\n }: {\n projectRepositoryId: string;\n userId: string;\n branch: string;\n }): Promise<SourceControlSession | null> =>\n this.sessionsRows.find(\n row => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch,\n ) ?? null,\n create: async (input: CreateSourceControlSessionInput): Promise<SourceControlSession> => {\n const existing = await this.sessions.getForBranch(input);\n if (existing) return existing;\n const now = new Date();\n const session: SourceControlSession = {\n id: randomUUID(),\n ...input,\n sandboxId: null,\n sandboxWorkdir: null,\n materializedAt: null,\n createdAt: now,\n updatedAt: now,\n };\n this.sessionsRows.push(session);\n return session;\n },\n setSandbox: async ({\n id,\n sandboxId,\n sandboxWorkdir,\n }: {\n id: string;\n sandboxId: string | null;\n sandboxWorkdir: string;\n }) => {\n const row = this.sessionsRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { sandboxId, sandboxWorkdir, updatedAt: new Date() });\n },\n markMaterialized: async ({ id }: { id: string }) => {\n const row = this.sessionsRows.find(candidate => candidate.id === id);\n if (row) Object.assign(row, { materializedAt: new Date(), updatedAt: new Date() });\n },\n delete: async (id: string) => {\n this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter(row => row.id !== id));\n },\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/factory",
3
- "version": "0.2.2",
3
+ "version": "0.2.3-alpha.0",
4
4
  "description": "Mastra Software Factory module: the server core behind the Mastra Software Factory — storage domains, integrations, and surfaces for agent-powered software delivery",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -52,8 +52,8 @@
52
52
  "zod": "^4.3.6",
53
53
  "@mastra/auth-studio": "1.3.3",
54
54
  "@mastra/auth-workos": "1.6.4",
55
- "@mastra/code-sdk": "1.1.0",
56
- "@mastra/core": "1.54.0"
55
+ "@mastra/code-sdk": "1.1.1-alpha.0",
56
+ "@mastra/core": "1.55.0-alpha.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/node": "22.20.1",