@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.
- package/dist/capabilities/version-control.d.ts +13 -8
- package/dist/capabilities/version-control.d.ts.map +1 -1
- package/dist/environment/build-runner.d.ts +72 -0
- package/dist/environment/build-runner.d.ts.map +1 -0
- package/dist/environment/build-runner.js +131 -0
- package/dist/environment/build-runner.js.map +1 -0
- package/dist/environment/build-schedule.d.ts +40 -0
- package/dist/environment/build-schedule.d.ts.map +1 -0
- package/dist/environment/build-schedule.js +94 -0
- package/dist/environment/build-schedule.js.map +1 -0
- package/dist/environment/build-workflow.d.ts +62 -0
- package/dist/environment/build-workflow.d.ts.map +1 -0
- package/dist/environment/build-workflow.js +149 -0
- package/dist/environment/build-workflow.js.map +1 -0
- package/dist/environment/build.d.ts +111 -0
- package/dist/environment/build.d.ts.map +1 -0
- package/dist/environment/build.js +344 -0
- package/dist/environment/build.js.map +1 -0
- package/dist/environment/heads.d.ts +36 -0
- package/dist/environment/heads.d.ts.map +1 -0
- package/dist/environment/heads.js +60 -0
- package/dist/environment/heads.js.map +1 -0
- package/dist/factory.d.ts +18 -4
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +89 -15
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/integrations/base.d.ts +17 -2
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/commits.d.ts +11 -0
- package/dist/integrations/github/commits.d.ts.map +1 -1
- package/dist/integrations/github/commits.js +20 -1
- package/dist/integrations/github/commits.js.map +1 -1
- package/dist/integrations/github/config.d.ts +3 -3
- package/dist/integrations/github/config.d.ts.map +1 -1
- package/dist/integrations/github/config.js +1 -1
- package/dist/integrations/github/config.js.map +1 -1
- package/dist/integrations/github/routes.d.ts +2 -2
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +6 -5
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/rules.d.ts +3 -1
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +31 -1
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +35 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +203 -2
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/session-subscriptions.js +117 -62
- package/dist/integrations/github/session-subscriptions.js.map +1 -1
- package/dist/integrations/github/token-refresh.d.ts +7 -0
- package/dist/integrations/github/token-refresh.d.ts.map +1 -1
- package/dist/integrations/github/token-refresh.js.map +1 -1
- package/dist/integrations/github/webhook.js.map +1 -1
- package/dist/integrations/gitlab/agent-tools.js +1 -1
- package/dist/integrations/gitlab/routes.d.ts +2 -2
- package/dist/integrations/gitlab/routes.d.ts.map +1 -1
- package/dist/integrations/gitlab/routes.js.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.js +8 -7
- package/dist/integrations/gitlab/session-subscriptions.js.map +1 -1
- package/dist/integrations/incidentio/agent-tools.js +1 -1
- package/dist/integrations/jira/agent-tools.js +1 -1
- package/dist/integrations/linear/agent-tools.js +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +46 -2
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/jira/agent-tools.js +1 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +15 -16
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/integrations/subscription-session.js +1 -1
- package/dist/packages/_internals/workspace/dist/index.js +21 -1
- package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
- package/dist/routes/contracts.d.ts +386 -2
- package/dist/routes/contracts.d.ts.map +1 -1
- package/dist/routes/contracts.js +166 -1
- package/dist/routes/contracts.js.map +1 -1
- package/dist/routes/fs.d.ts +25 -0
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +142 -46
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/projects.d.ts +6 -0
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +344 -1
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/source-control-sessions.d.ts +2 -0
- package/dist/routes/source-control-sessions.d.ts.map +1 -1
- package/dist/routes/source-control-sessions.js +36 -1
- package/dist/routes/source-control-sessions.js.map +1 -1
- package/dist/routes/supervisor.js +1 -1
- package/dist/routes/surface.d.ts +6 -3
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +21 -34
- package/dist/routes/surface.js.map +1 -1
- package/dist/rules/binding-context.d.ts +1 -1
- package/dist/rules/binding-context.d.ts.map +1 -1
- package/dist/rules/binding-context.js +1 -1
- package/dist/rules/binding-context.js.map +1 -1
- package/dist/rules/review-source-tool.js +1 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +7 -2
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/rules/tools.js +1 -1
- package/dist/sandbox/callback-factory-sandbox.d.ts +15 -0
- package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -0
- package/dist/sandbox/callback-factory-sandbox.js +22 -0
- package/dist/sandbox/callback-factory-sandbox.js.map +1 -0
- package/dist/sandbox/local-factory-sandbox.d.ts +20 -0
- package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -0
- package/dist/sandbox/local-factory-sandbox.js +27 -0
- package/dist/sandbox/local-factory-sandbox.js.map +1 -0
- package/dist/sandbox/session-retirement.d.ts.map +1 -1
- package/dist/sandbox/session-retirement.js +23 -3
- package/dist/sandbox/session-retirement.js.map +1 -1
- package/dist/sandbox/session-sandbox.d.ts +82 -40
- package/dist/sandbox/session-sandbox.d.ts.map +1 -1
- package/dist/sandbox/session-sandbox.js +130 -13
- package/dist/sandbox/session-sandbox.js.map +1 -1
- package/dist/sandbox/workdir.d.ts +10 -0
- package/dist/sandbox/workdir.d.ts.map +1 -1
- package/dist/sandbox/workdir.js +10 -1
- package/dist/sandbox/workdir.js.map +1 -1
- package/dist/session/environment-repositories.d.ts +31 -0
- package/dist/session/environment-repositories.d.ts.map +1 -0
- package/dist/session/environment-repositories.js +89 -0
- package/dist/session/environment-repositories.js.map +1 -0
- package/dist/session/environment-state-processor.d.ts +59 -0
- package/dist/session/environment-state-processor.d.ts.map +1 -0
- package/dist/session/environment-state-processor.js +105 -0
- package/dist/session/environment-state-processor.js.map +1 -0
- package/dist/session/factory-session.d.ts +26 -35
- package/dist/session/factory-session.d.ts.map +1 -1
- package/dist/session/factory-session.js +34 -71
- package/dist/session/factory-session.js.map +1 -1
- package/dist/session/filesystem-capture.d.ts +13 -0
- package/dist/session/filesystem-capture.d.ts.map +1 -1
- package/dist/session/filesystem-capture.js +73 -14
- package/dist/session/filesystem-capture.js.map +1 -1
- package/dist/session/source-control-tools.d.ts +1 -1
- package/dist/session/source-control-tools.d.ts.map +1 -1
- package/dist/session/source-control-tools.js +144 -71
- package/dist/session/source-control-tools.js.map +1 -1
- package/dist/spa-static.js +2 -2
- package/dist/storage/domains/audit/agent-audit.d.ts +6 -1
- package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -1
- package/dist/storage/domains/audit/agent-audit.js +31 -13
- package/dist/storage/domains/audit/agent-audit.js.map +1 -1
- package/dist/storage/domains/projects/base.d.ts +115 -2
- package/dist/storage/domains/projects/base.d.ts.map +1 -1
- package/dist/storage/domains/projects/base.js +219 -12
- package/dist/storage/domains/projects/base.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +123 -7
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +406 -33
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +19 -6
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +90 -2
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +12 -5
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/supervisor/read-tools.js +1 -1
- package/dist/supervisor/write-tools.js +1 -1
- package/dist/workspace.d.ts +50 -7
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +344 -24
- package/dist/workspace.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.js","names":["#versionControlIntegrationIds","#projects","#sourceControl","#handles","#project","#findConnection","#findProjectRepository","#repositoryPayload","#retireProjectRepositorySessions","#resolveTenant"],"sources":["../../src/routes/projects.ts"],"sourcesContent":["import type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\nimport type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type {\n ProjectRepository,\n SourceControlRepository,\n SourceControlStorage,\n SourceControlStorageHandle,\n UpdateProjectRepositoryInput,\n} from '../storage/domains/source-control/base.js';\nimport { ACTIVE_RUN_BINDING_STAGES } from '../storage/domains/work-items/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { FACTORY_ROUTE_CONTRACTS } from './contracts.js';\nimport type { RouteDependencies } from './route.js';\nimport { Route } from './route.js';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst MAX_NAME_LENGTH = 200;\nconst MAX_REPOSITORY_COMMAND_LENGTH = 2_000;\nconst MAX_BRANCH_LENGTH = 255;\nconst MAX_SANDBOX_PROVIDER_LENGTH = 100;\nconst MAX_SANDBOX_WORKDIR_LENGTH = 1_000;\nconst CONTROL_CHAR_RE = /[\\0-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/;\n\nfunction loose(context: unknown): Context {\n return context as Context;\n}\n\nasync function readJson(context: Context): Promise<unknown | undefined> {\n try {\n return await context.req.json();\n } catch {\n return undefined;\n }\n}\n\nfunction parseConnectionInput(value: unknown): { integrationId: string; installationId: string } | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n if (typeof input.integrationId !== 'string' || !input.integrationId.trim()) return null;\n if (typeof input.installationId !== 'string' || !UUID_RE.test(input.installationId)) return null;\n return { integrationId: input.integrationId.trim(), installationId: input.installationId };\n}\n\nfunction parseOptionalString(\n value: unknown,\n { maxLength, nullable = false }: { maxLength: number; nullable?: boolean },\n): string | null | undefined | false {\n if (value === undefined) return undefined;\n if (value === null) return nullable ? null : false;\n if (typeof value !== 'string') return false;\n const normalized = value.trim();\n if (!normalized) return nullable ? null : false;\n if (normalized.length > maxLength || CONTROL_CHAR_RE.test(normalized)) return false;\n return normalized;\n}\n\nfunction parseRepositoryLinkInput(value: unknown): {\n repositoryId?: string;\n repository?: { externalId: string; slug: string };\n branch: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand: string | null;\n teardownCommand: string | null;\n} | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const repositoryId =\n typeof input.repositoryId === 'string' && UUID_RE.test(input.repositoryId) ? input.repositoryId : undefined;\n const repositoryInput = input.repository;\n let repository: { externalId: string; slug: string } | undefined;\n if (repositoryInput && typeof repositoryInput === 'object') {\n const candidate = repositoryInput as Record<string, unknown>;\n const externalId = parseOptionalString(candidate.externalId, { maxLength: MAX_NAME_LENGTH });\n const slug = parseOptionalString(candidate.slug, { maxLength: MAX_NAME_LENGTH });\n if (typeof externalId !== 'string' || typeof slug !== 'string') return null;\n repository = { externalId, slug };\n }\n if (!repositoryId && !repository) return null;\n const branch = parseOptionalString(input.branch, { maxLength: MAX_BRANCH_LENGTH, nullable: true });\n const sandboxProvider = parseOptionalString(input.sandboxProvider, { maxLength: MAX_SANDBOX_PROVIDER_LENGTH });\n const sandboxWorkdir = parseOptionalString(input.sandboxWorkdir, { maxLength: MAX_SANDBOX_WORKDIR_LENGTH });\n const setupCommand = parseOptionalString(input.setupCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n const teardownCommand = parseOptionalString(input.teardownCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n if (\n branch === false ||\n typeof sandboxProvider !== 'string' ||\n typeof sandboxWorkdir !== 'string' ||\n setupCommand === false ||\n teardownCommand === false\n )\n return null;\n return {\n ...(repositoryId ? { repositoryId } : {}),\n ...(repository ? { repository } : {}),\n branch: branch ?? null,\n sandboxProvider,\n sandboxWorkdir,\n setupCommand: setupCommand ?? null,\n teardownCommand: teardownCommand ?? null,\n };\n}\n\nfunction parseRepositoryUpdateInput(value: unknown): UpdateProjectRepositoryInput | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const patch: UpdateProjectRepositoryInput = {};\n const branch = parseOptionalString(input.branch, { maxLength: MAX_BRANCH_LENGTH, nullable: true });\n const sandboxProvider = parseOptionalString(input.sandboxProvider, { maxLength: MAX_SANDBOX_PROVIDER_LENGTH });\n const sandboxWorkdir = parseOptionalString(input.sandboxWorkdir, { maxLength: MAX_SANDBOX_WORKDIR_LENGTH });\n const setupCommand = parseOptionalString(input.setupCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n const teardownCommand = parseOptionalString(input.teardownCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n if (\n branch === false ||\n sandboxProvider === false ||\n sandboxProvider === null ||\n sandboxWorkdir === false ||\n sandboxWorkdir === null ||\n setupCommand === false ||\n teardownCommand === false\n )\n return null;\n if (branch !== undefined) patch.branch = branch;\n if (sandboxProvider !== undefined) patch.sandboxProvider = sandboxProvider;\n if (sandboxWorkdir !== undefined) patch.sandboxWorkdir = sandboxWorkdir;\n if (setupCommand !== undefined) patch.setupCommand = setupCommand;\n if (teardownCommand !== undefined) patch.teardownCommand = teardownCommand;\n return Object.keys(patch).length > 0 ? patch : null;\n}\n\ninterface ModelApplySession {\n thread: {\n getById: (args: { threadId: string }) => Promise<{ metadata?: Record<string, unknown> | null } | null>;\n setSettingOn: (args: { threadId: string; key: string; value: unknown }) => Promise<unknown> | unknown;\n };\n}\n\ninterface ModelApplyController {\n getSessionByResource: (resourceId: string) => Promise<ModelApplySession | undefined>;\n}\n\nexport interface ProjectRoutesDeps extends RouteDependencies {\n /** Factory projects domain backing the CRUD surface. */\n projects: FactoryProjectsStorage;\n /** Source-control domain the connection/repository routes fan out over. */\n sourceControl: SourceControlStorage;\n /** Integration ids allowed as source-control connection targets. */\n versionControlIntegrationIds?: string[];\n /** Validate and persist a repository selected from a provider-backed listing. */\n resolveRepository?: (input: {\n integrationId: string;\n orgId: string;\n userId: string;\n installationId: string;\n externalId: string;\n slug: string;\n }) => Promise<SourceControlRepository | null>;\n /**\n * Fire-and-forget hook invoked after a repository is linked to a project —\n * kicks the initial base-checkpoint build. Must never throw.\n */\n onProjectRepositoryLinked?: (args: { orgId: string; projectRepository: ProjectRepository }) => void;\n /** Shared lifecycle for retiring sessions before their owning records are deleted. */\n sessionRetirement?: SessionRetirementCoordinator;\n /** Work-items domain used by session retirement and running-thread model updates. */\n workItems?: Pick<WorkItemsStorage, 'clearSessionReferences' | 'listRunBindings' | 'get'>;\n /** Controller used to reach the thread store behind each active binding. */\n controller?: ModelApplyController;\n}\n\nexport class ProjectRoutes extends Route<ProjectRoutesDeps> {\n readonly #versionControlIntegrationIds: Set<string>;\n\n constructor(deps: ProjectRoutesDeps) {\n super(deps);\n this.#versionControlIntegrationIds = new Set(deps.versionControlIntegrationIds ?? []);\n }\n\n async #projects(): Promise<FactoryProjectsStorage> {\n await this.deps.projects.ensureReady();\n return this.deps.projects;\n }\n\n async #sourceControl(): Promise<SourceControlStorage> {\n await this.deps.sourceControl.ensureReady();\n return this.deps.sourceControl;\n }\n\n async #handles(): Promise<SourceControlStorageHandle[]> {\n const storage = await this.#sourceControl();\n return [...this.#versionControlIntegrationIds].map(integrationId => storage.forIntegration(integrationId));\n }\n\n async #project(orgId: string, id: string) {\n return (await this.#projects()).get({ orgId, id });\n }\n\n async #findConnection({ orgId, projectId, id }: { orgId: string; projectId: string; id: string }) {\n for (const handle of await this.#handles()) {\n const connection = await handle.connections.get({ orgId, id });\n if (connection?.factoryProjectId === projectId) return { handle, connection };\n }\n return null;\n }\n\n async #findProjectRepository({ orgId, projectId, id }: { orgId: string; projectId: string; id: string }) {\n for (const handle of await this.#handles()) {\n const projectRepository = await handle.projectRepositories.get({ orgId, id });\n if (!projectRepository) continue;\n const connection = await handle.connections.get({ orgId, id: projectRepository.connectionId });\n if (connection?.factoryProjectId === projectId) return { handle, connection, projectRepository };\n }\n return null;\n }\n\n async #repositoryPayload(handle: SourceControlStorageHandle, orgId: string, projectRepository: ProjectRepository) {\n const repository = await handle.repositories.get({ orgId, id: projectRepository.repositoryId });\n return { ...projectRepository, repository };\n }\n\n async #retireProjectRepositorySessions(\n handle: SourceControlStorageHandle,\n orgId: string,\n projectRepositoryId: string,\n ): Promise<boolean> {\n const sessions = await handle.sessions.listByProjectRepository({ projectRepositoryId });\n if (sessions.length === 0) return true;\n if (!this.deps.sessionRetirement) return false;\n await this.deps.sessionRetirement.retireProjectRepositorySessions({\n sourceControl: handle,\n ...(this.deps.workItems ? { workItems: this.deps.workItems } : {}),\n orgId,\n projectRepositoryId,\n });\n return true;\n }\n\n async #resolveTenant(context: Context): Promise<{ orgId: string; userId: string } | { response: Response }> {\n await this.deps.auth.ensureUser(context);\n const tenant = this.deps.auth.tenant(context);\n if (!tenant) return { response: context.json({ error: 'unauthorized' }, 401) };\n if (!tenant.orgId) {\n return {\n response: context.json(\n { error: 'organization_required', message: 'Factory projects require an organization.' },\n 403,\n ),\n };\n }\n return { orgId: tenant.orgId, userId: tenant.userId };\n }\n\n routes(): ApiRoute[] {\n return [\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectList.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectList.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n return context.json({ projects: await (await this.#projects()).list({ orgId: tenant.orgId }) });\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectCreate.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectCreate.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsed = FACTORY_ROUTE_CONTRACTS.projectCreate.bodySchema.safeParse(await readJson(context));\n if (!parsed.success) return context.json({ error: 'invalid_project' }, 400);\n const project = await (\n await this.#projects()\n ).create({ orgId: tenant.orgId, userId: tenant.userId, input: parsed.data });\n return context.json({ project }, 201);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectGet.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectGet.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectGet.pathSchema.safeParse({ id: context.req.param('id') });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const { id } = parsedPath.data;\n const project = await this.#project(tenant.orgId, id);\n return project ? context.json({ project }) : context.json({ error: 'Project not found' }, 404);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectUpdate.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectUpdate.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectUpdate.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const parsedBody = FACTORY_ROUTE_CONTRACTS.projectUpdate.bodySchema.safeParse(await readJson(context));\n if (!parsedBody.success) return context.json({ error: 'invalid_project' }, 400);\n const project = await (\n await this.#projects()\n ).update({ orgId: tenant.orgId, id: parsedPath.data.id, input: parsedBody.data });\n return project ? context.json({ project }) : context.json({ error: 'Project not found' }, 404);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n if (!(await this.deps.auth.isOrganizationAdmin(context, tenant.orgId))) {\n return context.json(\n {\n error: 'forbidden',\n message: 'Organization administrator access is required to update running sessions.',\n },\n 403,\n );\n }\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, parsedPath.data.id);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const modelId = project.defaultModelId;\n if (!modelId) {\n return context.json(\n { error: 'default_model_not_set', message: 'Set a default model on the project first.' },\n 400,\n );\n }\n const { workItems, controller } = this.deps;\n if (!workItems || !controller) return context.json({ error: 'model_apply_unavailable' }, 503);\n\n const bindings = (await workItems.listRunBindings(tenant.orgId, project.id)).filter(\n binding => binding.status === 'active',\n );\n const seen = new Set<string>();\n const applied: string[] = [];\n const skipped: Array<{\n threadId: string;\n reason:\n | 'not-running'\n | 'work-item-missing'\n | 'stage-inactive'\n | 'thread-missing'\n | 'mode-unknown'\n | 'apply-failed';\n }> = [];\n\n for (const binding of bindings) {\n const key = `${binding.sessionId}:${binding.threadId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const item = await workItems.get({ orgId: tenant.orgId, id: binding.workItemId });\n if (!item || item.factoryProjectId !== project.id) {\n skipped.push({ threadId: binding.threadId, reason: 'work-item-missing' });\n continue;\n }\n if (!ACTIVE_RUN_BINDING_STAGES.has(item.stages[0] ?? '')) {\n skipped.push({ threadId: binding.threadId, reason: 'stage-inactive' });\n continue;\n }\n const session = await controller.getSessionByResource(binding.resourceId);\n if (!session) {\n skipped.push({ threadId: binding.threadId, reason: 'not-running' });\n continue;\n }\n const thread = await session.thread.getById({ threadId: binding.threadId });\n if (!thread) {\n skipped.push({ threadId: binding.threadId, reason: 'thread-missing' });\n continue;\n }\n try {\n // This route targets inactive bound threads, so persist the controller-owned key through the session gateway.\n await session.thread.setSettingOn({\n threadId: binding.threadId,\n key: 'currentModelId',\n value: modelId,\n });\n applied.push(binding.threadId);\n } catch (error) {\n console.warn('[factory] apply-default-model failed for thread', binding.threadId, error);\n skipped.push({ threadId: binding.threadId, reason: 'apply-failed' });\n }\n }\n\n return context.json({ modelId, applied, skipped });\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectDelete.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectDelete.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectDelete.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const { id } = parsedPath.data;\n if (!(await this.#project(tenant.orgId, id))) return context.json({ error: 'Project not found' }, 404);\n for (const handle of await this.#handles()) {\n for (const connection of await handle.connections.list({ orgId: tenant.orgId, factoryProjectId: id })) {\n for (const projectRepository of await handle.projectRepositories.list({\n orgId: tenant.orgId,\n connectionId: connection.id,\n })) {\n if (!(await this.#retireProjectRepositorySessions(handle, tenant.orgId, projectRepository.id))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n }\n await handle.connections.delete({ orgId: tenant.orgId, id: connection.id });\n }\n }\n await (await this.#projects()).delete({ orgId: tenant.orgId, id });\n return context.body(null, 204);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections', {\n method: 'GET',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId) || !(await this.#project(tenant.orgId, projectId)))\n return context.json({ error: 'Project not found' }, 404);\n const connections = [];\n for (const handle of await this.#handles()) {\n for (const connection of await handle.connections.list({\n orgId: tenant.orgId,\n factoryProjectId: projectId,\n })) {\n const installation = await handle.installations.get({\n orgId: tenant.orgId,\n id: connection.installationId,\n });\n // Skip orphaned connections whose installation was pruned (e.g.\n // the user uninstalled the GitHub App). Otherwise\n // `projectRepositories.list` throws `requireConnection` and the\n // whole endpoint 500s, which hangs the web UI on the page\n // loader for every project. New code cascade-deletes these on\n // installation removal, but this defensive skip lets already-\n // orphaned rows in existing databases self-heal on read.\n if (!installation) continue;\n const links = await handle.projectRepositories.list({ orgId: tenant.orgId, connectionId: connection.id });\n connections.push({\n ...connection,\n installation,\n repositories: await Promise.all(links.map(link => this.#repositoryPayload(handle, tenant.orgId, link))),\n });\n }\n }\n return context.json({ connections });\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections', {\n method: 'POST',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId) || !(await this.#project(tenant.orgId, projectId)))\n return context.json({ error: 'Project not found' }, 404);\n const input = parseConnectionInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_source_control_connection' }, 400);\n if (!this.#versionControlIntegrationIds.has(input.integrationId))\n return context.json({ error: 'Source-control integration not found' }, 404);\n const handle = (await this.#sourceControl()).forIntegration(input.integrationId);\n if (!(await handle.installations.get({ orgId: tenant.orgId, id: input.installationId })))\n return context.json({ error: 'Source-control installation not found' }, 404);\n const connection = await handle.connections.create({\n orgId: tenant.orgId,\n factoryProjectId: projectId,\n installationId: input.installationId,\n createdByUserId: tenant.userId,\n });\n return context.json({ connection }, 201);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections/:connectionId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const connectionId = context.req.param('connectionId');\n if (!projectId || !UUID_RE.test(projectId) || !connectionId || !UUID_RE.test(connectionId))\n return context.json({ error: 'Source-control connection not found' }, 404);\n const found = await this.#findConnection({ orgId: tenant.orgId, projectId, id: connectionId });\n if (!found) return context.json({ error: 'Source-control connection not found' }, 404);\n for (const projectRepository of await found.handle.projectRepositories.list({\n orgId: tenant.orgId,\n connectionId,\n })) {\n if (!(await this.#retireProjectRepositorySessions(found.handle, tenant.orgId, projectRepository.id))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n }\n await found.handle.connections.delete({ orgId: tenant.orgId, id: connectionId });\n return context.body(null, 204);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections/:connectionId/repositories', {\n method: 'POST',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const connectionId = context.req.param('connectionId');\n if (!projectId || !UUID_RE.test(projectId) || !connectionId || !UUID_RE.test(connectionId))\n return context.json({ error: 'Source-control connection not found' }, 404);\n const found = await this.#findConnection({ orgId: tenant.orgId, projectId, id: connectionId });\n if (!found) return context.json({ error: 'Source-control connection not found' }, 404);\n const input = parseRepositoryLinkInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_project_repository' }, 400);\n const repository = input.repositoryId\n ? await found.handle.repositories.get({ orgId: tenant.orgId, id: input.repositoryId })\n : input.repository && this.deps.resolveRepository\n ? await this.deps.resolveRepository({\n integrationId: found.connection.integrationId,\n orgId: tenant.orgId,\n userId: tenant.userId,\n installationId: found.connection.installationId,\n ...input.repository,\n })\n : null;\n if (!repository || repository.installationId !== found.connection.installationId)\n return context.json({ error: 'Source-control repository not found' }, 404);\n const { repositoryId: _repositoryId, repository: _repository, ...linkInput } = input;\n const projectRepository = await found.handle.projectRepositories.link({\n orgId: tenant.orgId,\n connectionId,\n createdByUserId: tenant.userId,\n repositoryId: repository.id,\n ...linkInput,\n });\n try {\n this.deps.onProjectRepositoryLinked?.({ orgId: tenant.orgId, projectRepository });\n } catch (error) {\n console.warn('[factory] onProjectRepositoryLinked failed after a successful repository link:', error);\n }\n return context.json(\n { projectRepository: await this.#repositoryPayload(found.handle, tenant.orgId, projectRepository) },\n 201,\n );\n },\n }),\n registerApiRoute('/web/factory/projects/:id/repositories/:projectRepositoryId', {\n method: 'PATCH',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const projectRepositoryId = context.req.param('projectRepositoryId');\n if (!projectId || !UUID_RE.test(projectId) || !projectRepositoryId || !UUID_RE.test(projectRepositoryId))\n return context.json({ error: 'Project repository not found' }, 404);\n const found = await this.#findProjectRepository({ orgId: tenant.orgId, projectId, id: projectRepositoryId });\n if (!found) return context.json({ error: 'Project repository not found' }, 404);\n const input = parseRepositoryUpdateInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_project_repository' }, 400);\n const projectRepository = await found.handle.projectRepositories.update({\n orgId: tenant.orgId,\n id: projectRepositoryId,\n input,\n });\n return context.json({\n projectRepository: await this.#repositoryPayload(found.handle, tenant.orgId, projectRepository!),\n });\n },\n }),\n registerApiRoute('/web/factory/projects/:id/repositories/:projectRepositoryId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const projectRepositoryId = context.req.param('projectRepositoryId');\n if (!projectId || !UUID_RE.test(projectId) || !projectRepositoryId || !UUID_RE.test(projectRepositoryId))\n return context.json({ error: 'Project repository not found' }, 404);\n const found = await this.#findProjectRepository({ orgId: tenant.orgId, projectId, id: projectRepositoryId });\n if (!found) return context.json({ error: 'Project repository not found' }, 404);\n if (!(await this.#retireProjectRepositorySessions(found.handle, tenant.orgId, projectRepositoryId))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n await found.handle.projectRepositories.unlink({ orgId: tenant.orgId, id: projectRepositoryId });\n return context.body(null, 204);\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"projects.js","names":["#versionControlIntegrationIds","#sandboxDescription","#mergeSettings","#settingsSchema","#describeSandbox","#projects","#sourceControl","#handles","#project","#findConnection","#findProjectRepository","#repositoryPayload","#environmentLinks","#environmentPayload","#buildPayload","#resolveTenant","#builds","#dropSchedule","#retireProjectRepositorySessions","#buildRoutes"],"sources":["../../src/routes/projects.ts"],"sourcesContent":["import { MastraError } from '@mastra/core/error';\nimport type { StandardSchemaWithJSON } from '@mastra/core/schema';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport { describeFactorySandbox, normalizeFactorySandboxSettings } from '@mastra/core/workspace';\nimport type { FactorySandbox, FactorySandboxDescription } from '@mastra/core/workspace';\nimport type { Context } from 'hono';\n\nimport type { EnvironmentBuildRunner } from '../environment/build-runner.js';\nimport { ensureSchedule, invalidCronMessage, readSchedule, scheduleIdFor } from '../environment/build-schedule.js';\nimport { redactCredentials } from '../environment/build.js';\nimport type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';\nimport type {\n FactoryProject,\n FactoryProjectsStorage,\n UpdateFactoryProjectInput,\n} from '../storage/domains/projects/base.js';\nimport type {\n ProjectRepository,\n SourceControlRepository,\n SourceControlStorage,\n SourceControlStorageHandle,\n UpdateProjectRepositoryInput,\n} from '../storage/domains/source-control/base.js';\nimport { ACTIVE_RUN_BINDING_STAGES } from '../storage/domains/work-items/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { FACTORY_ROUTE_CONTRACTS } from './contracts.js';\nimport type { RouteDependencies } from './route.js';\nimport { Route } from './route.js';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst MAX_NAME_LENGTH = 200;\nconst MAX_REPOSITORY_COMMAND_LENGTH = 2_000;\nconst MAX_BRANCH_LENGTH = 255;\nconst MAX_SANDBOX_PROVIDER_LENGTH = 100;\nconst MAX_SANDBOX_WORKDIR_LENGTH = 1_000;\nconst CONTROL_CHAR_RE = /[\\0-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/;\n\nfunction loose(context: unknown): Context {\n return context as Context;\n}\n\nasync function readJson(context: Context): Promise<unknown | undefined> {\n try {\n return await context.req.json();\n } catch {\n return undefined;\n }\n}\n\nfunction parseConnectionInput(value: unknown): { integrationId: string; installationId: string } | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n if (typeof input.integrationId !== 'string' || !input.integrationId.trim()) return null;\n if (typeof input.installationId !== 'string' || !UUID_RE.test(input.installationId)) return null;\n return { integrationId: input.integrationId.trim(), installationId: input.installationId };\n}\n\nfunction parseOptionalString(\n value: unknown,\n { maxLength, nullable = false }: { maxLength: number; nullable?: boolean },\n): string | null | undefined | false {\n if (value === undefined) return undefined;\n if (value === null) return nullable ? null : false;\n if (typeof value !== 'string') return false;\n const normalized = value.trim();\n if (!normalized) return nullable ? null : false;\n if (normalized.length > maxLength || CONTROL_CHAR_RE.test(normalized)) return false;\n return normalized;\n}\n\nfunction parseRepositoryLinkInput(value: unknown): {\n repositoryId?: string;\n repository?: { externalId: string; slug: string };\n branch: string | null;\n sandboxProvider: string;\n sandboxWorkdir: string;\n setupCommand: string | null;\n teardownCommand: string | null;\n} | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const repositoryId =\n typeof input.repositoryId === 'string' && UUID_RE.test(input.repositoryId) ? input.repositoryId : undefined;\n const repositoryInput = input.repository;\n let repository: { externalId: string; slug: string } | undefined;\n if (repositoryInput && typeof repositoryInput === 'object') {\n const candidate = repositoryInput as Record<string, unknown>;\n const externalId = parseOptionalString(candidate.externalId, { maxLength: MAX_NAME_LENGTH });\n const slug = parseOptionalString(candidate.slug, { maxLength: MAX_NAME_LENGTH });\n if (typeof externalId !== 'string' || typeof slug !== 'string') return null;\n repository = { externalId, slug };\n }\n if (!repositoryId && !repository) return null;\n const branch = parseOptionalString(input.branch, { maxLength: MAX_BRANCH_LENGTH, nullable: true });\n const sandboxProvider = parseOptionalString(input.sandboxProvider, { maxLength: MAX_SANDBOX_PROVIDER_LENGTH });\n const sandboxWorkdir = parseOptionalString(input.sandboxWorkdir, { maxLength: MAX_SANDBOX_WORKDIR_LENGTH });\n const setupCommand = parseOptionalString(input.setupCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n const teardownCommand = parseOptionalString(input.teardownCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n if (\n branch === false ||\n typeof sandboxProvider !== 'string' ||\n typeof sandboxWorkdir !== 'string' ||\n setupCommand === false ||\n teardownCommand === false\n )\n return null;\n return {\n ...(repositoryId ? { repositoryId } : {}),\n ...(repository ? { repository } : {}),\n branch: branch ?? null,\n sandboxProvider,\n sandboxWorkdir,\n setupCommand: setupCommand ?? null,\n teardownCommand: teardownCommand ?? null,\n };\n}\n\nfunction parseRepositoryUpdateInput(value: unknown): UpdateProjectRepositoryInput | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const patch: UpdateProjectRepositoryInput = {};\n const branch = parseOptionalString(input.branch, { maxLength: MAX_BRANCH_LENGTH, nullable: true });\n const sandboxProvider = parseOptionalString(input.sandboxProvider, { maxLength: MAX_SANDBOX_PROVIDER_LENGTH });\n const sandboxWorkdir = parseOptionalString(input.sandboxWorkdir, { maxLength: MAX_SANDBOX_WORKDIR_LENGTH });\n const setupCommand = parseOptionalString(input.setupCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n const teardownCommand = parseOptionalString(input.teardownCommand, {\n maxLength: MAX_REPOSITORY_COMMAND_LENGTH,\n nullable: true,\n });\n if (\n branch === false ||\n sandboxProvider === false ||\n sandboxProvider === null ||\n sandboxWorkdir === false ||\n sandboxWorkdir === null ||\n setupCommand === false ||\n teardownCommand === false\n )\n return null;\n if (branch !== undefined) patch.branch = branch;\n if (sandboxProvider !== undefined) patch.sandboxProvider = sandboxProvider;\n if (sandboxWorkdir !== undefined) patch.sandboxWorkdir = sandboxWorkdir;\n if (setupCommand !== undefined) patch.setupCommand = setupCommand;\n if (teardownCommand !== undefined) patch.teardownCommand = teardownCommand;\n return Object.keys(patch).length > 0 ? patch : null;\n}\n\ninterface ModelApplySession {\n thread: {\n getById: (args: { threadId: string }) => Promise<{ metadata?: Record<string, unknown> | null } | null>;\n setSettingOn: (args: { threadId: string; key: string; value: unknown }) => Promise<unknown> | unknown;\n };\n}\n\ninterface ModelApplyController {\n getSessionByResource: (resourceId: string) => Promise<ModelApplySession | undefined>;\n}\n\nexport interface ProjectRoutesDeps extends RouteDependencies {\n /** Factory projects domain backing the CRUD surface. */\n projects: FactoryProjectsStorage;\n /** Source-control domain the connection/repository routes fan out over. */\n sourceControl: SourceControlStorage;\n /** Integration ids allowed as source-control connection targets. */\n versionControlIntegrationIds?: string[];\n /** Validate and persist a repository selected from a provider-backed listing. */\n resolveRepository?: (input: {\n integrationId: string;\n orgId: string;\n userId: string;\n installationId: string;\n externalId: string;\n slug: string;\n }) => Promise<SourceControlRepository | null>;\n /**\n * Fire-and-forget hook invoked after a repository is linked to a project —\n * kicks the initial base-checkpoint build. Must never throw.\n */\n onProjectRepositoryLinked?: (args: { orgId: string; projectRepository: ProjectRepository }) => void;\n /** Shared lifecycle for retiring sessions before their owning records are deleted. */\n sessionRetirement?: SessionRetirementCoordinator;\n /** Work-items domain used by session retirement and running-thread model updates. */\n workItems?: Pick<WorkItemsStorage, 'clearSessionReferences' | 'listRunBindings' | 'get'>;\n /** Controller used to reach the thread store behind each active binding. */\n controller?: ModelApplyController;\n /** The factory's normalized sandbox; describes and validates the environment settings. */\n sandbox?: FactorySandbox;\n /** Environment builds, present only when the sandbox has a `builds` capability. */\n environmentBuilds?: EnvironmentBuildRunner;\n}\n\n/** Provider output is shown to the user; strip any clone credential from it first. */\nfunction redactBuild<T extends { error?: string; logs?: string[] }>(build: T): T {\n return {\n ...build,\n ...(build.error !== undefined ? { error: redactCredentials(build.error) } : {}),\n ...(build.logs ? { logs: build.logs.map(redactCredentials) } : {}),\n };\n}\n\n/** What the environment reports when the factory has no sandbox configured. */\nconst NO_SANDBOX: FactorySandboxDescription = {\n provider: 'none',\n settingsSchema: { type: 'object', properties: {}, additionalProperties: false },\n capabilities: { template: false, builds: { available: false, history: false } },\n};\n\nexport class ProjectRoutes extends Route<ProjectRoutesDeps> {\n readonly #versionControlIntegrationIds: Set<string>;\n #sandboxDescription: FactorySandboxDescription | undefined;\n #settingsSchema: StandardSchemaWithJSON | undefined;\n\n constructor(deps: ProjectRoutesDeps) {\n super(deps);\n this.#versionControlIntegrationIds = new Set(deps.versionControlIntegrationIds ?? []);\n }\n\n #describeSandbox(): FactorySandboxDescription {\n if (!this.deps.sandbox) return NO_SANDBOX;\n this.#sandboxDescription ??= describeFactorySandbox(this.deps.sandbox);\n return this.#sandboxDescription;\n }\n\n /**\n * Merge a settings patch onto the stored document (null removes a key) and\n * validate the result through the sandbox's schema. Returns the issues when\n * the merged document is rejected.\n *\n * A stored key the current schema does not declare is left over from another\n * provider or an older schema. When the merged document fails validation, the\n * merge retries without those keys so one stale value cannot lock every later\n * update; keys the patch itself sets are never pruned.\n */\n async #mergeSettings(\n stored: Record<string, unknown>,\n patch: Record<string, unknown | null>,\n ): Promise<\n { merged: Record<string, unknown> | null } | { issues: ReadonlyArray<{ message: string; path?: unknown }> }\n > {\n const merged: Record<string, unknown> = { ...stored };\n for (const [key, value] of Object.entries(patch)) {\n if (value === null) delete merged[key];\n else merged[key] = value;\n }\n this.#settingsSchema ??= normalizeFactorySandboxSettings(this.deps.sandbox!);\n const result = await this.#settingsSchema['~standard'].validate(merged);\n if (!result.issues) return { merged: Object.keys(merged).length > 0 ? merged : null };\n\n const declared = this.#describeSandbox().settingsSchema.properties ?? {};\n const pruned = Object.fromEntries(\n Object.entries(merged).filter(([key]) => key in patch || Object.hasOwn(declared, key)),\n );\n if (Object.keys(pruned).length === Object.keys(merged).length) return { issues: result.issues };\n const retried = await this.#settingsSchema['~standard'].validate(pruned);\n if (retried.issues) return { issues: result.issues };\n return { merged: Object.keys(pruned).length > 0 ? pruned : null };\n }\n\n async #projects(): Promise<FactoryProjectsStorage> {\n await this.deps.projects.ensureReady();\n return this.deps.projects;\n }\n\n async #sourceControl(): Promise<SourceControlStorage> {\n await this.deps.sourceControl.ensureReady();\n return this.deps.sourceControl;\n }\n\n async #handles(): Promise<SourceControlStorageHandle[]> {\n const storage = await this.#sourceControl();\n return [...this.#versionControlIntegrationIds].map(integrationId => storage.forIntegration(integrationId));\n }\n\n async #project(orgId: string, id: string) {\n return (await this.#projects()).get({ orgId, id });\n }\n\n async #findConnection({ orgId, projectId, id }: { orgId: string; projectId: string; id: string }) {\n for (const handle of await this.#handles()) {\n const connection = await handle.connections.get({ orgId, id });\n if (connection?.factoryProjectId === projectId) return { handle, connection };\n }\n return null;\n }\n\n async #findProjectRepository({ orgId, projectId, id }: { orgId: string; projectId: string; id: string }) {\n for (const handle of await this.#handles()) {\n const projectRepository = await handle.projectRepositories.get({ orgId, id });\n if (!projectRepository) continue;\n const connection = await handle.connections.get({ orgId, id: projectRepository.connectionId });\n if (connection?.factoryProjectId === projectId) return { handle, connection, projectRepository };\n }\n return null;\n }\n\n async #repositoryPayload(handle: SourceControlStorageHandle, orgId: string, projectRepository: ProjectRepository) {\n const repository = await handle.repositories.get({ orgId, id: projectRepository.repositoryId });\n return { ...projectRepository, repository };\n }\n\n /** Every link of the project across every handle, with the handle that owns it, in position order. */\n async #environmentLinks(orgId: string, projectId: string) {\n const links: Array<{ handle: SourceControlStorageHandle; projectRepository: ProjectRepository }> = [];\n for (const handle of await this.#handles()) {\n for (const projectRepository of await handle.projectRepositories.listByProject({\n orgId,\n factoryProjectId: projectId,\n })) {\n links.push({ handle, projectRepository });\n }\n }\n return links.sort(\n (a, b) =>\n a.projectRepository.position - b.projectRepository.position ||\n a.projectRepository.createdAt.getTime() - b.projectRepository.createdAt.getTime(),\n );\n }\n\n async #environmentPayload(orgId: string, project: FactoryProject) {\n const repositories = [];\n for (const { handle, projectRepository } of await this.#environmentLinks(orgId, project.id)) {\n const repository = await handle.repositories.get({ orgId, id: projectRepository.repositoryId });\n repositories.push({\n projectRepositoryId: projectRepository.id,\n connectionId: projectRepository.connectionId,\n repositoryId: projectRepository.repositoryId,\n slug: repository?.slug ?? null,\n defaultBranch: repository?.defaultBranch ?? null,\n position: projectRepository.position,\n inEnvironment: projectRepository.inEnvironment,\n setupCommand: projectRepository.setupCommand,\n teardownCommand: projectRepository.teardownCommand,\n lastBuildStatus: projectRepository.lastBuildStatus,\n lastBuildError: projectRepository.lastBuildError,\n lastBuiltAt: projectRepository.lastBuiltAt,\n });\n }\n return {\n environment: {\n sandbox: this.#describeSandbox(),\n settings: project.sandboxSettings ?? {},\n sandboxWorkingDirectory: project.sandboxWorkingDirectory,\n workspaceSetupCommand: project.workspaceSetupCommand,\n activeTemplateId: project.activeTemplateId,\n activeTemplateHeads: project.activeTemplateHeads,\n repositories,\n ...(await this.#buildPayload(project)),\n },\n };\n }\n\n /**\n * The build keys of the environment payload, present only when the\n * sandbox can build. Reads the project row and the schedule row; never\n * the provider (live status is the builds routes' job).\n */\n async #buildPayload(project: FactoryProject) {\n const builds = this.deps.environmentBuilds;\n if (!builds) return {};\n const schedules = builds.scheduleAvailable ? builds.schedules() : undefined;\n const schedule = schedules\n ? await readSchedule(schedules, project.id)\n : { enabled: false, cron: null, timezone: null };\n return {\n buildTriggers: {\n schedule: { ...schedule, scheduleAvailable: builds.scheduleAvailable },\n push: { enabled: project.buildOnPushEnabled, debounceMinutes: project.buildPushDebounceMinutes },\n },\n build: project.lastBuildId\n ? { buildId: project.lastBuildId, attemptedAt: project.lastBuildAttemptedAt?.toISOString() ?? null }\n : null,\n };\n }\n\n /** The builds capability behind the routes, or the 404 to answer with. */\n #builds(context: Context) {\n const builds = this.deps.sandbox?.builds;\n const runner = this.deps.environmentBuilds;\n if (!builds || !runner) return { response: context.json({ error: 'no_builds' }, 404) };\n return { builds, runner };\n }\n\n #buildRoutes(): ApiRoute[] {\n return [\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuild.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuild.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId)) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, projectId);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const capability = this.#builds(context);\n if ('response' in capability) return capability.response;\n const { heads: _heads, ...outcome } = await capability.runner.start(project.id, 'manual');\n return context.json(outcome);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuilds.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuilds.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId)) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, projectId);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const capability = this.#builds(context);\n if ('response' in capability) return capability.response;\n if (!capability.builds.list) return context.json({ error: 'no_history' }, 404);\n const read = await capability.runner.readContext(project.id);\n if (!read) return context.json({ error: 'no_environment' }, 404);\n const builds = await capability.builds.list(read.ctx, read.settings);\n return context.json({ builds: builds.map(redactBuild) });\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuildGet.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectEnvironmentBuildGet.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId)) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, projectId);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const capability = this.#builds(context);\n if ('response' in capability) return capability.response;\n // A composite provider id (E2B's `<templateId>:<buildId>`) travels\n // encoded; Hono hands the param back decoded.\n const buildId = context.req.param('buildId') ?? '';\n if (!buildId) return context.json({ error: 'Build not found' }, 404);\n const read = await capability.runner.readContext(project.id);\n if (!read) return context.json({ error: 'no_environment' }, 404);\n // Providers answer for any id on the host's account, so the route\n // only forwards ids that belong to this project: its last build, or\n // one the provider lists under the project's template.\n if (buildId !== project.lastBuildId) {\n const listed = capability.builds.list ? await capability.builds.list(read.ctx, read.settings) : [];\n if (!listed.some(build => build.buildId === buildId)) {\n return context.json({ error: 'Build not found' }, 404);\n }\n }\n return context.json({ build: redactBuild(await capability.builds.get(read.ctx, read.settings, buildId)) });\n },\n }),\n ];\n }\n\n /** Best effort: a deleted project's cron schedule must not keep firing. */\n async #dropSchedule(projectId: string): Promise<void> {\n const runner = this.deps.environmentBuilds;\n if (!runner?.scheduleAvailable) return;\n try {\n await runner.schedules()!.delete(scheduleIdFor(projectId));\n } catch (error) {\n if (error instanceof MastraError && error.id === 'SCHEDULES_NOT_FOUND') return;\n console.warn('[factory] could not delete the environment build schedule of a deleted project:', error);\n }\n }\n\n async #retireProjectRepositorySessions(\n handle: SourceControlStorageHandle,\n orgId: string,\n projectRepositoryId: string,\n ): Promise<boolean> {\n const sessions = await handle.sessions.listByProjectRepository({ projectRepositoryId });\n if (sessions.length === 0) return true;\n if (!this.deps.sessionRetirement) return false;\n await this.deps.sessionRetirement.retireProjectRepositorySessions({\n sourceControl: handle,\n ...(this.deps.workItems ? { workItems: this.deps.workItems } : {}),\n orgId,\n projectRepositoryId,\n });\n return true;\n }\n\n async #resolveTenant(context: Context): Promise<{ orgId: string; userId: string } | { response: Response }> {\n await this.deps.auth.ensureUser(context);\n const tenant = this.deps.auth.tenant(context);\n if (!tenant) return { response: context.json({ error: 'unauthorized' }, 401) };\n if (!tenant.orgId) {\n return {\n response: context.json(\n { error: 'organization_required', message: 'Factory projects require an organization.' },\n 403,\n ),\n };\n }\n return { orgId: tenant.orgId, userId: tenant.userId };\n }\n\n routes(): ApiRoute[] {\n return [\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectList.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectList.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n return context.json({ projects: await (await this.#projects()).list({ orgId: tenant.orgId }) });\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectCreate.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectCreate.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsed = FACTORY_ROUTE_CONTRACTS.projectCreate.bodySchema.safeParse(await readJson(context));\n if (!parsed.success) return context.json({ error: 'invalid_project' }, 400);\n const project = await (\n await this.#projects()\n ).create({ orgId: tenant.orgId, userId: tenant.userId, input: parsed.data });\n return context.json({ project }, 201);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectGet.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectGet.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectGet.pathSchema.safeParse({ id: context.req.param('id') });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const { id } = parsedPath.data;\n const project = await this.#project(tenant.orgId, id);\n return project ? context.json({ project }) : context.json({ error: 'Project not found' }, 404);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectUpdate.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectUpdate.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectUpdate.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const parsedBody = FACTORY_ROUTE_CONTRACTS.projectUpdate.bodySchema.safeParse(await readJson(context));\n if (!parsedBody.success) return context.json({ error: 'invalid_project' }, 400);\n const project = await (\n await this.#projects()\n ).update({ orgId: tenant.orgId, id: parsedPath.data.id, input: parsedBody.data });\n return project ? context.json({ project }) : context.json({ error: 'Project not found' }, 404);\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n if (!(await this.deps.auth.isOrganizationAdmin(context, tenant.orgId))) {\n return context.json(\n {\n error: 'forbidden',\n message: 'Organization administrator access is required to update running sessions.',\n },\n 403,\n );\n }\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectApplyDefaultModel.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, parsedPath.data.id);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const modelId = project.defaultModelId;\n if (!modelId) {\n return context.json(\n { error: 'default_model_not_set', message: 'Set a default model on the project first.' },\n 400,\n );\n }\n const { workItems, controller } = this.deps;\n if (!workItems || !controller) return context.json({ error: 'model_apply_unavailable' }, 503);\n\n const bindings = (await workItems.listRunBindings(tenant.orgId, project.id)).filter(\n binding => binding.status === 'active',\n );\n const seen = new Set<string>();\n const applied: string[] = [];\n const skipped: Array<{\n threadId: string;\n reason:\n | 'not-running'\n | 'work-item-missing'\n | 'stage-inactive'\n | 'thread-missing'\n | 'mode-unknown'\n | 'apply-failed';\n }> = [];\n\n for (const binding of bindings) {\n const key = `${binding.sessionId}:${binding.threadId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const item = await workItems.get({ orgId: tenant.orgId, id: binding.workItemId });\n if (!item || item.factoryProjectId !== project.id) {\n skipped.push({ threadId: binding.threadId, reason: 'work-item-missing' });\n continue;\n }\n if (!ACTIVE_RUN_BINDING_STAGES.has(item.stages[0] ?? '')) {\n skipped.push({ threadId: binding.threadId, reason: 'stage-inactive' });\n continue;\n }\n const session = await controller.getSessionByResource(binding.resourceId);\n if (!session) {\n skipped.push({ threadId: binding.threadId, reason: 'not-running' });\n continue;\n }\n const thread = await session.thread.getById({ threadId: binding.threadId });\n if (!thread) {\n skipped.push({ threadId: binding.threadId, reason: 'thread-missing' });\n continue;\n }\n try {\n // This route targets inactive bound threads, so persist the controller-owned key through the session gateway.\n await session.thread.setSettingOn({\n threadId: binding.threadId,\n key: 'currentModelId',\n value: modelId,\n });\n applied.push(binding.threadId);\n } catch (error) {\n console.warn('[factory] apply-default-model failed for thread', binding.threadId, error);\n skipped.push({ threadId: binding.threadId, reason: 'apply-failed' });\n }\n }\n\n return context.json({ modelId, applied, skipped });\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectDelete.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectDelete.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const parsedPath = FACTORY_ROUTE_CONTRACTS.projectDelete.pathSchema.safeParse({\n id: context.req.param('id'),\n });\n if (!parsedPath.success) return context.json({ error: 'Project not found' }, 404);\n const { id } = parsedPath.data;\n if (!(await this.#project(tenant.orgId, id))) return context.json({ error: 'Project not found' }, 404);\n for (const handle of await this.#handles()) {\n for (const connection of await handle.connections.list({ orgId: tenant.orgId, factoryProjectId: id })) {\n for (const projectRepository of await handle.projectRepositories.list({\n orgId: tenant.orgId,\n connectionId: connection.id,\n })) {\n if (!(await this.#retireProjectRepositorySessions(handle, tenant.orgId, projectRepository.id))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n }\n await handle.connections.delete({ orgId: tenant.orgId, id: connection.id });\n }\n }\n await (await this.#projects()).delete({ orgId: tenant.orgId, id });\n await this.#dropSchedule(id);\n return context.body(null, 204);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections', {\n method: 'GET',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId) || !(await this.#project(tenant.orgId, projectId)))\n return context.json({ error: 'Project not found' }, 404);\n const connections = [];\n for (const handle of await this.#handles()) {\n for (const connection of await handle.connections.list({\n orgId: tenant.orgId,\n factoryProjectId: projectId,\n })) {\n const installation = await handle.installations.get({\n orgId: tenant.orgId,\n id: connection.installationId,\n });\n // Skip orphaned connections whose installation was pruned (e.g.\n // the user uninstalled the GitHub App). Otherwise\n // `projectRepositories.list` throws `requireConnection` and the\n // whole endpoint 500s, which hangs the web UI on the page\n // loader for every project. New code cascade-deletes these on\n // installation removal, but this defensive skip lets already-\n // orphaned rows in existing databases self-heal on read.\n if (!installation) continue;\n const links = await handle.projectRepositories.list({ orgId: tenant.orgId, connectionId: connection.id });\n connections.push({\n ...connection,\n installation,\n repositories: await Promise.all(links.map(link => this.#repositoryPayload(handle, tenant.orgId, link))),\n });\n }\n }\n return context.json({ connections });\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections', {\n method: 'POST',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId) || !(await this.#project(tenant.orgId, projectId)))\n return context.json({ error: 'Project not found' }, 404);\n const input = parseConnectionInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_source_control_connection' }, 400);\n if (!this.#versionControlIntegrationIds.has(input.integrationId))\n return context.json({ error: 'Source-control integration not found' }, 404);\n const handle = (await this.#sourceControl()).forIntegration(input.integrationId);\n if (!(await handle.installations.get({ orgId: tenant.orgId, id: input.installationId })))\n return context.json({ error: 'Source-control installation not found' }, 404);\n const connection = await handle.connections.create({\n orgId: tenant.orgId,\n factoryProjectId: projectId,\n installationId: input.installationId,\n createdByUserId: tenant.userId,\n });\n return context.json({ connection }, 201);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections/:connectionId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const connectionId = context.req.param('connectionId');\n if (!projectId || !UUID_RE.test(projectId) || !connectionId || !UUID_RE.test(connectionId))\n return context.json({ error: 'Source-control connection not found' }, 404);\n const found = await this.#findConnection({ orgId: tenant.orgId, projectId, id: connectionId });\n if (!found) return context.json({ error: 'Source-control connection not found' }, 404);\n for (const projectRepository of await found.handle.projectRepositories.list({\n orgId: tenant.orgId,\n connectionId,\n })) {\n if (!(await this.#retireProjectRepositorySessions(found.handle, tenant.orgId, projectRepository.id))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n }\n await found.handle.connections.delete({ orgId: tenant.orgId, id: connectionId });\n return context.body(null, 204);\n },\n }),\n registerApiRoute('/web/factory/projects/:id/source-control-connections/:connectionId/repositories', {\n method: 'POST',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const connectionId = context.req.param('connectionId');\n if (!projectId || !UUID_RE.test(projectId) || !connectionId || !UUID_RE.test(connectionId))\n return context.json({ error: 'Source-control connection not found' }, 404);\n const found = await this.#findConnection({ orgId: tenant.orgId, projectId, id: connectionId });\n if (!found) return context.json({ error: 'Source-control connection not found' }, 404);\n const input = parseRepositoryLinkInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_project_repository' }, 400);\n const repository = input.repositoryId\n ? await found.handle.repositories.get({ orgId: tenant.orgId, id: input.repositoryId })\n : input.repository && this.deps.resolveRepository\n ? await this.deps.resolveRepository({\n integrationId: found.connection.integrationId,\n orgId: tenant.orgId,\n userId: tenant.userId,\n installationId: found.connection.installationId,\n ...input.repository,\n })\n : null;\n if (!repository || repository.installationId !== found.connection.installationId)\n return context.json({ error: 'Source-control repository not found' }, 404);\n const { repositoryId: _repositoryId, repository: _repository, ...linkInput } = input;\n const projectRepository = await found.handle.projectRepositories.link({\n orgId: tenant.orgId,\n connectionId,\n createdByUserId: tenant.userId,\n repositoryId: repository.id,\n ...linkInput,\n });\n try {\n this.deps.onProjectRepositoryLinked?.({ orgId: tenant.orgId, projectRepository });\n } catch (error) {\n console.warn('[factory] onProjectRepositoryLinked failed after a successful repository link:', error);\n }\n return context.json(\n { projectRepository: await this.#repositoryPayload(found.handle, tenant.orgId, projectRepository) },\n 201,\n );\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectEnvironmentGet.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectEnvironmentGet.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId)) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, projectId);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n return context.json(await this.#environmentPayload(tenant.orgId, project));\n },\n }),\n registerApiRoute(FACTORY_ROUTE_CONTRACTS.projectEnvironmentUpdate.path, {\n method: FACTORY_ROUTE_CONTRACTS.projectEnvironmentUpdate.method,\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n if (!projectId || !UUID_RE.test(projectId)) return context.json({ error: 'Project not found' }, 404);\n const project = await this.#project(tenant.orgId, projectId);\n if (!project) return context.json({ error: 'Project not found' }, 404);\n const parsed = FACTORY_ROUTE_CONTRACTS.projectEnvironmentUpdate.bodySchema.safeParse(await readJson(context));\n if (!parsed.success) return context.json({ error: 'invalid_environment' }, 400);\n const {\n repositories: repositoryPatches,\n settings: settingsPatch,\n buildTriggers,\n ...projectInput\n } = parsed.data;\n const input: UpdateFactoryProjectInput = projectInput;\n const runner = this.deps.environmentBuilds;\n if (buildTriggers !== undefined) {\n if (!runner) return context.json({ error: 'no_builds' }, 400);\n if (buildTriggers.push?.enabled !== undefined) input.buildOnPushEnabled = buildTriggers.push.enabled;\n if (buildTriggers.push?.debounceMinutes !== undefined) {\n input.buildPushDebounceMinutes = buildTriggers.push.debounceMinutes;\n }\n if (buildTriggers.schedule) {\n if (!runner.scheduleAvailable) {\n if (buildTriggers.schedule.enabled) return context.json({ error: 'schedules_unavailable' }, 400);\n } else {\n const { cron, timezone } = buildTriggers.schedule;\n const stored = await readSchedule(runner.schedules()!, project.id);\n const nextCron = cron ?? stored.cron;\n // Disabling a schedule that never existed needs no cron: it is a no-op.\n if (!nextCron && buildTriggers.schedule.enabled)\n return context.json(\n {\n error: 'invalid_environment',\n issues: [{ message: 'cron is required', path: ['buildTriggers', 'schedule', 'cron'] }],\n },\n 400,\n );\n const nextTimezone = timezone ?? stored.timezone ?? undefined;\n const message = nextCron ? invalidCronMessage(nextCron, nextTimezone) : undefined;\n if (message) {\n return context.json(\n {\n error: 'invalid_environment',\n issues: [{ message, path: ['buildTriggers', 'schedule', 'cron'] }],\n },\n 400,\n );\n }\n }\n }\n }\n if (settingsPatch !== undefined && !this.deps.sandbox) return context.json({ error: 'no_sandbox' }, 400);\n\n let updated = project;\n if (Object.keys(input).length > 0 || settingsPatch !== undefined || repositoryPatches !== undefined) {\n let issues: ReadonlyArray<{ message: string; path?: unknown }> | undefined;\n let repositoryOutcome: 'updated' | 'not_found' | 'incomplete_reorder' | undefined;\n const sourceControl = await this.#sourceControl();\n // One transaction holds the project row, so the settings merge and the link\n // writes either all land or none do, and concurrent patches apply in turn.\n const result = await (\n await this.#projects()\n ).update({\n orgId: tenant.orgId,\n id: projectId,\n input: async (current, ops) => {\n let sandboxSettings: Record<string, unknown> | null | undefined;\n if (settingsPatch !== undefined) {\n const settings = await this.#mergeSettings(current.sandboxSettings ?? {}, settingsPatch);\n if ('issues' in settings) {\n issues = settings.issues;\n return null;\n }\n sandboxSettings = settings.merged;\n }\n if (repositoryPatches !== undefined) {\n repositoryOutcome = await sourceControl.updateEnvironmentRepositories(ops, {\n factoryProjectId: current.id,\n integrationIds: [...this.#versionControlIntegrationIds],\n patches: repositoryPatches,\n });\n if (repositoryOutcome !== 'updated') return null;\n }\n return { ...input, ...(sandboxSettings !== undefined ? { sandboxSettings } : {}) };\n },\n });\n if (repositoryOutcome === 'not_found') return context.json({ error: 'Project repository not found' }, 404);\n if (repositoryOutcome === 'incomplete_reorder') return context.json({ error: 'invalid_environment' }, 400);\n if (issues) {\n return context.json(\n {\n error: 'invalid_environment',\n issues: issues.map(issue => ({\n message: issue.message,\n path: Array.isArray(issue.path)\n ? issue.path.map(segment =>\n typeof segment === 'object' && segment !== null && 'key' in segment ? segment.key : segment,\n )\n : [],\n })),\n },\n 400,\n );\n }\n if (!result) return context.json({ error: 'Project not found' }, 404);\n updated = result;\n }\n if (buildTriggers?.schedule && runner?.scheduleAvailable) {\n const stored = await readSchedule(runner.schedules()!, project.id);\n const cron = buildTriggers.schedule.cron ?? stored.cron;\n // Without a cron the request disables a schedule that never existed: nothing to write.\n if (cron)\n await ensureSchedule(runner.schedules()!, project.id, {\n enabled: buildTriggers.schedule.enabled,\n cron,\n ...((buildTriggers.schedule.timezone ?? stored.timezone)\n ? { timezone: (buildTriggers.schedule.timezone ?? stored.timezone)! }\n : {}),\n });\n }\n // Saving never builds: the next Build now, schedule or push run\n // picks the changed template up.\n return context.json(await this.#environmentPayload(tenant.orgId, updated));\n },\n }),\n registerApiRoute('/web/factory/projects/:id/repositories/:projectRepositoryId', {\n method: 'PATCH',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const projectRepositoryId = context.req.param('projectRepositoryId');\n if (!projectId || !UUID_RE.test(projectId) || !projectRepositoryId || !UUID_RE.test(projectRepositoryId))\n return context.json({ error: 'Project repository not found' }, 404);\n const found = await this.#findProjectRepository({ orgId: tenant.orgId, projectId, id: projectRepositoryId });\n if (!found) return context.json({ error: 'Project repository not found' }, 404);\n const input = parseRepositoryUpdateInput(await readJson(context));\n if (!input) return context.json({ error: 'invalid_project_repository' }, 400);\n const projectRepository = await found.handle.projectRepositories.update({\n orgId: tenant.orgId,\n id: projectRepositoryId,\n input,\n });\n return context.json({\n projectRepository: await this.#repositoryPayload(found.handle, tenant.orgId, projectRepository!),\n });\n },\n }),\n registerApiRoute('/web/factory/projects/:id/repositories/:projectRepositoryId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async routeContext => {\n const context = loose(routeContext);\n const tenant = await this.#resolveTenant(context);\n if ('response' in tenant) return tenant.response;\n const projectId = context.req.param('id');\n const projectRepositoryId = context.req.param('projectRepositoryId');\n if (!projectId || !UUID_RE.test(projectId) || !projectRepositoryId || !UUID_RE.test(projectRepositoryId))\n return context.json({ error: 'Project repository not found' }, 404);\n const found = await this.#findProjectRepository({ orgId: tenant.orgId, projectId, id: projectRepositoryId });\n if (!found) return context.json({ error: 'Project repository not found' }, 404);\n if (!(await this.#retireProjectRepositorySessions(found.handle, tenant.orgId, projectRepositoryId))) {\n return context.json({ error: 'session_retirement_unavailable' }, 409);\n }\n await found.handle.projectRepositories.unlink({ orgId: tenant.orgId, id: projectRepositoryId });\n return context.body(null, 204);\n },\n }),\n ...this.#buildRoutes(),\n ];\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import type { MountedMastraCode } from '@mastra/code-sdk';
|
|
|
2
2
|
import type { ApiRoute, IUserProvider } from '@mastra/core/server';
|
|
3
3
|
import type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';
|
|
4
4
|
import type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';
|
|
5
|
+
import type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';
|
|
5
6
|
import type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
|
|
6
7
|
import type { WorkItemsStorage } from '../storage/domains/work-items/base.js';
|
|
7
8
|
import type { RouteAuth } from './route.js';
|
|
@@ -9,6 +10,7 @@ type SessionOwnerUserProvider = Pick<IUserProvider, 'getUser'> & Partial<Pick<IU
|
|
|
9
10
|
export interface SourceControlSessionRoutesOptions {
|
|
10
11
|
auth: RouteAuth;
|
|
11
12
|
sourceControls: readonly SourceControlStorageHandle[];
|
|
13
|
+
projects: Pick<FactoryProjectsStorage, 'get'>;
|
|
12
14
|
users?: SessionOwnerUserProvider;
|
|
13
15
|
controller?: MountedMastraCode['controller'];
|
|
14
16
|
memorySettings: Pick<MemorySettingsStorage, 'get'>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-control-sessions.d.ts","sourceRoot":"","sources":["../../src/routes/source-control-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOnE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAGrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAGV,0BAA0B,EAC3B,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoB5C,KAAK,wBAAwB,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;AAE1G,MAAM,WAAW,iCAAiC;IAChD,IAAI,EAAE,SAAS,CAAC;IAChB,cAAc,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,cAAc,EAAE,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IACnD,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,SAAS,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;CAC9D;
|
|
1
|
+
{"version":3,"file":"source-control-sessions.d.ts","sourceRoot":"","sources":["../../src/routes/source-control-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOnE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAGrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,KAAK,EAGV,0BAA0B,EAC3B,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoB5C,KAAK,wBAAwB,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;AAE1G,MAAM,WAAW,iCAAiC;IAChD,IAAI,EAAE,SAAS,CAAC;IAChB,cAAc,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,cAAc,EAAE,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IACnD,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,SAAS,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;CAC9D;AA0RD,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,iCAAiC,GAAG,QAAQ,EAAE,CAiJtG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { isValidGitRef } from "../sandbox/git-ref.js";
|
|
1
2
|
import { waitForPendingFilesystemCapture } from "../session/filesystem-capture.js";
|
|
2
3
|
import { normalizeSessionTitle } from "../session/session-title.js";
|
|
3
4
|
import { reclaimDeletedSessionSandbox } from "../integrations/github/sandbox-release.js";
|
|
4
|
-
import { isValidGitRef } from "../sandbox/git-ref.js";
|
|
5
5
|
import { RequestContext } from "@mastra/core/request-context";
|
|
6
6
|
import { registerApiRoute } from "@mastra/core/server";
|
|
7
7
|
import { UniqueViolationError } from "@mastra/core/storage";
|
|
@@ -43,9 +43,15 @@ async function resolveProjectRepository(sourceControls, orgId, projectRepository
|
|
|
43
43
|
id: project.repositoryId
|
|
44
44
|
});
|
|
45
45
|
if (!repository) return null;
|
|
46
|
+
const connection = await sourceControl.connections.get({
|
|
47
|
+
orgId,
|
|
48
|
+
id: project.connectionId
|
|
49
|
+
});
|
|
50
|
+
if (!connection) return null;
|
|
46
51
|
return {
|
|
47
52
|
sourceControl,
|
|
48
53
|
project,
|
|
54
|
+
factoryProjectId: connection.factoryProjectId,
|
|
49
55
|
defaultBranch: project.branch ?? repository.defaultBranch
|
|
50
56
|
};
|
|
51
57
|
}))).filter((match) => match !== null);
|
|
@@ -192,6 +198,7 @@ function projectSessionRoutes(path, options, resolveOwnerProfiles) {
|
|
|
192
198
|
const session = await project.sourceControl.sessions.create({
|
|
193
199
|
sessionId,
|
|
194
200
|
projectRepositoryId: project.project.id,
|
|
201
|
+
factoryProjectId: project.factoryProjectId,
|
|
195
202
|
orgId,
|
|
196
203
|
userId,
|
|
197
204
|
branch,
|
|
@@ -213,6 +220,34 @@ function buildSourceControlSessionRoutes(options) {
|
|
|
213
220
|
const nameSession = createSessionNaming();
|
|
214
221
|
const resolveOwnerProfiles = createSessionOwnerProfileResolver(options.users);
|
|
215
222
|
return [
|
|
223
|
+
registerApiRoute("/web/factory/projects/:id/sessions", {
|
|
224
|
+
method: "GET",
|
|
225
|
+
requiresAuth: false,
|
|
226
|
+
handler: async (c) => {
|
|
227
|
+
const resolved = await resolveOrgTenant(loose(c), options.auth);
|
|
228
|
+
if ("response" in resolved) return resolved.response;
|
|
229
|
+
const { orgId, userId } = resolved.tenant;
|
|
230
|
+
const factoryProjectId = c.req.param("id");
|
|
231
|
+
const project = factoryProjectId ? await options.projects.get({
|
|
232
|
+
orgId,
|
|
233
|
+
id: factoryProjectId
|
|
234
|
+
}) : null;
|
|
235
|
+
if (!project) return c.json({ error: "Factory not found" }, 404);
|
|
236
|
+
const sessions = (await Promise.all(options.sourceControls.map((sourceControl) => sourceControl.sessions.listByProject({
|
|
237
|
+
orgId,
|
|
238
|
+
factoryProjectId: project.id,
|
|
239
|
+
viewerUserId: userId
|
|
240
|
+
})))).flat();
|
|
241
|
+
const owners = await resolveOwnerProfiles(sessions.map((session) => session.userId));
|
|
242
|
+
return c.json({ sessions: sessions.map((session) => {
|
|
243
|
+
const owner = owners.get(session.userId);
|
|
244
|
+
return {
|
|
245
|
+
...session,
|
|
246
|
+
...owner ? { owner } : {}
|
|
247
|
+
};
|
|
248
|
+
}) });
|
|
249
|
+
}
|
|
250
|
+
}),
|
|
216
251
|
...projectSessionRoutes("/web/source-control/projects/:id/sessions", options, resolveOwnerProfiles),
|
|
217
252
|
...projectSessionRoutes("/web/github/projects/:id/sessions", options, resolveOwnerProfiles),
|
|
218
253
|
registerApiRoute("/web/user-sessions/:sessionId", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-control-sessions.js","names":[],"sources":["../../src/routes/source-control-sessions.ts"],"sourcesContent":["import type { MountedMastraCode } from '@mastra/code-sdk';\nimport { resolveModel } from '@mastra/code-sdk/agents/model';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute, IUserProvider } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport { UniqueViolationError } from '@mastra/core/storage';\nimport type { Context } from 'hono';\n\nimport { reclaimDeletedSessionSandbox } from '../integrations/github/sandbox-release.js';\nimport { isValidGitRef } from '../sandbox/git-ref.js';\nimport type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';\nimport { waitForPendingFilesystemCapture } from '../session/filesystem-capture.js';\nimport { normalizeSessionTitle } from '../session/session-title.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type {\n ProjectRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { RouteAuth } from './route.js';\n\ntype RouteContext = Context;\n\nfunction loose(c: unknown): RouteContext {\n return c as RouteContext;\n}\n\nconst USER_SESSION_BRANCH_PREFIX = 'user/session-';\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst MAX_SESSION_OWNER_PROFILES = 100;\nconst MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES = 500;\nconst SESSION_OWNER_PROFILE_TTL_MS = 5 * 60_000;\n\ninterface SessionOwnerProfile {\n id: string;\n name: string;\n avatarUrl?: string;\n}\n\ntype SessionOwnerUserProvider = Pick<IUserProvider, 'getUser'> & Partial<Pick<IUserProvider, 'getUsers'>>;\n\nexport interface SourceControlSessionRoutesOptions {\n auth: RouteAuth;\n sourceControls: readonly SourceControlStorageHandle[];\n users?: SessionOwnerUserProvider;\n controller?: MountedMastraCode['controller'];\n memorySettings: Pick<MemorySettingsStorage, 'get'>;\n sessionRetirement?: SessionRetirementCoordinator;\n workItems?: Pick<WorkItemsStorage, 'clearSessionReferences'>;\n}\n\ninterface ResolvedProjectRepository {\n sourceControl: SourceControlStorageHandle;\n project: ProjectRepository;\n defaultBranch: string;\n}\n\nasync function resolveOrgTenant(\n c: RouteContext,\n auth: RouteAuth,\n): Promise<{ tenant: { orgId: string; userId: string } } | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant) return { response: c.json({ error: 'unauthorized', reason: 'auth_required' }, 401) };\n if (!tenant.orgId) {\n return {\n response: c.json(\n {\n error: 'organization_required',\n message: 'Source-control sessions require an organization.',\n },\n 403,\n ),\n };\n }\n return { tenant: { orgId: tenant.orgId, userId: tenant.userId } };\n}\n\nasync function resolveProjectRepository(\n sourceControls: readonly SourceControlStorageHandle[],\n orgId: string,\n projectRepositoryId: string,\n): Promise<ResolvedProjectRepository | null> {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => {\n const project = await sourceControl.projectRepositories.get({ orgId, id: projectRepositoryId });\n if (!project) return null;\n const repository = await sourceControl.repositories.get({ orgId, id: project.repositoryId });\n if (!repository) return null;\n return {\n sourceControl,\n project,\n defaultBranch: project.branch ?? repository.defaultBranch,\n };\n }),\n )\n ).filter((match): match is ResolvedProjectRepository => match !== null);\n if (matches.length > 1) {\n throw new Error('Factory project repository exists in multiple source-control providers.');\n }\n return matches[0] ?? null;\n}\n\nasync function resolveSession(\n sourceControls: readonly SourceControlStorageHandle[],\n sessionId: string,\n): Promise<{ sourceControl: SourceControlStorageHandle; session: SourceControlSession } | null> {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(sessionId),\n })),\n )\n ).filter(\n (match): match is { sourceControl: SourceControlStorageHandle; session: SourceControlSession } =>\n match.session !== null,\n );\n if (matches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n return matches[0] ?? null;\n}\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction createSessionNaming() {\n const inFlight = new Map<string, Promise<string | null>>();\n return (sessionId: string, run: () => Promise<string | null>) => {\n const pending = inFlight.get(sessionId);\n if (pending) return pending;\n const started = run().finally(() => inFlight.delete(sessionId));\n inFlight.set(sessionId, started);\n return started;\n };\n}\n\nfunction titleModel(modelId: string) {\n return ({ requestContext }: { requestContext: RequestContext }) =>\n resolveModel(modelId, { remapForCodexOAuth: true, requestContext });\n}\n\nfunction createSessionOwnerProfileResolver(users: SessionOwnerUserProvider | undefined) {\n const cache = new Map<string, { profile?: SessionOwnerProfile; expiresAt: number }>();\n const cacheProfile = (userId: string, profile: SessionOwnerProfile | undefined, expiresAt: number) => {\n cache.delete(userId);\n cache.set(userId, { profile, expiresAt });\n if (cache.size > MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES) {\n const oldestUserId = cache.keys().next().value;\n if (oldestUserId !== undefined) cache.delete(oldestUserId);\n }\n };\n\n return async (userIds: string[]): Promise<Map<string, SessionOwnerProfile>> => {\n if (!users) return new Map();\n const requestedUserIds = [...new Set(userIds)].slice(0, MAX_SESSION_OWNER_PROFILES);\n const profiles = new Map<string, SessionOwnerProfile>();\n const unresolvedUserIds: string[] = [];\n const now = Date.now();\n\n for (const userId of requestedUserIds) {\n const cached = cache.get(userId);\n if (!cached || cached.expiresAt <= now) {\n cache.delete(userId);\n unresolvedUserIds.push(userId);\n } else if (cached.profile) {\n profiles.set(userId, cached.profile);\n }\n }\n if (unresolvedUserIds.length === 0) return profiles;\n\n let resolvedUsers: Array<Awaited<ReturnType<SessionOwnerUserProvider['getUser']>>>;\n if (users.getUsers) {\n try {\n resolvedUsers = await users.getUsers(unresolvedUserIds);\n } catch (error) {\n console.warn('[Factory Sessions] Bulk owner profile lookup failed; falling back to individual lookups', {\n error: error instanceof Error ? error.message : String(error),\n });\n resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map(userId => users.getUser(userId))))\n .filter(result => result.status === 'fulfilled')\n .map(result => result.value);\n }\n } else {\n resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map(userId => users.getUser(userId))))\n .filter(result => result.status === 'fulfilled')\n .map(result => result.value);\n }\n\n for (const user of resolvedUsers) {\n if (!user) continue;\n const name = user.name?.trim() || user.email?.trim();\n if (!name) continue;\n profiles.set(user.id, {\n id: user.id,\n name,\n ...(user.avatarUrl ? { avatarUrl: user.avatarUrl } : {}),\n });\n }\n const expiresAt = now + SESSION_OWNER_PROFILE_TTL_MS;\n for (const userId of unresolvedUserIds) cacheProfile(userId, profiles.get(userId), expiresAt);\n return profiles;\n };\n}\n\nfunction projectSessionRoutes(\n path: '/web/source-control/projects/:id/sessions' | '/web/github/projects/:id/sessions',\n options: SourceControlSessionRoutesOptions,\n resolveOwnerProfiles: ReturnType<typeof createSessionOwnerProfileResolver>,\n): ApiRoute[] {\n return [\n registerApiRoute(path, {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const { orgId, userId } = resolved.tenant;\n const projectRepositoryId = c.req.param('id');\n const project = projectRepositoryId\n ? await resolveProjectRepository(options.sourceControls, orgId, projectRepositoryId)\n : null;\n if (!project) return c.json({ error: 'Project repository not found' }, 404);\n const sessions = await project.sourceControl.sessions.list({\n projectRepositoryId: project.project.id,\n viewerUserId: userId,\n });\n const owners = await resolveOwnerProfiles(sessions.map(session => session.userId));\n return c.json({\n sessions: sessions.map(session => {\n const owner = owners.get(session.userId);\n return { ...session, ...(owner ? { owner } : {}) };\n }),\n });\n },\n }),\n registerApiRoute(path, {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const { orgId, userId } = resolved.tenant;\n const projectRepositoryId = c.req.param('id');\n const project = projectRepositoryId\n ? await resolveProjectRepository(options.sourceControls, orgId, projectRepositoryId)\n : null;\n if (!project) return c.json({ error: 'Project repository not found' }, 404);\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n if (!isJsonObject(body)) return c.json({ error: 'Invalid JSON body' }, 400);\n if (body.baseBranch !== undefined && typeof body.baseBranch !== 'string') {\n return c.json({ error: 'Invalid baseBranch' }, 400);\n }\n const baseBranch = body.baseBranch ?? project.defaultBranch;\n if (!isValidGitRef(baseBranch)) return c.json({ error: 'Invalid baseBranch' }, 400);\n if (\n body.sessionId !== undefined &&\n (typeof body.sessionId !== 'string' || !UUID_PATTERN.test(body.sessionId))\n ) {\n return c.json({ error: 'Invalid sessionId' }, 400);\n }\n const requestedSessionId = body.sessionId as string | undefined;\n const sessionId = requestedSessionId ?? globalThis.crypto.randomUUID();\n if (body.title !== undefined && typeof body.title !== 'string') {\n return c.json({ error: 'Invalid title' }, 400);\n }\n const normalizedTitle = body.title === undefined ? null : normalizeSessionTitle(body.title as string);\n let branch: string;\n if (body.branch === undefined) branch = `${USER_SESSION_BRANCH_PREFIX}${sessionId}`;\n else if (isValidGitRef(body.branch)) branch = body.branch;\n else return c.json({ error: 'Invalid branch' }, 400);\n\n if (requestedSessionId) {\n const existing = await project.sourceControl.sessions.getBySessionId(sessionId);\n if (existing) {\n if (\n existing.projectRepositoryId !== project.project.id ||\n existing.orgId !== orgId ||\n existing.userId !== userId ||\n existing.branch !== branch\n ) {\n return c.json({ error: 'Session ID conflict' }, 409);\n }\n return c.json({ session: existing });\n }\n }\n\n const session = await project.sourceControl.sessions\n .create({\n sessionId,\n projectRepositoryId: project.project.id,\n orgId,\n userId,\n branch,\n baseBranch,\n title: normalizedTitle,\n visibility: 'org',\n })\n .catch(async error => {\n if (!(error instanceof UniqueViolationError) || !requestedSessionId) throw error;\n const conflict = await project.sourceControl.sessions.getBySessionId(sessionId);\n if (!conflict) throw error;\n return conflict;\n });\n if (\n requestedSessionId &&\n (session.sessionId !== sessionId ||\n session.projectRepositoryId !== project.project.id ||\n session.orgId !== orgId ||\n session.userId !== userId ||\n session.branch !== branch)\n ) {\n return c.json({ error: 'Session ID conflict' }, 409);\n }\n return c.json({ session });\n },\n }),\n ];\n}\n\nexport function buildSourceControlSessionRoutes(options: SourceControlSessionRoutesOptions): ApiRoute[] {\n const nameSession = createSessionNaming();\n const resolveOwnerProfiles = createSessionOwnerProfileResolver(options.users);\n return [\n ...projectSessionRoutes('/web/source-control/projects/:id/sessions', options, resolveOwnerProfiles),\n // Compatibility for existing clients; new code uses the provider-neutral path.\n ...projectSessionRoutes('/web/github/projects/:id/sessions', options, resolveOwnerProfiles),\n registerApiRoute('/web/user-sessions/:sessionId', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const match = await resolveSession(options.sourceControls, c.req.param('sessionId'));\n const session = match?.session;\n if (\n !session ||\n session.orgId !== resolved.tenant.orgId ||\n (session.visibility === 'private' && session.userId !== resolved.tenant.userId)\n ) {\n return c.json({ error: 'Session not found' }, 404);\n }\n return c.json({ session });\n },\n }),\n registerApiRoute('/web/user-sessions/:sessionId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const match = await resolveSession(options.sourceControls, c.req.param('sessionId'));\n const session = match?.session;\n if (\n !match ||\n !session ||\n session.orgId !== resolved.tenant.orgId ||\n session.userId !== resolved.tenant.userId\n ) {\n return c.json({ error: 'Session not found' }, 404);\n }\n try {\n // Drain the turn's queued filesystem capture while the thread and sandbox still exist.\n // A failed drain only costs the snapshot; it must not block teardown.\n await waitForPendingFilesystemCapture(session.sessionId).catch(error => {\n console.warn('[Factory Sessions] Failed to drain filesystem capture before delete', {\n sessionId: session.sessionId,\n error,\n });\n });\n await options.controller?.deleteSession({ resourceId: session.sessionId });\n } catch (error) {\n console.error('[Factory Sessions] Failed to tear down live controller session', {\n sessionId: session.sessionId,\n error,\n });\n }\n if (options.sessionRetirement) {\n await options.sessionRetirement.retireSession({\n sourceControl: match.sourceControl,\n ...(options.workItems ? { workItems: options.workItems } : {}),\n orgId: session.orgId,\n sessionId: session.sessionId,\n deleteSession: true,\n });\n } else {\n await options.workItems?.clearSessionReferences({ orgId: session.orgId, sessionId: session.sessionId });\n await match.sourceControl.sessions.delete(session.id);\n void reclaimDeletedSessionSandbox({ session }).catch((error: unknown) => {\n console.error('[Factory Sessions] Failed to reclaim sandbox for deleted session', {\n sessionId: session.sessionId,\n sandboxId: session.sandboxId,\n error,\n });\n });\n }\n return c.json({ removed: true });\n },\n }),\n registerApiRoute('/web/user-sessions/:sessionId/title', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const sessionId = c.req.param('sessionId');\n const match = await resolveSession(options.sourceControls, sessionId);\n const row = match?.session;\n if (!match || !row || row.orgId !== resolved.tenant.orgId || row.userId !== resolved.tenant.userId) {\n return c.json({ error: 'Session not found' }, 404);\n }\n if (!options.controller) return c.json({ error: 'Sessions are not available on this server.' }, 503);\n const threads = await options.controller.queryThreads({ resourceId: sessionId });\n const thread = threads.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];\n if (!thread) return c.json({ error: 'This session has no conversation to name yet.' }, 409);\n const stored = await options.memorySettings.get({ orgId: row.orgId, userId: row.userId });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: row.userId, organizationId: row.orgId });\n try {\n const title = await nameSession(sessionId, async () => {\n const generated = await options.controller!.generateThreadTitle({\n threadId: thread.id,\n resourceId: sessionId,\n requestContext,\n ...(stored?.observerModelId ? { model: titleModel(stored.observerModelId) } : {}),\n });\n const named = generated ? normalizeSessionTitle(generated) : null;\n if (named) await match.sourceControl.sessions.rename({ sessionId, title: named });\n return named;\n });\n if (!title) return c.json({ error: 'The model returned an empty title. Try again.' }, 502);\n return c.json({ title });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n}\n"],"mappings":";;;;;;;;;AAwBA,SAAS,MAAM,GAA0B;CACvC,OAAO;AACT;AAEA,MAAM,6BAA6B;AACnC,MAAM,eAAe;AACrB,MAAM,6BAA6B;AACnC,MAAM,0CAA0C;AAChD,MAAM,+BAA+B,IAAI;AA0BzC,eAAe,iBACb,GACA,MACiF;CACjF,MAAM,KAAK,WAAW,CAAC;CACvB,MAAM,SAAS,KAAK,OAAO,CAAC;CAC5B,IAAI,CAAC,QAAQ,OAAO,EAAE,UAAU,EAAE,KAAK;EAAE,OAAO;EAAgB,QAAQ;CAAgB,GAAG,GAAG,EAAE;CAChG,IAAI,CAAC,OAAO,OACV,OAAO,EACL,UAAU,EAAE,KACV;EACE,OAAO;EACP,SAAS;CACX,GACA,GACF,EACF;CAEF,OAAO,EAAE,QAAQ;EAAE,OAAO,OAAO;EAAO,QAAQ,OAAO;CAAO,EAAE;AAClE;AAEA,eAAe,yBACb,gBACA,OACA,qBAC2C;CAC3C,MAAM,WACJ,MAAM,QAAQ,IACZ,eAAe,IAAI,OAAM,kBAAiB;EACxC,MAAM,UAAU,MAAM,cAAc,oBAAoB,IAAI;GAAE;GAAO,IAAI;EAAoB,CAAC;EAC9F,IAAI,CAAC,SAAS,OAAO;EACrB,MAAM,aAAa,MAAM,cAAc,aAAa,IAAI;GAAE;GAAO,IAAI,QAAQ;EAAa,CAAC;EAC3F,IAAI,CAAC,YAAY,OAAO;EACxB,OAAO;GACL;GACA;GACA,eAAe,QAAQ,UAAU,WAAW;EAC9C;CACF,CAAC,CACH,EAAA,CACA,QAAQ,UAA8C,UAAU,IAAI;CACtE,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MAAM,yEAAyE;CAE3F,OAAO,QAAQ,MAAM;AACvB;AAEA,eAAe,eACb,gBACA,WAC8F;CAC9F,MAAM,WACJ,MAAM,QAAQ,IACZ,eAAe,IAAI,OAAM,mBAAkB;EACzC;EACA,SAAS,MAAM,cAAc,SAAS,eAAe,SAAS;CAChE,EAAE,CACJ,EAAA,CACA,QACC,UACC,MAAM,YAAY,IACtB;CACA,IAAI,QAAQ,SAAS,GAAG,MAAM,IAAI,MAAM,8DAA8D;CACtG,OAAO,QAAQ,MAAM;AACvB;AAEA,SAAS,aAAa,OAAkD;CACtE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,sBAAsB;CAC7B,MAAM,2BAAW,IAAI,IAAoC;CACzD,QAAQ,WAAmB,QAAsC;EAC/D,MAAM,UAAU,SAAS,IAAI,SAAS;EACtC,IAAI,SAAS,OAAO;EACpB,MAAM,UAAU,IAAI,CAAC,CAAC,cAAc,SAAS,OAAO,SAAS,CAAC;EAC9D,SAAS,IAAI,WAAW,OAAO;EAC/B,OAAO;CACT;AACF;AAEA,SAAS,WAAW,SAAiB;CACnC,QAAQ,EAAE,qBACR,aAAa,SAAS;EAAE,oBAAoB;EAAM;CAAe,CAAC;AACtE;AAEA,SAAS,kCAAkC,OAA6C;CACtF,MAAM,wBAAQ,IAAI,IAAkE;CACpF,MAAM,gBAAgB,QAAgB,SAA0C,cAAsB;EACpG,MAAM,OAAO,MAAM;EACnB,MAAM,IAAI,QAAQ;GAAE;GAAS;EAAU,CAAC;EACxC,IAAI,MAAM,OAAO,yCAAyC;GACxD,MAAM,eAAe,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GACzC,IAAI,iBAAiB,KAAA,GAAW,MAAM,OAAO,YAAY;EAC3D;CACF;CAEA,OAAO,OAAO,YAAiE;EAC7E,IAAI,CAAC,OAAO,uBAAO,IAAI,IAAI;EAC3B,MAAM,mBAAmB,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,0BAA0B;EAClF,MAAM,2BAAW,IAAI,IAAiC;EACtD,MAAM,oBAA8B,CAAC;EACrC,MAAM,MAAM,KAAK,IAAI;EAErB,KAAK,MAAM,UAAU,kBAAkB;GACrC,MAAM,SAAS,MAAM,IAAI,MAAM;GAC/B,IAAI,CAAC,UAAU,OAAO,aAAa,KAAK;IACtC,MAAM,OAAO,MAAM;IACnB,kBAAkB,KAAK,MAAM;GAC/B,OAAO,IAAI,OAAO,SAChB,SAAS,IAAI,QAAQ,OAAO,OAAO;EAEvC;EACA,IAAI,kBAAkB,WAAW,GAAG,OAAO;EAE3C,IAAI;EACJ,IAAI,MAAM,UACR,IAAI;GACF,gBAAgB,MAAM,MAAM,SAAS,iBAAiB;EACxD,SAAS,OAAO;GACd,QAAQ,KAAK,2FAA2F,EACtG,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAC9D,CAAC;GACD,iBAAiB,MAAM,QAAQ,WAAW,kBAAkB,KAAI,WAAU,MAAM,QAAQ,MAAM,CAAC,CAAC,EAAA,CAC7F,QAAO,WAAU,OAAO,WAAW,WAAW,CAAC,CAC/C,KAAI,WAAU,OAAO,KAAK;EAC/B;OAEA,iBAAiB,MAAM,QAAQ,WAAW,kBAAkB,KAAI,WAAU,MAAM,QAAQ,MAAM,CAAC,CAAC,EAAA,CAC7F,QAAO,WAAU,OAAO,WAAW,WAAW,CAAC,CAC/C,KAAI,WAAU,OAAO,KAAK;EAG/B,KAAK,MAAM,QAAQ,eAAe;GAChC,IAAI,CAAC,MAAM;GACX,MAAM,OAAO,KAAK,MAAM,KAAK,KAAK,KAAK,OAAO,KAAK;GACnD,IAAI,CAAC,MAAM;GACX,SAAS,IAAI,KAAK,IAAI;IACpB,IAAI,KAAK;IACT;IACA,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;GACxD,CAAC;EACH;EACA,MAAM,YAAY,MAAM;EACxB,KAAK,MAAM,UAAU,mBAAmB,aAAa,QAAQ,SAAS,IAAI,MAAM,GAAG,SAAS;EAC5F,OAAO;CACT;AACF;AAEA,SAAS,qBACP,MACA,SACA,sBACY;CACZ,OAAO,CACL,iBAAiB,MAAM;EACrB,QAAQ;EACR,cAAc;EACd,SAAS,OAAM,MAAK;GAClB,MAAM,WAAW,MAAM,iBAAiB,MAAM,CAAC,GAAG,QAAQ,IAAI;GAC9D,IAAI,cAAc,UAAU,OAAO,SAAS;GAC5C,MAAM,EAAE,OAAO,WAAW,SAAS;GACnC,MAAM,sBAAsB,EAAE,IAAI,MAAM,IAAI;GAC5C,MAAM,UAAU,sBACZ,MAAM,yBAAyB,QAAQ,gBAAgB,OAAO,mBAAmB,IACjF;GACJ,IAAI,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,OAAO,+BAA+B,GAAG,GAAG;GAC1E,MAAM,WAAW,MAAM,QAAQ,cAAc,SAAS,KAAK;IACzD,qBAAqB,QAAQ,QAAQ;IACrC,cAAc;GAChB,CAAC;GACD,MAAM,SAAS,MAAM,qBAAqB,SAAS,KAAI,YAAW,QAAQ,MAAM,CAAC;GACjF,OAAO,EAAE,KAAK,EACZ,UAAU,SAAS,KAAI,YAAW;IAChC,MAAM,QAAQ,OAAO,IAAI,QAAQ,MAAM;IACvC,OAAO;KAAE,GAAG;KAAS,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;IAAG;GACnD,CAAC,EACH,CAAC;EACH;CACF,CAAC,GACD,iBAAiB,MAAM;EACrB,QAAQ;EACR,cAAc;EACd,SAAS,OAAM,MAAK;GAClB,MAAM,WAAW,MAAM,iBAAiB,MAAM,CAAC,GAAG,QAAQ,IAAI;GAC9D,IAAI,cAAc,UAAU,OAAO,SAAS;GAC5C,MAAM,EAAE,OAAO,WAAW,SAAS;GACnC,MAAM,sBAAsB,EAAE,IAAI,MAAM,IAAI;GAC5C,MAAM,UAAU,sBACZ,MAAM,yBAAyB,QAAQ,gBAAgB,OAAO,mBAAmB,IACjF;GACJ,IAAI,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,OAAO,+BAA+B,GAAG,GAAG;GAC1E,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,EAAE,IAAI,KAAK;GAC1B,QAAQ;IACN,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;GACnD;GACA,IAAI,CAAC,aAAa,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;GAC1E,IAAI,KAAK,eAAe,KAAA,KAAa,OAAO,KAAK,eAAe,UAC9D,OAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;GAEpD,MAAM,aAAa,KAAK,cAAc,QAAQ;GAC9C,IAAI,CAAC,cAAc,UAAU,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;GAClF,IACE,KAAK,cAAc,KAAA,MAClB,OAAO,KAAK,cAAc,YAAY,CAAC,aAAa,KAAK,KAAK,SAAS,IAExE,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;GAEnD,MAAM,qBAAqB,KAAK;GAChC,MAAM,YAAY,sBAAsB,WAAW,OAAO,WAAW;GACrE,IAAI,KAAK,UAAU,KAAA,KAAa,OAAO,KAAK,UAAU,UACpD,OAAO,EAAE,KAAK,EAAE,OAAO,gBAAgB,GAAG,GAAG;GAE/C,MAAM,kBAAkB,KAAK,UAAU,KAAA,IAAY,OAAO,sBAAsB,KAAK,KAAe;GACpG,IAAI;GACJ,IAAI,KAAK,WAAW,KAAA,GAAW,SAAS,GAAG,6BAA6B;QACnE,IAAI,cAAc,KAAK,MAAM,GAAG,SAAS,KAAK;QAC9C,OAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;GAEnD,IAAI,oBAAoB;IACtB,MAAM,WAAW,MAAM,QAAQ,cAAc,SAAS,eAAe,SAAS;IAC9E,IAAI,UAAU;KACZ,IACE,SAAS,wBAAwB,QAAQ,QAAQ,MACjD,SAAS,UAAU,SACnB,SAAS,WAAW,UACpB,SAAS,WAAW,QAEpB,OAAO,EAAE,KAAK,EAAE,OAAO,sBAAsB,GAAG,GAAG;KAErD,OAAO,EAAE,KAAK,EAAE,SAAS,SAAS,CAAC;IACrC;GACF;GAEA,MAAM,UAAU,MAAM,QAAQ,cAAc,SACzC,OAAO;IACN;IACA,qBAAqB,QAAQ,QAAQ;IACrC;IACA;IACA;IACA;IACA,OAAO;IACP,YAAY;GACd,CAAC,CAAC,CACD,MAAM,OAAM,UAAS;IACpB,IAAI,EAAE,iBAAiB,yBAAyB,CAAC,oBAAoB,MAAM;IAC3E,MAAM,WAAW,MAAM,QAAQ,cAAc,SAAS,eAAe,SAAS;IAC9E,IAAI,CAAC,UAAU,MAAM;IACrB,OAAO;GACT,CAAC;GACH,IACE,uBACC,QAAQ,cAAc,aACrB,QAAQ,wBAAwB,QAAQ,QAAQ,MAChD,QAAQ,UAAU,SAClB,QAAQ,WAAW,UACnB,QAAQ,WAAW,SAErB,OAAO,EAAE,KAAK,EAAE,OAAO,sBAAsB,GAAG,GAAG;GAErD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;EAC3B;CACF,CAAC,CACH;AACF;AAEA,SAAgB,gCAAgC,SAAwD;CACtG,MAAM,cAAc,oBAAoB;CACxC,MAAM,uBAAuB,kCAAkC,QAAQ,KAAK;CAC5E,OAAO;EACL,GAAG,qBAAqB,6CAA6C,SAAS,oBAAoB;EAElG,GAAG,qBAAqB,qCAAqC,SAAS,oBAAoB;EAC1F,iBAAiB,iCAAiC;GAChD,QAAQ;GACR,cAAc;GACd,SAAS,OAAM,MAAK;IAClB,MAAM,WAAW,MAAM,iBAAiB,MAAM,CAAC,GAAG,QAAQ,IAAI;IAC9D,IAAI,cAAc,UAAU,OAAO,SAAS;IAE5C,MAAM,WAAU,MADI,eAAe,QAAQ,gBAAgB,EAAE,IAAI,MAAM,WAAW,CAAC,EAAA,EAC5D;IACvB,IACE,CAAC,WACD,QAAQ,UAAU,SAAS,OAAO,SACjC,QAAQ,eAAe,aAAa,QAAQ,WAAW,SAAS,OAAO,QAExE,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;IAEnD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;GAC3B;EACF,CAAC;EACD,iBAAiB,iCAAiC;GAChD,QAAQ;GACR,cAAc;GACd,SAAS,OAAM,MAAK;IAClB,MAAM,WAAW,MAAM,iBAAiB,MAAM,CAAC,GAAG,QAAQ,IAAI;IAC9D,IAAI,cAAc,UAAU,OAAO,SAAS;IAC5C,MAAM,QAAQ,MAAM,eAAe,QAAQ,gBAAgB,EAAE,IAAI,MAAM,WAAW,CAAC;IACnF,MAAM,UAAU,OAAO;IACvB,IACE,CAAC,SACD,CAAC,WACD,QAAQ,UAAU,SAAS,OAAO,SAClC,QAAQ,WAAW,SAAS,OAAO,QAEnC,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;IAEnD,IAAI;KAGF,MAAM,gCAAgC,QAAQ,SAAS,CAAC,CAAC,OAAM,UAAS;MACtE,QAAQ,KAAK,uEAAuE;OAClF,WAAW,QAAQ;OACnB;MACF,CAAC;KACH,CAAC;KACD,MAAM,QAAQ,YAAY,cAAc,EAAE,YAAY,QAAQ,UAAU,CAAC;IAC3E,SAAS,OAAO;KACd,QAAQ,MAAM,kEAAkE;MAC9E,WAAW,QAAQ;MACnB;KACF,CAAC;IACH;IACA,IAAI,QAAQ,mBACV,MAAM,QAAQ,kBAAkB,cAAc;KAC5C,eAAe,MAAM;KACrB,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;KAC5D,OAAO,QAAQ;KACf,WAAW,QAAQ;KACnB,eAAe;IACjB,CAAC;SACI;KACL,MAAM,QAAQ,WAAW,uBAAuB;MAAE,OAAO,QAAQ;MAAO,WAAW,QAAQ;KAAU,CAAC;KACtG,MAAM,MAAM,cAAc,SAAS,OAAO,QAAQ,EAAE;KACpD,6BAAkC,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAmB;MACvE,QAAQ,MAAM,oEAAoE;OAChF,WAAW,QAAQ;OACnB,WAAW,QAAQ;OACnB;MACF,CAAC;KACH,CAAC;IACH;IACA,OAAO,EAAE,KAAK,EAAE,SAAS,KAAK,CAAC;GACjC;EACF,CAAC;EACD,iBAAiB,uCAAuC;GACtD,QAAQ;GACR,cAAc;GACd,SAAS,OAAM,MAAK;IAClB,MAAM,WAAW,MAAM,iBAAiB,MAAM,CAAC,GAAG,QAAQ,IAAI;IAC9D,IAAI,cAAc,UAAU,OAAO,SAAS;IAC5C,MAAM,YAAY,EAAE,IAAI,MAAM,WAAW;IACzC,MAAM,QAAQ,MAAM,eAAe,QAAQ,gBAAgB,SAAS;IACpE,MAAM,MAAM,OAAO;IACnB,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,UAAU,SAAS,OAAO,SAAS,IAAI,WAAW,SAAS,OAAO,QAC1F,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;IAEnD,IAAI,CAAC,QAAQ,YAAY,OAAO,EAAE,KAAK,EAAE,OAAO,6CAA6C,GAAG,GAAG;IAEnG,MAAM,UAAS,MADO,QAAQ,WAAW,aAAa,EAAE,YAAY,UAAU,CAAC,EAAA,CACxD,MAAM,GAAG,MAAM,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,CAAC,CAAC,CAAC;IACrF,IAAI,CAAC,QAAQ,OAAO,EAAE,KAAK,EAAE,OAAO,gDAAgD,GAAG,GAAG;IAC1F,MAAM,SAAS,MAAM,QAAQ,eAAe,IAAI;KAAE,OAAO,IAAI;KAAO,QAAQ,IAAI;IAAO,CAAC;IACxF,MAAM,iBAAiB,IAAI,eAAe;IAC1C,eAAe,IAAI,QAAQ;KAAE,UAAU,IAAI;KAAQ,gBAAgB,IAAI;IAAM,CAAC;IAC9E,IAAI;KACF,MAAM,QAAQ,MAAM,YAAY,WAAW,YAAY;MACrD,MAAM,YAAY,MAAM,QAAQ,WAAY,oBAAoB;OAC9D,UAAU,OAAO;OACjB,YAAY;OACZ;OACA,GAAI,QAAQ,kBAAkB,EAAE,OAAO,WAAW,OAAO,eAAe,EAAE,IAAI,CAAC;MACjF,CAAC;MACD,MAAM,QAAQ,YAAY,sBAAsB,SAAS,IAAI;MAC7D,IAAI,OAAO,MAAM,MAAM,cAAc,SAAS,OAAO;OAAE;OAAW,OAAO;MAAM,CAAC;MAChF,OAAO;KACT,CAAC;KACD,IAAI,CAAC,OAAO,OAAO,EAAE,KAAK,EAAE,OAAO,gDAAgD,GAAG,GAAG;KACzF,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;IACzB,SAAS,OAAO;KACd,OAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAAG,GAAG;IACtF;GACF;EACF,CAAC;CACH;AACF"}
|
|
1
|
+
{"version":3,"file":"source-control-sessions.js","names":[],"sources":["../../src/routes/source-control-sessions.ts"],"sourcesContent":["import type { MountedMastraCode } from '@mastra/code-sdk';\nimport { resolveModel } from '@mastra/code-sdk/agents/model';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute, IUserProvider } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport { UniqueViolationError } from '@mastra/core/storage';\nimport type { Context } from 'hono';\n\nimport { reclaimDeletedSessionSandbox } from '../integrations/github/sandbox-release.js';\nimport { isValidGitRef } from '../sandbox/git-ref.js';\nimport type { SessionRetirementCoordinator } from '../sandbox/session-retirement.js';\nimport { waitForPendingFilesystemCapture } from '../session/filesystem-capture.js';\nimport { normalizeSessionTitle } from '../session/session-title.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type {\n ProjectRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { RouteAuth } from './route.js';\n\ntype RouteContext = Context;\n\nfunction loose(c: unknown): RouteContext {\n return c as RouteContext;\n}\n\nconst USER_SESSION_BRANCH_PREFIX = 'user/session-';\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst MAX_SESSION_OWNER_PROFILES = 100;\nconst MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES = 500;\nconst SESSION_OWNER_PROFILE_TTL_MS = 5 * 60_000;\n\ninterface SessionOwnerProfile {\n id: string;\n name: string;\n avatarUrl?: string;\n}\n\ntype SessionOwnerUserProvider = Pick<IUserProvider, 'getUser'> & Partial<Pick<IUserProvider, 'getUsers'>>;\n\nexport interface SourceControlSessionRoutesOptions {\n auth: RouteAuth;\n sourceControls: readonly SourceControlStorageHandle[];\n projects: Pick<FactoryProjectsStorage, 'get'>;\n users?: SessionOwnerUserProvider;\n controller?: MountedMastraCode['controller'];\n memorySettings: Pick<MemorySettingsStorage, 'get'>;\n sessionRetirement?: SessionRetirementCoordinator;\n workItems?: Pick<WorkItemsStorage, 'clearSessionReferences'>;\n}\n\ninterface ResolvedProjectRepository {\n sourceControl: SourceControlStorageHandle;\n project: ProjectRepository;\n factoryProjectId: string;\n defaultBranch: string;\n}\n\nasync function resolveOrgTenant(\n c: RouteContext,\n auth: RouteAuth,\n): Promise<{ tenant: { orgId: string; userId: string } } | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant) return { response: c.json({ error: 'unauthorized', reason: 'auth_required' }, 401) };\n if (!tenant.orgId) {\n return {\n response: c.json(\n {\n error: 'organization_required',\n message: 'Source-control sessions require an organization.',\n },\n 403,\n ),\n };\n }\n return { tenant: { orgId: tenant.orgId, userId: tenant.userId } };\n}\n\nasync function resolveProjectRepository(\n sourceControls: readonly SourceControlStorageHandle[],\n orgId: string,\n projectRepositoryId: string,\n): Promise<ResolvedProjectRepository | null> {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => {\n const project = await sourceControl.projectRepositories.get({ orgId, id: projectRepositoryId });\n if (!project) return null;\n const repository = await sourceControl.repositories.get({ orgId, id: project.repositoryId });\n if (!repository) return null;\n const connection = await sourceControl.connections.get({ orgId, id: project.connectionId });\n if (!connection) return null;\n return {\n sourceControl,\n project,\n factoryProjectId: connection.factoryProjectId,\n defaultBranch: project.branch ?? repository.defaultBranch,\n };\n }),\n )\n ).filter((match): match is ResolvedProjectRepository => match !== null);\n if (matches.length > 1) {\n throw new Error('Factory project repository exists in multiple source-control providers.');\n }\n return matches[0] ?? null;\n}\n\nasync function resolveSession(\n sourceControls: readonly SourceControlStorageHandle[],\n sessionId: string,\n): Promise<{ sourceControl: SourceControlStorageHandle; session: SourceControlSession } | null> {\n const matches = (\n await Promise.all(\n sourceControls.map(async sourceControl => ({\n sourceControl,\n session: await sourceControl.sessions.getBySessionId(sessionId),\n })),\n )\n ).filter(\n (match): match is { sourceControl: SourceControlStorageHandle; session: SourceControlSession } =>\n match.session !== null,\n );\n if (matches.length > 1) throw new Error('Factory session exists in multiple source-control providers.');\n return matches[0] ?? null;\n}\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction createSessionNaming() {\n const inFlight = new Map<string, Promise<string | null>>();\n return (sessionId: string, run: () => Promise<string | null>) => {\n const pending = inFlight.get(sessionId);\n if (pending) return pending;\n const started = run().finally(() => inFlight.delete(sessionId));\n inFlight.set(sessionId, started);\n return started;\n };\n}\n\nfunction titleModel(modelId: string) {\n return ({ requestContext }: { requestContext: RequestContext }) =>\n resolveModel(modelId, { remapForCodexOAuth: true, requestContext });\n}\n\nfunction createSessionOwnerProfileResolver(users: SessionOwnerUserProvider | undefined) {\n const cache = new Map<string, { profile?: SessionOwnerProfile; expiresAt: number }>();\n const cacheProfile = (userId: string, profile: SessionOwnerProfile | undefined, expiresAt: number) => {\n cache.delete(userId);\n cache.set(userId, { profile, expiresAt });\n if (cache.size > MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES) {\n const oldestUserId = cache.keys().next().value;\n if (oldestUserId !== undefined) cache.delete(oldestUserId);\n }\n };\n\n return async (userIds: string[]): Promise<Map<string, SessionOwnerProfile>> => {\n if (!users) return new Map();\n const requestedUserIds = [...new Set(userIds)].slice(0, MAX_SESSION_OWNER_PROFILES);\n const profiles = new Map<string, SessionOwnerProfile>();\n const unresolvedUserIds: string[] = [];\n const now = Date.now();\n\n for (const userId of requestedUserIds) {\n const cached = cache.get(userId);\n if (!cached || cached.expiresAt <= now) {\n cache.delete(userId);\n unresolvedUserIds.push(userId);\n } else if (cached.profile) {\n profiles.set(userId, cached.profile);\n }\n }\n if (unresolvedUserIds.length === 0) return profiles;\n\n let resolvedUsers: Array<Awaited<ReturnType<SessionOwnerUserProvider['getUser']>>>;\n if (users.getUsers) {\n try {\n resolvedUsers = await users.getUsers(unresolvedUserIds);\n } catch (error) {\n console.warn('[Factory Sessions] Bulk owner profile lookup failed; falling back to individual lookups', {\n error: error instanceof Error ? error.message : String(error),\n });\n resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map(userId => users.getUser(userId))))\n .filter(result => result.status === 'fulfilled')\n .map(result => result.value);\n }\n } else {\n resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map(userId => users.getUser(userId))))\n .filter(result => result.status === 'fulfilled')\n .map(result => result.value);\n }\n\n for (const user of resolvedUsers) {\n if (!user) continue;\n const name = user.name?.trim() || user.email?.trim();\n if (!name) continue;\n profiles.set(user.id, {\n id: user.id,\n name,\n ...(user.avatarUrl ? { avatarUrl: user.avatarUrl } : {}),\n });\n }\n const expiresAt = now + SESSION_OWNER_PROFILE_TTL_MS;\n for (const userId of unresolvedUserIds) cacheProfile(userId, profiles.get(userId), expiresAt);\n return profiles;\n };\n}\n\nfunction projectSessionRoutes(\n path: '/web/source-control/projects/:id/sessions' | '/web/github/projects/:id/sessions',\n options: SourceControlSessionRoutesOptions,\n resolveOwnerProfiles: ReturnType<typeof createSessionOwnerProfileResolver>,\n): ApiRoute[] {\n return [\n registerApiRoute(path, {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const { orgId, userId } = resolved.tenant;\n const projectRepositoryId = c.req.param('id');\n const project = projectRepositoryId\n ? await resolveProjectRepository(options.sourceControls, orgId, projectRepositoryId)\n : null;\n if (!project) return c.json({ error: 'Project repository not found' }, 404);\n const sessions = await project.sourceControl.sessions.list({\n projectRepositoryId: project.project.id,\n viewerUserId: userId,\n });\n const owners = await resolveOwnerProfiles(sessions.map(session => session.userId));\n return c.json({\n sessions: sessions.map(session => {\n const owner = owners.get(session.userId);\n return { ...session, ...(owner ? { owner } : {}) };\n }),\n });\n },\n }),\n registerApiRoute(path, {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const { orgId, userId } = resolved.tenant;\n const projectRepositoryId = c.req.param('id');\n const project = projectRepositoryId\n ? await resolveProjectRepository(options.sourceControls, orgId, projectRepositoryId)\n : null;\n if (!project) return c.json({ error: 'Project repository not found' }, 404);\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n if (!isJsonObject(body)) return c.json({ error: 'Invalid JSON body' }, 400);\n if (body.baseBranch !== undefined && typeof body.baseBranch !== 'string') {\n return c.json({ error: 'Invalid baseBranch' }, 400);\n }\n const baseBranch = body.baseBranch ?? project.defaultBranch;\n if (!isValidGitRef(baseBranch)) return c.json({ error: 'Invalid baseBranch' }, 400);\n if (\n body.sessionId !== undefined &&\n (typeof body.sessionId !== 'string' || !UUID_PATTERN.test(body.sessionId))\n ) {\n return c.json({ error: 'Invalid sessionId' }, 400);\n }\n const requestedSessionId = body.sessionId as string | undefined;\n const sessionId = requestedSessionId ?? globalThis.crypto.randomUUID();\n if (body.title !== undefined && typeof body.title !== 'string') {\n return c.json({ error: 'Invalid title' }, 400);\n }\n const normalizedTitle = body.title === undefined ? null : normalizeSessionTitle(body.title as string);\n let branch: string;\n if (body.branch === undefined) branch = `${USER_SESSION_BRANCH_PREFIX}${sessionId}`;\n else if (isValidGitRef(body.branch)) branch = body.branch;\n else return c.json({ error: 'Invalid branch' }, 400);\n\n if (requestedSessionId) {\n const existing = await project.sourceControl.sessions.getBySessionId(sessionId);\n if (existing) {\n if (\n existing.projectRepositoryId !== project.project.id ||\n existing.orgId !== orgId ||\n existing.userId !== userId ||\n existing.branch !== branch\n ) {\n return c.json({ error: 'Session ID conflict' }, 409);\n }\n return c.json({ session: existing });\n }\n }\n\n const session = await project.sourceControl.sessions\n .create({\n sessionId,\n projectRepositoryId: project.project.id,\n factoryProjectId: project.factoryProjectId,\n orgId,\n userId,\n branch,\n baseBranch,\n title: normalizedTitle,\n visibility: 'org',\n })\n .catch(async error => {\n if (!(error instanceof UniqueViolationError) || !requestedSessionId) throw error;\n const conflict = await project.sourceControl.sessions.getBySessionId(sessionId);\n if (!conflict) throw error;\n return conflict;\n });\n if (\n requestedSessionId &&\n (session.sessionId !== sessionId ||\n session.projectRepositoryId !== project.project.id ||\n session.orgId !== orgId ||\n session.userId !== userId ||\n session.branch !== branch)\n ) {\n return c.json({ error: 'Session ID conflict' }, 409);\n }\n return c.json({ session });\n },\n }),\n ];\n}\n\nexport function buildSourceControlSessionRoutes(options: SourceControlSessionRoutesOptions): ApiRoute[] {\n const nameSession = createSessionNaming();\n const resolveOwnerProfiles = createSessionOwnerProfileResolver(options.users);\n return [\n registerApiRoute('/web/factory/projects/:id/sessions', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const { orgId, userId } = resolved.tenant;\n const factoryProjectId = c.req.param('id');\n const project = factoryProjectId ? await options.projects.get({ orgId, id: factoryProjectId }) : null;\n if (!project) return c.json({ error: 'Factory not found' }, 404);\n // Storage is partitioned per provider; a Factory's sessions can live in any of them.\n const sessions = (\n await Promise.all(\n options.sourceControls.map(sourceControl =>\n sourceControl.sessions.listByProject({ orgId, factoryProjectId: project.id, viewerUserId: userId }),\n ),\n )\n ).flat();\n const owners = await resolveOwnerProfiles(sessions.map(session => session.userId));\n return c.json({\n sessions: sessions.map(session => {\n const owner = owners.get(session.userId);\n return { ...session, ...(owner ? { owner } : {}) };\n }),\n });\n },\n }),\n ...projectSessionRoutes('/web/source-control/projects/:id/sessions', options, resolveOwnerProfiles),\n // Compatibility for existing clients; new code uses the provider-neutral path.\n ...projectSessionRoutes('/web/github/projects/:id/sessions', options, resolveOwnerProfiles),\n registerApiRoute('/web/user-sessions/:sessionId', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const match = await resolveSession(options.sourceControls, c.req.param('sessionId'));\n const session = match?.session;\n if (\n !session ||\n session.orgId !== resolved.tenant.orgId ||\n (session.visibility === 'private' && session.userId !== resolved.tenant.userId)\n ) {\n return c.json({ error: 'Session not found' }, 404);\n }\n return c.json({ session });\n },\n }),\n registerApiRoute('/web/user-sessions/:sessionId', {\n method: 'DELETE',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const match = await resolveSession(options.sourceControls, c.req.param('sessionId'));\n const session = match?.session;\n if (\n !match ||\n !session ||\n session.orgId !== resolved.tenant.orgId ||\n session.userId !== resolved.tenant.userId\n ) {\n return c.json({ error: 'Session not found' }, 404);\n }\n try {\n // Drain the turn's queued filesystem capture while the thread and sandbox still exist.\n // A failed drain only costs the snapshot; it must not block teardown.\n await waitForPendingFilesystemCapture(session.sessionId).catch(error => {\n console.warn('[Factory Sessions] Failed to drain filesystem capture before delete', {\n sessionId: session.sessionId,\n error,\n });\n });\n await options.controller?.deleteSession({ resourceId: session.sessionId });\n } catch (error) {\n console.error('[Factory Sessions] Failed to tear down live controller session', {\n sessionId: session.sessionId,\n error,\n });\n }\n if (options.sessionRetirement) {\n await options.sessionRetirement.retireSession({\n sourceControl: match.sourceControl,\n ...(options.workItems ? { workItems: options.workItems } : {}),\n orgId: session.orgId,\n sessionId: session.sessionId,\n deleteSession: true,\n });\n } else {\n await options.workItems?.clearSessionReferences({ orgId: session.orgId, sessionId: session.sessionId });\n await match.sourceControl.sessions.delete(session.id);\n void reclaimDeletedSessionSandbox({ session }).catch((error: unknown) => {\n console.error('[Factory Sessions] Failed to reclaim sandbox for deleted session', {\n sessionId: session.sessionId,\n sandboxId: session.sandboxId,\n error,\n });\n });\n }\n return c.json({ removed: true });\n },\n }),\n registerApiRoute('/web/user-sessions/:sessionId/title', {\n method: 'POST',\n requiresAuth: false,\n handler: async c => {\n const resolved = await resolveOrgTenant(loose(c), options.auth);\n if ('response' in resolved) return resolved.response;\n const sessionId = c.req.param('sessionId');\n const match = await resolveSession(options.sourceControls, sessionId);\n const row = match?.session;\n if (!match || !row || row.orgId !== resolved.tenant.orgId || row.userId !== resolved.tenant.userId) {\n return c.json({ error: 'Session not found' }, 404);\n }\n if (!options.controller) return c.json({ error: 'Sessions are not available on this server.' }, 503);\n const threads = await options.controller.queryThreads({ resourceId: sessionId });\n const thread = threads.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];\n if (!thread) return c.json({ error: 'This session has no conversation to name yet.' }, 409);\n const stored = await options.memorySettings.get({ orgId: row.orgId, userId: row.userId });\n const requestContext = new RequestContext();\n requestContext.set('user', { workosId: row.userId, organizationId: row.orgId });\n try {\n const title = await nameSession(sessionId, async () => {\n const generated = await options.controller!.generateThreadTitle({\n threadId: thread.id,\n resourceId: sessionId,\n requestContext,\n ...(stored?.observerModelId ? { model: titleModel(stored.observerModelId) } : {}),\n });\n const named = generated ? normalizeSessionTitle(generated) : null;\n if (named) await match.sourceControl.sessions.rename({ sessionId, title: named });\n return named;\n });\n if (!title) return c.json({ error: 'The model returned an empty title. Try again.' }, 502);\n return c.json({ title });\n } catch (error) {\n return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n }),\n ];\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FACTORY_ROUTE_CONTRACTS } from "./contracts.js";
|
|
2
1
|
import { supervisorResourceId, supervisorThreadId } from "../supervisor/session.js";
|
|
2
|
+
import { FACTORY_ROUTE_CONTRACTS } from "./contracts.js";
|
|
3
3
|
import { runFactoryHealthCheck } from "../supervisor/health.js";
|
|
4
4
|
import { registerApiRoute } from "@mastra/core/server";
|
|
5
5
|
//#region src/routes/supervisor.ts
|
package/dist/routes/surface.d.ts
CHANGED
|
@@ -3,13 +3,13 @@ import type { MastraCodeState } from '@mastra/code-sdk/schema';
|
|
|
3
3
|
import type { AgentController } from '@mastra/core/agent-controller';
|
|
4
4
|
import type { ApiRoute, IUserProvider } from '@mastra/core/server';
|
|
5
5
|
import type { FactoryStorage } from '@mastra/core/storage';
|
|
6
|
+
import type { FactorySandbox } from '@mastra/core/workspace';
|
|
6
7
|
import type { BoardRegistry } from '../boards/index.js';
|
|
7
|
-
import type { FactoryIntegration, IntegrationContext } from '../integrations/base.js';
|
|
8
|
+
import type { FactoryIntegration, IntegrationContext, IntegrationHooks } from '../integrations/base.js';
|
|
8
9
|
import type { GithubIntegration } from '../integrations/github/integration.js';
|
|
9
10
|
import type { FactoryBindingPreparationInput } from '../rules/dispatcher.js';
|
|
10
11
|
import { FactoryStartCoordinator } from '../rules/start-coordinator.js';
|
|
11
12
|
import { FactoryTransitionService } from '../rules/transition-service.js';
|
|
12
|
-
import type { MastraFactorySandboxConfig } from '../sandbox/session-sandbox.js';
|
|
13
13
|
import type { LiveSessions } from '../session/live-sessions.js';
|
|
14
14
|
import type { StateSigner } from '../state-signing.js';
|
|
15
15
|
import type { AuditEmitter, AuditRecorder } from '../storage/domains/audit/domain.js';
|
|
@@ -48,7 +48,9 @@ export interface FactoryApiRoutesDeps {
|
|
|
48
48
|
publicOrigin: string;
|
|
49
49
|
stateSigner?: StateSigner;
|
|
50
50
|
/** Sandbox surface (enablement, provider label, create callback). */
|
|
51
|
-
sandbox?:
|
|
51
|
+
sandbox?: FactorySandbox;
|
|
52
|
+
/** Push hand-off for environment builds, present when the sandbox can build templates. */
|
|
53
|
+
onRepositoryPush?: IntegrationHooks['onRepositoryPush'];
|
|
52
54
|
/** Root factory storage backend (distributed locks, app-db diagnostics). */
|
|
53
55
|
factoryStorage?: FactoryStorage;
|
|
54
56
|
integrationStorage: IntegrationStorage;
|
|
@@ -106,6 +108,7 @@ export declare function prepareFactoryRuleBinding(sourceControlProvider: SourceC
|
|
|
106
108
|
export declare function buildIntegrationContext(deps: Pick<FactoryApiRoutesDeps, 'controller' | 'publicOrigin' | 'auth' | 'sandbox' | 'users' | 'factoryStorage' | 'integrationStorage' | 'sourceControlStorage' | 'integrations'> & {
|
|
107
109
|
stateSigner: StateSigner;
|
|
108
110
|
emitAudit?: AuditEmitter['emit'];
|
|
111
|
+
onRepositoryPush?: IntegrationHooks['onRepositoryPush'];
|
|
109
112
|
configVersion: string;
|
|
110
113
|
boardRegistry: BoardRegistry;
|
|
111
114
|
factoryReady: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/routes/surface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/routes/surface.ts"],"names":[],"mappings":"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"}
|