@mastra/factory 0.21.1-alpha.3 → 0.22.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/capabilities/version-control.d.ts +13 -8
  2. package/dist/capabilities/version-control.d.ts.map +1 -1
  3. package/dist/environment/build-runner.d.ts +72 -0
  4. package/dist/environment/build-runner.d.ts.map +1 -0
  5. package/dist/environment/build-runner.js +131 -0
  6. package/dist/environment/build-runner.js.map +1 -0
  7. package/dist/environment/build-schedule.d.ts +40 -0
  8. package/dist/environment/build-schedule.d.ts.map +1 -0
  9. package/dist/environment/build-schedule.js +94 -0
  10. package/dist/environment/build-schedule.js.map +1 -0
  11. package/dist/environment/build-workflow.d.ts +62 -0
  12. package/dist/environment/build-workflow.d.ts.map +1 -0
  13. package/dist/environment/build-workflow.js +149 -0
  14. package/dist/environment/build-workflow.js.map +1 -0
  15. package/dist/environment/build.d.ts +111 -0
  16. package/dist/environment/build.d.ts.map +1 -0
  17. package/dist/environment/build.js +344 -0
  18. package/dist/environment/build.js.map +1 -0
  19. package/dist/environment/heads.d.ts +36 -0
  20. package/dist/environment/heads.d.ts.map +1 -0
  21. package/dist/environment/heads.js +60 -0
  22. package/dist/environment/heads.js.map +1 -0
  23. package/dist/factory.d.ts +18 -4
  24. package/dist/factory.d.ts.map +1 -1
  25. package/dist/factory.js +89 -15
  26. package/dist/factory.js.map +1 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -2
  30. package/dist/integrations/base.d.ts +17 -2
  31. package/dist/integrations/base.d.ts.map +1 -1
  32. package/dist/integrations/github/commits.d.ts +11 -0
  33. package/dist/integrations/github/commits.d.ts.map +1 -1
  34. package/dist/integrations/github/commits.js +20 -1
  35. package/dist/integrations/github/commits.js.map +1 -1
  36. package/dist/integrations/github/config.d.ts +3 -3
  37. package/dist/integrations/github/config.d.ts.map +1 -1
  38. package/dist/integrations/github/config.js +1 -1
  39. package/dist/integrations/github/config.js.map +1 -1
  40. package/dist/integrations/github/routes.d.ts +2 -2
  41. package/dist/integrations/github/routes.d.ts.map +1 -1
  42. package/dist/integrations/github/routes.js +6 -5
  43. package/dist/integrations/github/routes.js.map +1 -1
  44. package/dist/integrations/github/rules.d.ts +3 -1
  45. package/dist/integrations/github/rules.d.ts.map +1 -1
  46. package/dist/integrations/github/rules.js +31 -1
  47. package/dist/integrations/github/rules.js.map +1 -1
  48. package/dist/integrations/github/sandbox.d.ts +35 -0
  49. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  50. package/dist/integrations/github/sandbox.js +203 -2
  51. package/dist/integrations/github/sandbox.js.map +1 -1
  52. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
  53. package/dist/integrations/github/session-subscriptions.js +117 -62
  54. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  55. package/dist/integrations/github/token-refresh.d.ts +7 -0
  56. package/dist/integrations/github/token-refresh.d.ts.map +1 -1
  57. package/dist/integrations/github/token-refresh.js.map +1 -1
  58. package/dist/integrations/github/webhook.js.map +1 -1
  59. package/dist/integrations/gitlab/agent-tools.js +1 -1
  60. package/dist/integrations/gitlab/routes.d.ts +2 -2
  61. package/dist/integrations/gitlab/routes.d.ts.map +1 -1
  62. package/dist/integrations/gitlab/routes.js.map +1 -1
  63. package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -1
  64. package/dist/integrations/gitlab/session-subscriptions.js +8 -7
  65. package/dist/integrations/gitlab/session-subscriptions.js.map +1 -1
  66. package/dist/integrations/incidentio/agent-tools.js +1 -1
  67. package/dist/integrations/jira/agent-tools.js +1 -1
  68. package/dist/integrations/linear/agent-tools.js +1 -1
  69. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  70. package/dist/integrations/platform/github/integration.js +46 -2
  71. package/dist/integrations/platform/github/integration.js.map +1 -1
  72. package/dist/integrations/platform/jira/agent-tools.js +1 -1
  73. package/dist/integrations/slack/slack.d.ts.map +1 -1
  74. package/dist/integrations/slack/slack.js +15 -16
  75. package/dist/integrations/slack/slack.js.map +1 -1
  76. package/dist/integrations/subscription-session.js +1 -1
  77. package/dist/packages/_internals/workspace/dist/index.js +21 -1
  78. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  79. package/dist/routes/contracts.d.ts +386 -2
  80. package/dist/routes/contracts.d.ts.map +1 -1
  81. package/dist/routes/contracts.js +166 -1
  82. package/dist/routes/contracts.js.map +1 -1
  83. package/dist/routes/fs.d.ts +25 -0
  84. package/dist/routes/fs.d.ts.map +1 -1
  85. package/dist/routes/fs.js +142 -46
  86. package/dist/routes/fs.js.map +1 -1
  87. package/dist/routes/projects.d.ts +6 -0
  88. package/dist/routes/projects.d.ts.map +1 -1
  89. package/dist/routes/projects.js +344 -1
  90. package/dist/routes/projects.js.map +1 -1
  91. package/dist/routes/source-control-sessions.d.ts +2 -0
  92. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  93. package/dist/routes/source-control-sessions.js +36 -1
  94. package/dist/routes/source-control-sessions.js.map +1 -1
  95. package/dist/routes/supervisor.js +1 -1
  96. package/dist/routes/surface.d.ts +6 -3
  97. package/dist/routes/surface.d.ts.map +1 -1
  98. package/dist/routes/surface.js +21 -34
  99. package/dist/routes/surface.js.map +1 -1
  100. package/dist/rules/binding-context.d.ts +1 -1
  101. package/dist/rules/binding-context.d.ts.map +1 -1
  102. package/dist/rules/binding-context.js +1 -1
  103. package/dist/rules/binding-context.js.map +1 -1
  104. package/dist/rules/review-source-tool.js +1 -1
  105. package/dist/rules/start-coordinator.d.ts.map +1 -1
  106. package/dist/rules/start-coordinator.js +7 -2
  107. package/dist/rules/start-coordinator.js.map +1 -1
  108. package/dist/rules/tools.js +1 -1
  109. package/dist/sandbox/callback-factory-sandbox.d.ts +15 -0
  110. package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -0
  111. package/dist/sandbox/callback-factory-sandbox.js +22 -0
  112. package/dist/sandbox/callback-factory-sandbox.js.map +1 -0
  113. package/dist/sandbox/local-factory-sandbox.d.ts +20 -0
  114. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -0
  115. package/dist/sandbox/local-factory-sandbox.js +27 -0
  116. package/dist/sandbox/local-factory-sandbox.js.map +1 -0
  117. package/dist/sandbox/session-retirement.d.ts.map +1 -1
  118. package/dist/sandbox/session-retirement.js +23 -3
  119. package/dist/sandbox/session-retirement.js.map +1 -1
  120. package/dist/sandbox/session-sandbox.d.ts +82 -40
  121. package/dist/sandbox/session-sandbox.d.ts.map +1 -1
  122. package/dist/sandbox/session-sandbox.js +130 -13
  123. package/dist/sandbox/session-sandbox.js.map +1 -1
  124. package/dist/sandbox/workdir.d.ts +10 -0
  125. package/dist/sandbox/workdir.d.ts.map +1 -1
  126. package/dist/sandbox/workdir.js +10 -1
  127. package/dist/sandbox/workdir.js.map +1 -1
  128. package/dist/session/environment-repositories.d.ts +31 -0
  129. package/dist/session/environment-repositories.d.ts.map +1 -0
  130. package/dist/session/environment-repositories.js +89 -0
  131. package/dist/session/environment-repositories.js.map +1 -0
  132. package/dist/session/environment-state-processor.d.ts +59 -0
  133. package/dist/session/environment-state-processor.d.ts.map +1 -0
  134. package/dist/session/environment-state-processor.js +105 -0
  135. package/dist/session/environment-state-processor.js.map +1 -0
  136. package/dist/session/factory-session.d.ts +26 -35
  137. package/dist/session/factory-session.d.ts.map +1 -1
  138. package/dist/session/factory-session.js +34 -71
  139. package/dist/session/factory-session.js.map +1 -1
  140. package/dist/session/filesystem-capture.d.ts +13 -0
  141. package/dist/session/filesystem-capture.d.ts.map +1 -1
  142. package/dist/session/filesystem-capture.js +73 -14
  143. package/dist/session/filesystem-capture.js.map +1 -1
  144. package/dist/session/source-control-tools.d.ts +1 -1
  145. package/dist/session/source-control-tools.d.ts.map +1 -1
  146. package/dist/session/source-control-tools.js +144 -71
  147. package/dist/session/source-control-tools.js.map +1 -1
  148. package/dist/spa-static.js +2 -2
  149. package/dist/storage/domains/audit/agent-audit.d.ts +6 -1
  150. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -1
  151. package/dist/storage/domains/audit/agent-audit.js +31 -13
  152. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  153. package/dist/storage/domains/projects/base.d.ts +115 -2
  154. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  155. package/dist/storage/domains/projects/base.js +219 -12
  156. package/dist/storage/domains/projects/base.js.map +1 -1
  157. package/dist/storage/domains/source-control/base.d.ts +123 -7
  158. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  159. package/dist/storage/domains/source-control/base.js +406 -33
  160. package/dist/storage/domains/source-control/base.js.map +1 -1
  161. package/dist/storage/domains/source-control/inmemory.d.ts +19 -6
  162. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  163. package/dist/storage/domains/source-control/inmemory.js +90 -2
  164. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  165. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  166. package/dist/storage/domains/work-items/base.js +12 -5
  167. package/dist/storage/domains/work-items/base.js.map +1 -1
  168. package/dist/supervisor/read-tools.js +1 -1
  169. package/dist/supervisor/write-tools.js +1 -1
  170. package/dist/workspace.d.ts +50 -7
  171. package/dist/workspace.d.ts.map +1 -1
  172. package/dist/workspace.js +344 -24
  173. package/dist/workspace.js.map +1 -1
  174. package/package.json +7 -7
