@mastra/factory 0.18.0 → 0.18.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/integrations/github/default-rules.d.ts.map +1 -1
  2. package/dist/integrations/github/default-rules.js +3 -3
  3. package/dist/integrations/github/default-rules.js.map +1 -1
  4. package/dist/integrations/github/reconcile-worker.d.ts.map +1 -1
  5. package/dist/integrations/github/reconcile-worker.js +1 -2
  6. package/dist/integrations/github/reconcile-worker.js.map +1 -1
  7. package/dist/integrations/github/routes.d.ts.map +1 -1
  8. package/dist/integrations/github/routes.js +1 -14
  9. package/dist/integrations/github/routes.js.map +1 -1
  10. package/dist/integrations/gitlab/version-control.d.ts.map +1 -1
  11. package/dist/integrations/gitlab/version-control.js +4 -5
  12. package/dist/integrations/gitlab/version-control.js.map +1 -1
  13. package/dist/integrations/gitlab/webhook.d.ts.map +1 -1
  14. package/dist/integrations/gitlab/webhook.js +2 -2
  15. package/dist/integrations/gitlab/webhook.js.map +1 -1
  16. package/dist/integrations/issue-reconcile-worker.d.ts.map +1 -1
  17. package/dist/integrations/issue-reconcile-worker.js +1 -2
  18. package/dist/integrations/issue-reconcile-worker.js.map +1 -1
  19. package/dist/integrations/linear/integration.d.ts.map +1 -1
  20. package/dist/integrations/linear/integration.js +10 -30
  21. package/dist/integrations/linear/integration.js.map +1 -1
  22. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
  23. package/dist/integrations/platform/github/event-worker.js +1 -2
  24. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  25. package/dist/integrations/platform/gitlab/event-worker.d.ts.map +1 -1
  26. package/dist/integrations/platform/gitlab/event-worker.js +1 -2
  27. package/dist/integrations/platform/gitlab/event-worker.js.map +1 -1
  28. package/dist/integrations/platform/linear/event-worker.d.ts.map +1 -1
  29. package/dist/integrations/platform/linear/event-worker.js +1 -2
  30. package/dist/integrations/platform/linear/event-worker.js.map +1 -1
  31. package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
  32. package/dist/integrations/platform/linear/integration.js +9 -9
  33. package/dist/integrations/platform/linear/integration.js.map +1 -1
  34. package/dist/integrations/slack/slack.d.ts.map +1 -1
  35. package/dist/integrations/slack/slack.js +1 -2
  36. package/dist/integrations/slack/slack.js.map +1 -1
  37. package/dist/review-verdict.d.ts +6 -0
  38. package/dist/review-verdict.d.ts.map +1 -0
  39. package/dist/review-verdict.js +14 -0
  40. package/dist/review-verdict.js.map +1 -0
  41. package/dist/routes/oauth.d.ts.map +1 -1
  42. package/dist/routes/oauth.js +3 -3
  43. package/dist/routes/oauth.js.map +1 -1
  44. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  45. package/dist/routes/source-control-sessions.js +1 -2
  46. package/dist/routes/source-control-sessions.js.map +1 -1
  47. package/dist/rules/dispatcher.d.ts.map +1 -1
  48. package/dist/rules/dispatcher.js +1 -2
  49. package/dist/rules/dispatcher.js.map +1 -1
  50. package/dist/rules/processor.d.ts.map +1 -1
  51. package/dist/rules/processor.js +5 -5
  52. package/dist/rules/processor.js.map +1 -1
  53. package/dist/rules/transition-service.d.ts.map +1 -1
  54. package/dist/rules/transition-service.js +1 -2
  55. package/dist/rules/transition-service.js.map +1 -1
  56. package/dist/secret-encryption.js +2 -2
  57. package/dist/secret-encryption.js.map +1 -1
  58. package/dist/session/factory-session.d.ts.map +1 -1
  59. package/dist/session/factory-session.js +1 -2
  60. package/dist/session/factory-session.js.map +1 -1
  61. package/dist/session/source-control-tools.d.ts +9 -0
  62. package/dist/session/source-control-tools.d.ts.map +1 -1
  63. package/dist/session/source-control-tools.js +51 -2
  64. package/dist/session/source-control-tools.js.map +1 -1
  65. package/dist/state-signing.js +3 -3
  66. package/dist/state-signing.js.map +1 -1
  67. package/dist/storage/domains/audit/base.d.ts.map +1 -1
  68. package/dist/storage/domains/audit/base.js +2 -3
  69. package/dist/storage/domains/audit/base.js.map +1 -1
  70. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  71. package/dist/storage/domains/source-control/inmemory.js +5 -6
  72. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  73. package/factory-skills/factory-gitlab-rereview/SKILL.md +1 -1
  74. package/factory-skills/factory-gitlab-review/SKILL.md +1 -1
  75. package/factory-skills/factory-rereview/SKILL.md +12 -3
  76. package/factory-skills/factory-review/SKILL.md +12 -3
  77. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"source-control-sessions.js","names":[],"sources":["../../src/routes/source-control-sessions.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport 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 ?? 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":"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"}
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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/rules/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/rules/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,6 @@ import { resolvePromptInvocation, resolveSkillInvocation, resolveSkillResumeInvo
11
11
  import { FACTORY_OPEN_RUN_STALE_MS, heartbeatSessionOpenRun, isOpenRunLiveElsewhere, listSessionOpenRuns, recordSessionRunStart, waitForSessionRunAudit } from "../session/run-audit.js";
12
12
  import { withWorkItemFeed } from "../storage/domains/comments/feed-context.js";
13
13
  import { RequestContext } from "@mastra/core/request-context";
14
- import { randomUUID } from "crypto";
15
14
  //#region src/rules/dispatcher.ts
16
15
  const LEASE_MS = 3e4;
17
16
  const POLL_MS = 1e3;
@@ -269,7 +268,7 @@ var FactoryDecisionDispatcher = class {
269
268
  this.#transitionService = options.transitionService;
270
269
  this.#boards = options.boards ?? createBoardRegistry();
271
270
  this.#storage = options.storage;
272
- this.#ownerId = options.ownerId ?? `factory-dispatcher:${randomUUID()}`;
271
+ this.#ownerId = options.ownerId ?? `factory-dispatcher:${globalThis.crypto.randomUUID()}`;
273
272
  this.#isAutoRunEnabled = options.isAutoRunEnabled;
274
273
  this.#autoApprovePlans = options.autoApprovePlans;
275
274
  this.#reconcileToolResults = options.reconcileToolResults;