@@ -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 SESSIONS = 'source_control_sessions';\n\nexport class SourceControlConnectionNotFoundError extends Error {\n constructor() {\n super('Project source-control connection not found for this organization and integration.');\n this.name = 'SourceControlConnectionNotFoundError';\n }\n}\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 teardown_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: 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 title: { type: 'text', nullable: true },\n visibility: { type: 'text', nullable: true },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text', nullable: true },\n materialized_at: { type: 'timestamp', nullable: true },\n first_message_at: { type: 'timestamp', nullable: true },\n first_meaningful_exec_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 teardownCommand: 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 teardownCommand?: string | null;\n}\n\nexport interface UpdateProjectRepositoryInput {\n branch?: string | null;\n sandboxProvider?: string;\n sandboxWorkdir?: string;\n setupCommand?: string | null;\n teardownCommand?: string | null;\n}\n\n/**\n * Who can open a session: 'org' sessions are visible to every member of the\n * owning organization, 'private' sessions only to their owner. Stored at\n * creation; rows created before the column existed read as 'org'.\n */\nexport type SourceControlSessionVisibility = 'org' | 'private';\n\nexport interface SourceControlSession {\n id: string;\n sessionId: string;\n projectRepositoryId: string;\n orgId: string;\n userId: string;\n branch: string;\n title: string | null;\n visibility: SourceControlSessionVisibility;\n baseBranch: string;\n sandboxId: string | null;\n sandboxWorkdir: string | null;\n materializedAt: Date | null;\n /** When the first user message reached the session's agent. Write-once. */\n firstMessageAt: Date | null;\n /** When the agent's first successful sandbox exec finished. Write-once. */\n firstMeaningfulExecAt: 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 title?: string | null;\n /** Defaults to 'org' when omitted, matching how NULL rows are read. */\n visibility?: SourceControlSessionVisibility;\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 sessions: {\n /**\n * Viewer-aware listing: every org-visible session for the repository\n * (regardless of owner) plus the viewer's own private sessions.\n */\n list(args: { projectRepositoryId: string; viewerUserId: string }): Promise<SourceControlSession[]>;\n /**\n * System-level listing of every session for the repository regardless of\n * visibility. For internal flows only (session retirement, repository\n * teardown); never expose directly to a viewer.\n */\n listByProjectRepository(args: { projectRepositoryId: string }): Promise<SourceControlSession[]>;\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n /** Overwrite the session's display title. Keyed by the controller-facing `sessionId`. */\n rename(args: { sessionId: string; title: string }): Promise<void>;\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 /**\n * Record when the session's workspace was first materialized. Write-once:\n * the guarded update only lands while the column is still NULL, so resumes\n * (Railway idle-reap, checkpoint restore, sandbox recreate) do not overwrite\n * the initial-materialize baseline that `materialize_s = materialized_at -\n * created_at` depends on.\n */\n markMaterialized(args: { id: string }): Promise<void>;\n /**\n * Record when the session's agent received its first user message.\n * Write-once: the guarded update only lands while the column is still\n * NULL, so retries and process restarts are no-ops. Keyed by the\n * controller-facing `sessionId` (not the row id) because the caller —\n * the session observer — only knows the controller resourceId.\n */\n markFirstMessage(args: { sessionId: string }): Promise<void>;\n /**\n * Record when the session's agent completed its first successful sandbox\n * exec (TTFME anchor). Same write-once contract as `markFirstMessage`:\n * guarded on the column being NULL, keyed by the controller-facing\n * `sessionId`.\n */\n markFirstMeaningfulExec(args: { sessionId: 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 teardown_command: string | null;\n created_at: Date;\n updated_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 title: string | null;\n visibility: string | null;\n base_branch: string;\n sandbox_id: string | null;\n sandbox_workdir: string | null;\n materialized_at: Date | null;\n first_message_at: Date | null;\n first_meaningful_exec_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 teardownCommand: row.teardown_command,\n createdAt: row.created_at,\n updatedAt: row.updated_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 title: row.title,\n visibility: row.visibility === 'private' ? 'private' : 'org',\n baseBranch: row.base_branch,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n firstMessageAt: row.first_message_at,\n firstMeaningfulExecAt: row.first_meaningful_exec_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(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) throw new SourceControlConnectionNotFoundError();\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 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 }\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 try {\n const row = await db().insertOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\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 teardown_command: input.teardownCommand ?? null,\n created_at: now,\n updated_at: now,\n });\n return toProjectRepository(row);\n } catch (error) {\n // Match the in-memory handle: return the existing row unchanged on\n // a unique-constraint race.\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: input.connectionId,\n repository_id: input.repositoryId,\n });\n if (!row) throw error;\n return toProjectRepository(row);\n }\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 if (input.teardownCommand !== undefined) patch.teardown_command = input.teardownCommand;\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(PROJECT_REPOSITORIES, { id });\n return true;\n },\n },\n sessions: {\n list: async ({ projectRepositoryId, viewerUserId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n const rows = await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n });\n // Org-visible sessions (NULL counts as org) plus the viewer's own.\n return rows.filter(row => row.visibility !== 'private' || row.user_id === viewerUserId).map(toSession);\n },\n listByProjectRepository: async ({ projectRepositoryId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n return (\n await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\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 rename: async ({ sessionId, title }) => {\n await db().updateAtomic<SessionDbRow>(SESSIONS, { session_id: sessionId }, () => ({\n title,\n updated_at: new Date(),\n }));\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 title: input.title ?? null,\n visibility: input.visibility ?? 'org',\n base_branch: input.baseBranch,\n sandbox_id: null,\n sandbox_workdir: null,\n materialized_at: null,\n first_message_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 // `materialized_at: null` in the filter compiles to `IS NULL`, making\n // this a write-once update: session resumes (idle-reap, checkpoint\n // restore, sandbox recreate) match zero rows and cannot overwrite the\n // initial-materialize timestamp that `materialize_s` is derived from.\n await db().updateMany(\n SESSIONS,\n { id, materialized_at: null },\n { materialized_at: new Date(), updated_at: new Date() },\n );\n },\n markFirstMessage: async ({ sessionId }) => {\n // `first_message_at: null` in the filter compiles to `IS NULL`, making\n // this an atomic one-shot: concurrent callers and later messages\n // match zero rows. Sessions without a source-control row (chat-only\n // channels) are a zero-row no-op too.\n await db().updateMany(\n SESSIONS,\n { session_id: sessionId, first_message_at: null },\n { first_message_at: new Date(), updated_at: new Date() },\n );\n },\n markFirstMeaningfulExec: async ({ sessionId }) => {\n // Same atomic one-shot shape as markFirstMessage: the NULL filter\n // makes concurrent callers and later execs zero-row no-ops.\n await db().updateMany(\n SESSIONS,\n { session_id: sessionId, first_meaningful_exec_at: null },\n { first_meaningful_exec_at: new Date(), updated_at: new Date() },\n );\n },\n delete: async id => {\n await db().deleteMany(SESSIONS, { id });\n },\n },\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base.js","names":["#backfillEnvironment","#backfillSessionFactory"],"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\nimport { FACTORY_PROJECTS_SCHEMA } from '../projects/base.js';\n\nconst FACTORY_PROJECTS = 'factory_projects';\n\nconst INSTALLATIONS = 'source_control_installations';\nconst REPOSITORIES = 'source_control_repositories';\nconst CONNECTIONS = 'factory_project_source_control_connections';\nconst PROJECT_REPOSITORIES = 'factory_project_repositories';\nconst SESSIONS = 'source_control_sessions';\nconst SESSION_REPOSITORIES = 'source_control_session_repositories';\n\n/**\n * The user already holds the branch on this link in a session without this\n * factory's ownership, left by the factory migration. It is never reused and\n * cannot be replaced while it holds the branch.\n */\nexport class SessionOwnershipMismatchError extends Error {\n constructor(readonly sessionId: string) {\n super(`Session ${sessionId} already holds this branch but does not belong to this factory.`);\n this.name = 'SessionOwnershipMismatchError';\n }\n}\n\nexport class SourceControlConnectionNotFoundError extends Error {\n constructor() {\n super('Project source-control connection not found for this organization and integration.');\n this.name = 'SourceControlConnectionNotFoundError';\n }\n}\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 teardown_command: { type: 'text', nullable: true },\n position: { type: 'integer', default: 0 },\n in_environment: { type: 'boolean', default: true },\n last_build_status: { type: 'text', default: 'unbuilt' },\n last_build_error: { type: 'text', nullable: true },\n last_built_at: { type: 'timestamp', 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: SESSIONS,\n columns: {\n id: { type: 'uuid-pk' },\n session_id: { type: 'text' },\n // The link the session is filed under (the position-1 link by default).\n // The PR tools, subscriptions, audit and work-item check still read it.\n project_repository_id: { type: 'text' },\n // Nullable so the column can be added to populated tables; filled by the\n // init() backfill and written by every `create` since.\n factory_project_id: { type: 'text', nullable: true },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n branch: { type: 'text' },\n base_branch: { type: 'text' },\n title: { type: 'text', nullable: true },\n visibility: { type: 'text', nullable: true },\n sandbox_id: { type: 'text', nullable: true },\n sandbox_workdir: { type: 'text', nullable: true },\n materialized_at: { type: 'timestamp', nullable: true },\n first_message_at: { type: 'timestamp', nullable: true },\n first_meaningful_exec_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 name: 'source_control_sessions_project_user_branch_unique',\n columns: ['factory_project_id', 'user_id', 'branch'],\n },\n ],\n indexes: [{ name: 'source_control_sessions_project_idx', columns: ['factory_project_id'] }],\n },\n {\n name: SESSION_REPOSITORIES,\n columns: {\n id: { type: 'uuid-pk' },\n session_id: { type: 'text' },\n project_repository_id: { type: 'text' },\n branch: { type: 'text' },\n change_request_id: { type: 'text', nullable: true },\n change_request_url: { type: 'text', nullable: true },\n pushed_at: { type: 'timestamp' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n {\n name: 'source_control_session_repositories_session_link_unique',\n columns: ['session_id', 'project_repository_id'],\n },\n ],\n indexes: [{ name: 'source_control_session_repositories_session_idx', columns: ['session_id'] }],\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 type ProjectRepositoryBuildStatus = 'unbuilt' | 'configured' | 'failed';\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 teardownCommand: string | null;\n /** 1-based order within the project's environment (display and setup order only). */\n position: number;\n /** Whether the repository is part of the project's sandbox environment. */\n inEnvironment: boolean;\n lastBuildStatus: ProjectRepositoryBuildStatus;\n lastBuildError: string | null;\n lastBuiltAt: Date | 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 teardownCommand?: string | null;\n}\n\nexport interface UpdateProjectRepositoryInput {\n branch?: string | null;\n sandboxProvider?: string;\n sandboxWorkdir?: string;\n setupCommand?: string | null;\n teardownCommand?: string | null;\n position?: number;\n inEnvironment?: boolean;\n}\n\nexport interface SetProjectRepositoryBuildStatusInput {\n orgId: string;\n id: string;\n status: ProjectRepositoryBuildStatus;\n error?: string | null;\n builtAt?: Date | null;\n}\n\n/**\n * Who can open a session: 'org' sessions are visible to every member of the\n * owning organization, 'private' sessions only to their owner. Stored at\n * creation; rows created before the column existed read as 'org'.\n */\nexport type SourceControlSessionVisibility = 'org' | 'private';\n\nexport interface SourceControlSession {\n id: string;\n sessionId: string;\n /**\n * The repository link the session is filed under (the position-1 link by\n * default). The PR tools default to it, and subscriptions, audit and the\n * work-item check still read it; `sessionRepositories` records each\n * repository the session pushed to or opened a change request in, but\n * nothing reads those rows back yet. Moving the readers to them is a\n * follow-up; nullable now so that deletion is a column change only.\n */\n projectRepositoryId: string | null;\n /** The factory the session belongs to. Null only on rows the backfill could not resolve. */\n factoryProjectId: string | null;\n orgId: string;\n userId: string;\n branch: string;\n title: string | null;\n visibility: SourceControlSessionVisibility;\n baseBranch: string;\n sandboxId: string | null;\n sandboxWorkdir: string | null;\n materializedAt: Date | null;\n /** When the first user message reached the session's agent. Write-once. */\n firstMessageAt: Date | null;\n /** When the agent's first successful sandbox exec finished. Write-once. */\n firstMeaningfulExecAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateSourceControlSessionInput {\n sessionId: string;\n projectRepositoryId: string;\n /**\n * The factory the link's connection belongs to. It must match the link, so a\n * caller cannot file a session under another project. The stored value is\n * always read from the connection, so a fixture that omits it still gets the\n * right one.\n */\n factoryProjectId: string;\n orgId: string;\n userId: string;\n branch: string;\n title?: string | null;\n /** Defaults to 'org' when omitted, matching how NULL rows are read. */\n visibility?: SourceControlSessionVisibility;\n baseBranch: string;\n}\n\n/** One repository a session pushed to; the branch and change request it holds there. */\nexport interface SourceControlSessionRepository {\n id: string;\n sessionId: string;\n projectRepositoryId: string;\n branch: string;\n changeRequestId: string | null;\n changeRequestUrl: string | null;\n pushedAt: Date;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * Every optional field keeps the stored value when omitted, so a push after a\n * change request keeps the change request and a change request recorded after\n * a push keeps the pushed branch. `fallbackBranch` only matters on insert: the\n * column is not nullable, so a caller that records a change request for a\n * session with no row yet (raw `git push` + `gh pr create`) passes the head ref.\n */\nexport interface UpsertSessionRepositoryInput {\n sessionId: string;\n projectRepositoryId: string;\n branch?: string;\n fallbackBranch?: string;\n changeRequestId?: string | null;\n changeRequestUrl?: string | null;\n pushedAt?: Date;\n}\n\nexport type SessionBranchKey =\n | { projectRepositoryId: string; userId: string; branch: string }\n | { factoryProjectId: string; userId: string; branch: string };\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 /** Every link of this integration's connections to the project, ordered by `position`. */\n listByProject(args: { orgId: string; factoryProjectId: string }): Promise<ProjectRepository[]>;\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 /** Record the outcome of the last environment build for this repository. */\n setBuildStatus(args: SetProjectRepositoryBuildStatusInput): Promise<ProjectRepository | null>;\n unlink(args: { orgId: string; id: string }): Promise<boolean>;\n };\n readonly sessions: {\n /**\n * Viewer-aware listing: every org-visible session for the repository\n * (regardless of owner) plus the viewer's own private sessions.\n */\n list(args: { projectRepositoryId: string; viewerUserId: string }): Promise<SourceControlSession[]>;\n /**\n * System-level listing of every session for the repository regardless of\n * visibility. For internal flows only (session retirement, repository\n * teardown); never expose directly to a viewer.\n */\n listByProjectRepository(args: { projectRepositoryId: string }): Promise<SourceControlSession[]>;\n /**\n * Viewer-aware listing of the project's sessions reachable through this\n * integration, across all of its links. Same visibility rule as `list`.\n */\n listByProject(args: {\n orgId: string;\n factoryProjectId: string;\n viewerUserId: string;\n }): Promise<SourceControlSession[]>;\n getBySessionId(sessionId: string): Promise<SourceControlSession | null>;\n /** Overwrite the session's display title. Keyed by the controller-facing `sessionId`. */\n rename(args: { sessionId: string; title: string }): Promise<void>;\n /** Keyed by the link (today's callers) or by the factory. */\n getForBranch(args: SessionBranchKey): Promise<SourceControlSession | null>;\n create(input: CreateSourceControlSessionInput): Promise<SourceControlSession>;\n setSandbox(args: { id: string; sandboxId: string | null; sandboxWorkdir: string }): Promise<void>;\n /**\n * Record when the session's workspace was first materialized. Write-once:\n * the guarded update only lands while the column is still NULL, so resumes\n * (Railway idle-reap, checkpoint restore, sandbox recreate) do not overwrite\n * the initial-materialize baseline that `materialize_s = materialized_at -\n * created_at` depends on.\n */\n markMaterialized(args: { id: string }): Promise<void>;\n /**\n * Record when the session's agent received its first user message.\n * Write-once: the guarded update only lands while the column is still\n * NULL, so retries and process restarts are no-ops. Keyed by the\n * controller-facing `sessionId` (not the row id) because the caller —\n * the session observer — only knows the controller resourceId.\n */\n markFirstMessage(args: { sessionId: string }): Promise<void>;\n /**\n * Record when the session's agent completed its first successful sandbox\n * exec (TTFME anchor). Same write-once contract as `markFirstMessage`:\n * guarded on the column being NULL, keyed by the controller-facing\n * `sessionId`.\n */\n markFirstMeaningfulExec(args: { sessionId: string }): Promise<void>;\n /** Removes the session and its repository rows. */\n delete(id: string): Promise<void>;\n };\n readonly sessionRepositories: {\n /** Insert, or on `(session, link)` conflict update branch, change request and push time. */\n upsert(input: UpsertSessionRepositoryInput): Promise<SourceControlSessionRepository>;\n listBySession(args: { sessionId: string }): Promise<SourceControlSessionRepository[]>;\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 teardown_command: string | null;\n position: number | null;\n in_environment: boolean | null;\n last_build_status: string | null;\n last_build_error: string | null;\n last_built_at: Date | null;\n created_at: Date;\n updated_at: Date;\n}\n\n/** The environment columns on `factory_projects` the backfill reads and writes. */\ninterface EnvironmentProjectRow extends Record<string, unknown> {\n id: string;\n environment_backfilled_at: Date | null;\n}\n\ninterface SessionDbRow extends Record<string, unknown> {\n id: string;\n session_id: string;\n project_repository_id: string;\n factory_project_id?: string | null;\n org_id: string;\n user_id: string;\n branch: string;\n title: string | null;\n visibility: string | null;\n base_branch: string;\n sandbox_id: string | null;\n sandbox_workdir: string | null;\n materialized_at: Date | null;\n first_message_at: Date | null;\n first_meaningful_exec_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 teardownCommand: row.teardown_command,\n position: row.position ?? 0,\n inEnvironment: row.in_environment ?? true,\n lastBuildStatus: toBuildStatus(row.last_build_status),\n lastBuildError: row.last_build_error,\n lastBuiltAt: row.last_built_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction toBuildStatus(value: string | null): ProjectRepositoryBuildStatus {\n return value === 'configured' || value === 'failed' ? value : 'unbuilt';\n}\n\n/** Oldest first; ties (same millisecond) break on id so re-runs see one order. */\nfunction byCreatedAt(a: ProjectRepositoryDbRow, b: ProjectRepositoryDbRow): number {\n return a.created_at.getTime() - b.created_at.getTime() || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);\n}\n\ninterface SessionRepositoryDbRow extends Record<string, unknown> {\n id: string;\n session_id: string;\n project_repository_id: string;\n branch: string;\n change_request_id: string | null;\n change_request_url: string | null;\n pushed_at: Date;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toSessionRepository(row: SessionRepositoryDbRow): SourceControlSessionRepository {\n return {\n id: row.id,\n sessionId: row.session_id,\n projectRepositoryId: row.project_repository_id,\n branch: row.branch,\n changeRequestId: row.change_request_id,\n changeRequestUrl: row.change_request_url,\n pushedAt: row.pushed_at,\n createdAt: row.created_at,\n updatedAt: row.updated_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 factoryProjectId: row.factory_project_id ?? null,\n orgId: row.org_id,\n userId: row.user_id,\n branch: row.branch,\n title: row.title,\n visibility: row.visibility === 'private' ? 'private' : 'org',\n baseBranch: row.base_branch,\n sandboxId: row.sandbox_id,\n sandboxWorkdir: row.sandbox_workdir,\n materializedAt: row.materialized_at,\n firstMessageAt: row.first_message_at,\n firstMeaningfulExecAt: row.first_meaningful_exec_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction projectRepositoryPatch(input: UpdateProjectRepositoryInput): Record<string, unknown> {\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 if (input.teardownCommand !== undefined) patch.teardown_command = input.teardownCommand;\n if (input.position !== undefined) patch.position = input.position;\n if (input.inEnvironment !== undefined) patch.in_environment = input.inEnvironment;\n return patch;\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 await this.#backfillEnvironment();\n await this.#backfillSessionFactory();\n }\n\n /**\n * Fill `factory_project_id` on sessions that predate the column, walking\n * link → connection. The old constraint was per link, so two links of one\n * factory may hold the same user and branch; the new per-factory index\n * would reject the second write and a throwing `init()` only leaves the\n * domain not-ready. Within such a group the oldest session wins and the\n * others keep a null factory. Idempotent, O(rows), deletes nothing.\n */\n async #backfillSessionFactory(): Promise<void> {\n let unresolved = 0;\n let collisions = 0;\n try {\n const pending = await this.ops.findMany<SessionDbRow>(SESSIONS, { factory_project_id: null });\n if (pending.length === 0) return;\n const connections = await this.ops.findMany<ConnectionDbRow>(CONNECTIONS, {});\n const links = await this.ops.findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {});\n const projectByConnectionId = new Map(connections.map(row => [row.id, row.factory_project_id]));\n const projectByLinkId = new Map(\n links.flatMap(link => {\n const projectId = projectByConnectionId.get(link.connection_id);\n return projectId ? [[link.id, projectId] as const] : [];\n }),\n );\n const keyOf = (projectId: string, row: SessionDbRow) => `${projectId}\\u0000${row.user_id}\\u0000${row.branch}`;\n const taken = new Set<string>();\n for (const row of await this.ops.findMany<SessionDbRow>(SESSIONS, {})) {\n if (row.factory_project_id) taken.add(keyOf(row.factory_project_id, row));\n }\n const ordered = [...pending].sort(\n (a, b) => a.created_at.getTime() - b.created_at.getTime() || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0),\n );\n for (const row of ordered) {\n const projectId = projectByLinkId.get(row.project_repository_id);\n if (!projectId) {\n unresolved += 1;\n continue;\n }\n const key = keyOf(projectId, row);\n if (taken.has(key)) {\n collisions += 1;\n continue;\n }\n try {\n await this.ops.updateMany(SESSIONS, { id: row.id }, { factory_project_id: projectId });\n taken.add(key);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n collisions += 1;\n }\n }\n } catch (error) {\n // Rows written before the failure keep their factory; the next init() resumes from the rest.\n console.warn(`[factory] session backfill stopped early: ${error instanceof Error ? error.message : error}`);\n return;\n }\n if (unresolved > 0 || collisions > 0) {\n console.warn(\n `[factory] session backfill: ${unresolved} sessions have no resolvable factory, ${collisions} sessions collide on (factory, user, branch) and keep a null factory`,\n );\n }\n }\n\n /**\n * One-time fill of the environment columns from the rows that predate them.\n * Idempotent and non-destructive: a project is touched only while its\n * `environment_backfilled_at` is null, every other write lands only where the\n * stored value is still the column default, and nothing is deleted. Runs\n * on every start; reports what it could not resolve instead of throwing,\n * because a throwing `init()` only leaves the domain not-ready.\n */\n async #backfillEnvironment(): Promise<void> {\n // Domains initialize in parallel, so the project columns may not exist yet.\n await this.ensureCollections([FACTORY_PROJECTS_SCHEMA]);\n let missingRepositories = 0;\n const failedProjects: string[] = [];\n try {\n const projects = await this.ops.findMany<EnvironmentProjectRow>(FACTORY_PROJECTS, {\n environment_backfilled_at: null,\n });\n if (projects.length === 0) return;\n const connections = await this.ops.findMany<ConnectionDbRow>(CONNECTIONS, {});\n const links = await this.ops.findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {});\n const repositories = await this.ops.findMany<RepositoryDbRow>(REPOSITORIES, {});\n const slugByRepositoryId = new Map(repositories.map(row => [row.id, row.slug]));\n const linksByConnectionId = new Map<string, ProjectRepositoryDbRow[]>();\n for (const link of links) {\n const bucket = linksByConnectionId.get(link.connection_id) ?? [];\n bucket.push(link);\n linksByConnectionId.set(link.connection_id, bucket);\n }\n const connectionsByProjectId = new Map<string, ConnectionDbRow[]>();\n for (const connection of connections) {\n const bucket = connectionsByProjectId.get(connection.factory_project_id) ?? [];\n bucket.push(connection);\n connectionsByProjectId.set(connection.factory_project_id, bucket);\n }\n\n for (const project of projects) {\n try {\n const projectLinks = (connectionsByProjectId.get(project.id) ?? [])\n .flatMap(connection => linksByConnectionId.get(connection.id) ?? [])\n .sort(byCreatedAt);\n const slugOf = (link: ProjectRepositoryDbRow): string => {\n const slug = slugByRepositoryId.get(link.repository_id);\n if (slug !== undefined) return slug;\n missingRepositories += 1;\n return `missing-repository:${link.id}`;\n };\n\n // Positions continue after whatever the API already assigned; slugs\n // already in the environment keep their newly positioned duplicates out.\n let nextPosition = Math.max(0, ...projectLinks.map(link => link.position ?? 0));\n const seenSlugs = new Set(\n projectLinks.filter(link => (link.position ?? 0) > 0 && link.in_environment !== false).map(slugOf),\n );\n for (const link of projectLinks) {\n if ((link.position ?? 0) > 0) continue;\n nextPosition += 1;\n const slug = slugOf(link);\n const inEnvironment = link.in_environment !== false && !seenSlugs.has(slug);\n if (inEnvironment) seenSlugs.add(slug);\n await this.ops.updateMany(\n PROJECT_REPOSITORIES,\n { id: link.id },\n { position: nextPosition, in_environment: inEnvironment },\n );\n }\n\n await this.ops.updateMany(FACTORY_PROJECTS, { id: project.id }, { environment_backfilled_at: new Date() });\n } catch {\n failedProjects.push(project.id);\n }\n }\n } catch (error) {\n console.warn(`[factory] environment backfill did not run: ${error instanceof Error ? error.message : error}`);\n return;\n }\n if (missingRepositories > 0 || failedProjects.length > 0) {\n console.warn(\n `[factory] environment backfill: ${missingRepositories} links point at a missing repository row, ${failedProjects.length} projects could not be updated${failedProjects.length > 0 ? ` (${failedProjects.join(', ')})` : ''}`,\n );\n }\n }\n\n /**\n * Applies environment patches to a project's repository links through `ops`,\n * normally a transaction that also holds the project row. Validates against\n * the links as they are inside that transaction: every id must belong to the\n * project, and a reorder must list every link so no two share a position.\n * Nothing is written when validation fails.\n */\n async updateEnvironmentRepositories(\n ops: FactoryStorageOps,\n args: {\n factoryProjectId: string;\n integrationIds: string[];\n patches: Array<UpdateProjectRepositoryInput & { projectRepositoryId: string }>;\n },\n ): Promise<'updated' | 'not_found' | 'incomplete_reorder'> {\n const connections =\n args.integrationIds.length === 0\n ? []\n : await ops.findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: args.factoryProjectId,\n integration_id: { in: args.integrationIds },\n });\n const links =\n connections.length === 0\n ? []\n : await ops.findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: { in: connections.map(connection => connection.id) },\n });\n const linkIds = new Set(links.map(link => link.id));\n if (args.patches.some(patch => !linkIds.has(patch.projectRepositoryId))) return 'not_found';\n if (args.patches.some(patch => patch.position !== undefined) && args.patches.length !== linkIds.size) {\n return 'incomplete_reorder';\n }\n for (const { projectRepositoryId, ...input } of args.patches) {\n if (Object.keys(input).length === 0) continue;\n await ops.updateMany(PROJECT_REPOSITORIES, { id: projectRepositoryId }, projectRepositoryPatch(input));\n }\n return 'updated';\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany(SESSION_REPOSITORIES, {});\n await this.ops.deleteMany(SESSIONS, {});\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) throw new SourceControlConnectionNotFoundError();\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 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 // Same cleanup as `projectRepositories.unlink`, for every link of the connection.\n for (const projectRepository of projectRepositories) {\n for (const session of await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepository.id,\n })) {\n await db().deleteMany(SESSION_REPOSITORIES, { session_id: session.session_id });\n }\n await db().deleteMany(SESSION_REPOSITORIES, { project_repository_id: projectRepository.id });\n await db().deleteMany(SESSIONS, { 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 listByProject: 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 const connections = await db().findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n });\n if (connections.length === 0) return [];\n const rows = await db().findMany<ProjectRepositoryDbRow>(\n PROJECT_REPOSITORIES,\n { connection_id: { in: connections.map(connection => connection.id) } },\n {\n orderBy: [\n ['position', 'asc'],\n ['created_at', 'asc'],\n ],\n },\n );\n return rows.map(toProjectRepository);\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 // Order and dedupe span every connection of the project, whatever the integration.\n const siblingConnections = await db().findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: connection.factoryProjectId,\n });\n const siblings = await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: { in: siblingConnections.map(sibling => sibling.id) },\n });\n const position = 1 + Math.max(0, ...siblings.map(sibling => sibling.position ?? 0));\n let inEnvironment = true;\n for (const sibling of siblings) {\n if (sibling.in_environment === false) continue;\n const siblingRepository = await db().findOne<RepositoryDbRow>(REPOSITORIES, { id: sibling.repository_id });\n if (siblingRepository?.slug === repository.slug) {\n inEnvironment = false;\n break;\n }\n }\n const now = new Date();\n try {\n const row = await db().insertOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\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 teardown_command: input.teardownCommand ?? null,\n position,\n in_environment: inEnvironment,\n last_build_status: 'unbuilt',\n last_build_error: null,\n last_built_at: null,\n created_at: now,\n updated_at: now,\n });\n return toProjectRepository(row);\n } catch (error) {\n // Match the in-memory handle: return the existing row unchanged on\n // a unique-constraint race.\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await db().findOne<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: input.connectionId,\n repository_id: input.repositoryId,\n });\n if (!row) throw error;\n return toProjectRepository(row);\n }\n },\n update: async ({ orgId, id, input }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return null;\n await db().updateMany(PROJECT_REPOSITORIES, { id }, projectRepositoryPatch(input));\n return getProjectRepository({ orgId, id });\n },\n setBuildStatus: async ({ orgId, id, status, error, builtAt }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return null;\n await db().updateMany(\n PROJECT_REPOSITORIES,\n { id },\n {\n last_build_status: status,\n last_build_error: error ?? null,\n last_built_at: builtAt ?? null,\n updated_at: new Date(),\n },\n );\n return getProjectRepository({ orgId, id });\n },\n unlink: async ({ orgId, id }) => {\n const existing = await getProjectRepository({ orgId, id });\n if (!existing) return false;\n for (const session of await db().findMany<SessionDbRow>(SESSIONS, { project_repository_id: id })) {\n await db().deleteMany(SESSION_REPOSITORIES, { session_id: session.session_id });\n }\n await db().deleteMany(SESSION_REPOSITORIES, { project_repository_id: id });\n await db().deleteMany(SESSIONS, { project_repository_id: id });\n await db().deleteMany(PROJECT_REPOSITORIES, { id });\n return true;\n },\n },\n sessions: {\n list: async ({ projectRepositoryId, viewerUserId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n const rows = await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n });\n // Org-visible sessions (NULL counts as org) plus the viewer's own.\n return rows.filter(row => row.visibility !== 'private' || row.user_id === viewerUserId).map(toSession);\n },\n listByProjectRepository: async ({ projectRepositoryId }) => {\n if (!(await getProjectRepositoryById(projectRepositoryId))) return [];\n return (\n await db().findMany<SessionDbRow>(SESSIONS, {\n project_repository_id: projectRepositoryId,\n })\n ).map(toSession);\n },\n listByProject: async ({ orgId, factoryProjectId, viewerUserId }) => {\n const connections = await db().findMany<ConnectionDbRow>(CONNECTIONS, {\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n });\n if (connections.length === 0) return [];\n const linkIds = new Set<string>();\n for (const connection of connections) {\n for (const link of await db().findMany<ProjectRepositoryDbRow>(PROJECT_REPOSITORIES, {\n connection_id: connection.id,\n })) {\n linkIds.add(link.id);\n }\n }\n const rows = await db().findMany<SessionDbRow>(SESSIONS, {\n factory_project_id: factoryProjectId,\n org_id: orgId,\n });\n return rows\n .filter(row => linkIds.has(row.project_repository_id))\n .filter(row => row.visibility !== 'private' || row.user_id === viewerUserId)\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 rename: async ({ sessionId, title }) => {\n await db().updateAtomic<SessionDbRow>(SESSIONS, { session_id: sessionId }, () => ({\n title,\n updated_at: new Date(),\n }));\n },\n getForBranch: async args => {\n if ('factoryProjectId' in args) {\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n factory_project_id: args.factoryProjectId,\n user_id: args.userId,\n branch: args.branch,\n });\n // Same integration scoping as `getBySessionId`: the tables are shared across providers.\n return row && (await getProjectRepositoryById(row.project_repository_id)) ? toSession(row) : null;\n }\n if (!(await getProjectRepositoryById(args.projectRepositoryId))) return null;\n const row = await db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: args.projectRepositoryId,\n user_id: args.userId,\n branch: args.branch,\n });\n return row ? toSession(row) : null;\n },\n create: async input => {\n const link = await requireProjectRepositoryById(input.projectRepositoryId);\n const connection = await getConnection({ orgId: input.orgId, id: link.connectionId });\n if (!connection) throw new Error('Project repository not found for this integration.');\n if (input.factoryProjectId !== undefined && input.factoryProjectId !== connection.factoryProjectId) {\n throw new Error('Session factory does not match the repository link.');\n }\n const factoryProjectId = connection.factoryProjectId;\n const reuse = (row: SessionDbRow) => {\n if (row.factory_project_id !== factoryProjectId) throw new SessionOwnershipMismatchError(row.session_id);\n return toSession(row);\n };\n // Reuse is still keyed by the link, as before this column existed. A\n // branch the same user already holds on another link of the factory\n // surfaces as the unique violation of the insert below.\n const findExisting = async () =>\n db().findOne<SessionDbRow>(SESSIONS, {\n project_repository_id: input.projectRepositoryId,\n user_id: input.userId,\n branch: input.branch,\n });\n const existing = await findExisting();\n if (existing) return reuse(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 factory_project_id: factoryProjectId,\n org_id: input.orgId,\n user_id: input.userId,\n branch: input.branch,\n title: input.title ?? null,\n visibility: input.visibility ?? 'org',\n base_branch: input.baseBranch,\n sandbox_id: null,\n sandbox_workdir: null,\n materialized_at: null,\n first_message_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 findExisting();\n if (!row) throw error;\n return reuse(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 // `materialized_at: null` in the filter compiles to `IS NULL`, making\n // this a write-once update: session resumes (idle-reap, checkpoint\n // restore, sandbox recreate) match zero rows and cannot overwrite the\n // initial-materialize timestamp that `materialize_s` is derived from.\n await db().updateMany(\n SESSIONS,\n { id, materialized_at: null },\n { materialized_at: new Date(), updated_at: new Date() },\n );\n },\n markFirstMessage: async ({ sessionId }) => {\n // `first_message_at: null` in the filter compiles to `IS NULL`, making\n // this an atomic one-shot: concurrent callers and later messages\n // match zero rows. Sessions without a source-control row (chat-only\n // channels) are a zero-row no-op too.\n await db().updateMany(\n SESSIONS,\n { session_id: sessionId, first_message_at: null },\n { first_message_at: new Date(), updated_at: new Date() },\n );\n },\n markFirstMeaningfulExec: async ({ sessionId }) => {\n // Same atomic one-shot shape as markFirstMessage: the NULL filter\n // makes concurrent callers and later execs zero-row no-ops.\n await db().updateMany(\n SESSIONS,\n { session_id: sessionId, first_meaningful_exec_at: null },\n { first_meaningful_exec_at: new Date(), updated_at: new Date() },\n );\n },\n delete: async id => {\n const row = await db().findOne<SessionDbRow>(SESSIONS, { id });\n if (row) await db().deleteMany(SESSION_REPOSITORIES, { session_id: row.session_id });\n await db().deleteMany(SESSIONS, { id });\n },\n },\n sessionRepositories: {\n upsert: async input => {\n const key = { session_id: input.sessionId, project_repository_id: input.projectRepositoryId };\n const now = new Date();\n const changes: Partial<SessionRepositoryDbRow> = { updated_at: now };\n if (input.branch !== undefined) {\n changes.branch = input.branch;\n changes.pushed_at = input.pushedAt ?? now;\n } else if (input.pushedAt) {\n changes.pushed_at = input.pushedAt;\n }\n if (input.changeRequestId !== undefined) changes.change_request_id = input.changeRequestId;\n if (input.changeRequestUrl !== undefined) changes.change_request_url = input.changeRequestUrl;\n const update = async () => {\n await db().updateMany(SESSION_REPOSITORIES, key, changes);\n const row = await db().findOne<SessionRepositoryDbRow>(SESSION_REPOSITORIES, key);\n if (!row) throw new Error('Session repository row vanished during upsert.');\n return toSessionRepository(row);\n };\n if (await db().findOne<SessionRepositoryDbRow>(SESSION_REPOSITORIES, key)) return update();\n const branch = input.branch ?? input.fallbackBranch;\n if (!branch) throw new Error('A session repository row needs a branch when it is first recorded.');\n try {\n return toSessionRepository(\n await db().insertOne<SessionRepositoryDbRow>(SESSION_REPOSITORIES, {\n ...key,\n branch,\n change_request_id: input.changeRequestId ?? null,\n change_request_url: input.changeRequestUrl ?? null,\n pushed_at: input.pushedAt ?? now,\n updated_at: now,\n created_at: now,\n }),\n );\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n return update();\n }\n },\n listBySession: async ({ sessionId }) =>\n (\n await db().findMany<SessionRepositoryDbRow>(\n SESSION_REPOSITORIES,\n { session_id: sessionId },\n {\n orderBy: [['created_at', 'asc']],\n },\n )\n ).map(toSessionRepository),\n },\n };\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ConfiguredExternalRepositoryKey, CreateProjectSourceControlConnectionInput, CreateSourceControlSessionInput, ExternalRepositoryProjectTarget, LinkProjectRepositoryInput, ProjectRepository, ProjectSourceControlConnection, SourceControlInstallation, SourceControlRepository, SourceControlSession, SourceControlStorageHandle, UpdateProjectRepositoryInput, UpsertSourceControlInstallationInput, UpsertSourceControlRepositoryInput } from './base.js';
1
+ import type { ConfiguredExternalRepositoryKey, CreateProjectSourceControlConnectionInput, CreateSourceControlSessionInput, ExternalRepositoryProjectTarget, LinkProjectRepositoryInput, ProjectRepository, ProjectSourceControlConnection, SessionBranchKey, SetProjectRepositoryBuildStatusInput, SourceControlInstallation, SourceControlRepository, SourceControlSession, SourceControlSessionRepository, SourceControlStorageHandle, UpdateProjectRepositoryInput, UpsertSessionRepositoryInput, UpsertSourceControlInstallationInput, UpsertSourceControlRepositoryInput } from './base.js';
2
2
  /** In-memory provider-scoped source-control handle for route tests. */
3
3
  export declare class SourceControlStorageInMemory implements SourceControlStorageHandle {
4
4
  readonly integrationId: string;
@@ -7,6 +7,7 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
7
7
  connectionsRows: ProjectSourceControlConnection[];
8
8
  projectRepositoriesRows: ProjectRepository[];
9
9
  sessionsRows: SourceControlSession[];
10
+ sessionRepositoriesRows: SourceControlSessionRepository[];
10
11
  constructor(integrationId?: string);
11
12
  readonly installations: {
12
13
  list: ({ orgId }: {
@@ -80,6 +81,10 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
80
81
  installationExternalId: string;
81
82
  repositoryExternalId: string;
82
83
  }) => Promise<ExternalRepositoryProjectTarget[]>;
84
+ listByProject: ({ orgId, factoryProjectId }: {
85
+ orgId: string;
86
+ factoryProjectId: string;
87
+ }) => Promise<ProjectRepository[]>;
83
88
  get: ({ orgId, id }: {
84
89
  orgId: string;
85
90
  id: string;
@@ -90,6 +95,7 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
90
95
  id: string;
91
96
  input: UpdateProjectRepositoryInput;
92
97
  }) => Promise<ProjectRepository | null>;
98
+ setBuildStatus: ({ orgId, id, status, error, builtAt, }: SetProjectRepositoryBuildStatusInput) => Promise<ProjectRepository | null>;
93
99
  unlink: ({ orgId, id }: {
94
100
  orgId: string;
95
101
  id: string;
@@ -103,16 +109,17 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
103
109
  listByProjectRepository: ({ projectRepositoryId }: {
104
110
  projectRepositoryId: string;
105
111
  }) => Promise<SourceControlSession[]>;
112
+ listByProject: ({ orgId, factoryProjectId, viewerUserId, }: {
113
+ orgId: string;
114
+ factoryProjectId: string;
115
+ viewerUserId: string;
116
+ }) => Promise<SourceControlSession[]>;
106
117
  getBySessionId: (sessionId: string) => Promise<SourceControlSession | null>;
107
118
  rename: ({ sessionId, title }: {
108
119
  sessionId: string;
109
120
  title: string;
110
121
  }) => Promise<void>;
111
- getForBranch: ({ projectRepositoryId, userId, branch, }: {
112
- projectRepositoryId: string;
113
- userId: string;
114
- branch: string;
115
- }) => Promise<SourceControlSession | null>;
122
+ getForBranch: (args: SessionBranchKey) => Promise<SourceControlSession | null>;
116
123
  create: (input: CreateSourceControlSessionInput) => Promise<SourceControlSession>;
117
124
  setSandbox: ({ id, sandboxId, sandboxWorkdir, }: {
118
125
  id: string;
@@ -130,5 +137,11 @@ export declare class SourceControlStorageInMemory implements SourceControlStorag
130
137
  }) => Promise<void>;
131
138
  delete: (id: string) => Promise<void>;
132
139
  };
140
+ readonly sessionRepositories: {
141
+ upsert: (input: UpsertSessionRepositoryInput) => Promise<SourceControlSessionRepository>;
142
+ listBySession: ({ sessionId }: {
143
+ sessionId: string;
144
+ }) => Promise<SourceControlSessionRepository[]>;
145
+ };
133
146
  }
134
147
  //# sourceMappingURL=inmemory.d.ts.map
@@ -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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"}
@@ -8,6 +8,7 @@ var SourceControlStorageInMemory = class {
8
8
  connectionsRows = [];
9
9
  projectRepositoriesRows = [];
10
10
  sessionsRows = [];
11
+ sessionRepositoriesRows = [];
11
12
  constructor(integrationId = "github") {
12
13
  this.integrationId = integrationId;
13
14
  }
@@ -154,6 +155,10 @@ var SourceControlStorageInMemory = class {
154
155
  orgId,
155
156
  id
156
157
  })) return false;
158
+ for (const link of this.projectRepositoriesRows.filter((row) => row.connectionId === id)) await this.projectRepositories.unlink({
159
+ orgId,
160
+ id: link.id
161
+ });
157
162
  this.connectionsRows.splice(0, this.connectionsRows.length, ...this.connectionsRows.filter((row) => row.id !== id));
158
163
  return true;
159
164
  }
@@ -196,6 +201,13 @@ var SourceControlStorageInMemory = class {
196
201
  }
197
202
  return targets;
198
203
  },
204
+ listByProject: async ({ orgId, factoryProjectId }) => {
205
+ const connectionIds = new Set((await this.connections.list({
206
+ orgId,
207
+ factoryProjectId
208
+ })).filter((row) => row.integrationId === this.integrationId).map((row) => row.id));
209
+ return this.projectRepositoriesRows.filter((row) => connectionIds.has(row.connectionId)).sort((a, b) => a.position - b.position || a.createdAt.getTime() - b.createdAt.getTime());
210
+ },
199
211
  get: async ({ orgId, id }) => {
200
212
  const row = this.projectRepositoriesRows.find((candidate) => candidate.id === id);
201
213
  if (!row) return null;
@@ -216,6 +228,10 @@ var SourceControlStorageInMemory = class {
216
228
  if (!connection || !repository || repository.installationId !== connection.installationId) throw new Error("Source-control connection or repository not found");
217
229
  const existing = this.projectRepositoriesRows.find((row) => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId);
218
230
  if (existing) return existing;
231
+ const siblingConnectionIds = new Set(this.connectionsRows.filter((row) => row.factoryProjectId === connection.factoryProjectId).map((row) => row.id));
232
+ const siblings = this.projectRepositoriesRows.filter((row) => siblingConnectionIds.has(row.connectionId));
233
+ const position = 1 + Math.max(0, ...siblings.map((row) => row.position));
234
+ const inEnvironment = !siblings.some((row) => row.inEnvironment && this.repositoriesRows.find((candidate) => candidate.id === row.repositoryId)?.slug === repository.slug);
219
235
  const now = /* @__PURE__ */ new Date();
220
236
  const created = {
221
237
  id: globalThis.crypto.randomUUID(),
@@ -227,6 +243,11 @@ var SourceControlStorageInMemory = class {
227
243
  sandboxWorkdir: input.sandboxWorkdir,
228
244
  setupCommand: input.setupCommand ?? null,
229
245
  teardownCommand: input.teardownCommand ?? null,
246
+ position,
247
+ inEnvironment,
248
+ lastBuildStatus: "unbuilt",
249
+ lastBuildError: null,
250
+ lastBuiltAt: null,
230
251
  createdAt: now,
231
252
  updatedAt: now
232
253
  };
@@ -242,11 +263,28 @@ var SourceControlStorageInMemory = class {
242
263
  Object.assign(row, input, { updatedAt: /* @__PURE__ */ new Date() });
243
264
  return row;
244
265
  },
266
+ setBuildStatus: async ({ orgId, id, status, error, builtAt }) => {
267
+ const row = await this.projectRepositories.get({
268
+ orgId,
269
+ id
270
+ });
271
+ if (!row) return null;
272
+ Object.assign(row, {
273
+ lastBuildStatus: status,
274
+ lastBuildError: error ?? null,
275
+ lastBuiltAt: builtAt ?? null,
276
+ updatedAt: /* @__PURE__ */ new Date()
277
+ });
278
+ return row;
279
+ },
245
280
  unlink: async ({ orgId, id }) => {
246
281
  if (!await this.projectRepositories.get({
247
282
  orgId,
248
283
  id
249
284
  })) return false;
285
+ const sessionIds = new Set(this.sessionsRows.filter((row) => row.projectRepositoryId === id).map((r) => r.sessionId));
286
+ this.sessionRepositoriesRows = this.sessionRepositoriesRows.filter((row) => row.projectRepositoryId !== id && !sessionIds.has(row.sessionId));
287
+ this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter((row) => row.projectRepositoryId !== id));
250
288
  this.projectRepositoriesRows.splice(0, this.projectRepositoriesRows.length, ...this.projectRepositoriesRows.filter((row) => row.id !== id));
251
289
  return true;
252
290
  }
@@ -254,6 +292,11 @@ var SourceControlStorageInMemory = class {
254
292
  sessions = {
255
293
  list: async ({ projectRepositoryId, viewerUserId }) => this.sessionsRows.filter((row) => row.projectRepositoryId === projectRepositoryId && (row.visibility !== "private" || row.userId === viewerUserId)),
256
294
  listByProjectRepository: async ({ projectRepositoryId }) => this.sessionsRows.filter((row) => row.projectRepositoryId === projectRepositoryId),
295
+ listByProject: async ({ orgId, factoryProjectId, viewerUserId }) => {
296
+ const connectionIds = new Set(this.connectionsRows.filter((row) => row.factoryProjectId === factoryProjectId).map((row) => row.id));
297
+ const linkIds = new Set(this.projectRepositoriesRows.filter((row) => connectionIds.has(row.connectionId)).map((row) => row.id));
298
+ return this.sessionsRows.filter((row) => row.factoryProjectId === factoryProjectId && row.orgId === orgId && row.projectRepositoryId !== null && linkIds.has(row.projectRepositoryId) && (row.visibility !== "private" || row.userId === viewerUserId));
299
+ },
257
300
  getBySessionId: async (sessionId) => {
258
301
  const row = this.sessionsRows.find((candidate) => candidate.sessionId === sessionId);
259
302
  if (!row) return null;
@@ -266,15 +309,26 @@ var SourceControlStorageInMemory = class {
266
309
  row.updatedAt = /* @__PURE__ */ new Date();
267
310
  }
268
311
  },
269
- getForBranch: async ({ projectRepositoryId, userId, branch }) => this.sessionsRows.find((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch) ?? null,
312
+ getForBranch: async (args) => this.sessionsRows.find((row) => ("factoryProjectId" in args ? row.factoryProjectId === args.factoryProjectId && this.projectRepositoriesRows.some((link) => link.id === row.projectRepositoryId) : row.projectRepositoryId === args.projectRepositoryId) && row.userId === args.userId && row.branch === args.branch) ?? null,
270
313
  create: async (input) => {
271
- const existing = await this.sessions.getForBranch(input);
314
+ const link = this.projectRepositoriesRows.find((row) => row.id === input.projectRepositoryId);
315
+ const connection = link && this.connectionsRows.find((row) => row.id === link.connectionId);
316
+ if (!connection) throw new Error("Project repository not found for this integration.");
317
+ if (input.factoryProjectId !== void 0 && input.factoryProjectId !== connection.factoryProjectId) throw new Error("Session factory does not match the repository link.");
318
+ const factoryProjectId = connection.factoryProjectId;
319
+ const existing = await this.sessions.getForBranch({
320
+ projectRepositoryId: input.projectRepositoryId,
321
+ userId: input.userId,
322
+ branch: input.branch
323
+ });
272
324
  if (existing) return existing;
273
325
  if (this.sessionsRows.some((row) => row.sessionId === input.sessionId)) throw new UniqueViolationError("Source-control session ID already exists");
326
+ if (this.sessionsRows.some((row) => row.factoryProjectId === factoryProjectId && row.userId === input.userId && row.branch === input.branch)) throw new UniqueViolationError("Source-control session branch already exists in this factory");
274
327
  const now = /* @__PURE__ */ new Date();
275
328
  const session = {
276
329
  id: globalThis.crypto.randomUUID(),
277
330
  ...input,
331
+ factoryProjectId,
278
332
  title: input.title ?? null,
279
333
  visibility: input.visibility ?? "org",
280
334
  sandboxId: null,
@@ -318,9 +372,43 @@ var SourceControlStorageInMemory = class {
318
372
  });
319
373
  },
320
374
  delete: async (id) => {
375
+ const row = this.sessionsRows.find((candidate) => candidate.id === id);
376
+ if (row) this.sessionRepositoriesRows = this.sessionRepositoriesRows.filter((r) => r.sessionId !== row.sessionId);
321
377
  this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter((row) => row.id !== id));
322
378
  }
323
379
  };
380
+ sessionRepositories = {
381
+ upsert: async (input) => {
382
+ const now = /* @__PURE__ */ new Date();
383
+ const existing = this.sessionRepositoriesRows.find((row) => row.sessionId === input.sessionId && row.projectRepositoryId === input.projectRepositoryId);
384
+ if (existing) {
385
+ if (input.branch !== void 0) {
386
+ existing.branch = input.branch;
387
+ existing.pushedAt = input.pushedAt ?? now;
388
+ } else if (input.pushedAt) existing.pushedAt = input.pushedAt;
389
+ if (input.changeRequestId !== void 0) existing.changeRequestId = input.changeRequestId;
390
+ if (input.changeRequestUrl !== void 0) existing.changeRequestUrl = input.changeRequestUrl;
391
+ existing.updatedAt = now;
392
+ return existing;
393
+ }
394
+ const branch = input.branch ?? input.fallbackBranch;
395
+ if (!branch) throw new Error("A session repository row needs a branch when it is first recorded.");
396
+ const created = {
397
+ id: globalThis.crypto.randomUUID(),
398
+ sessionId: input.sessionId,
399
+ projectRepositoryId: input.projectRepositoryId,
400
+ branch,
401
+ changeRequestId: input.changeRequestId ?? null,
402
+ changeRequestUrl: input.changeRequestUrl ?? null,
403
+ pushedAt: input.pushedAt ?? now,
404
+ updatedAt: now,
405
+ createdAt: now
406
+ };
407
+ this.sessionRepositoriesRows.push(created);
408
+ return created;
409
+ },
410
+ listBySession: async ({ sessionId }) => this.sessionRepositoriesRows.filter((row) => row.sessionId === sessionId)
411
+ };
324
412
  };
325
413
  //#endregion
326
414
  export { SourceControlStorageInMemory };