@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":"source-control-tools.js","names":[],"sources":["../../src/session/source-control-tools.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { createTool } from '@mastra/core/tools';\nimport type { WorkspaceSandbox } from '@mastra/core/workspace';\nimport { z } from 'zod';\n\nimport { getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from '../auth.js';\nimport type { VersionControl } from '../capabilities/version-control.js';\nimport type { IntegrationTools } from '../integrations/base.js';\nimport { pushRepositoryBranch, refreshMergeRequestCheckout } from '../integrations/github/sandbox.js';\nimport { normalizedVerdictLine } from '../review-verdict.js';\nimport type { ExecutableSandbox } from '../sandbox/materialization.js';\nimport { resolveSessionWorkdir } from '../sandbox/session-sandbox.js';\nimport type { AuditAgentEmitter } from '../storage/domains/audit/domain.js';\nimport type {\n ProjectRepository,\n SourceControlRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport { mergeRequestNumberFromBranch } from '../work-item-branch.js';\n\ntype RepositorySessionState = {\n factoryProjectId?: string;\n projectRepositoryId?: string;\n};\n\nexport interface SourceControlToolProvider {\n id: string;\n storage: SourceControlStorageHandle;\n versionControl: VersionControl;\n}\n\ninterface SessionTarget {\n context: AgentControllerRequestContext<RepositorySessionState>;\n provider: SourceControlToolProvider;\n session: SourceControlSession;\n projectRepository: ProjectRepository;\n repository: SourceControlRepository;\n orgId: string;\n userId: string;\n}\n\ntype ReviewEvent = 'approve' | 'request-changes' | 'comment';\n\n/** Returns why a review's leading `Verdict:` line contradicts the submitted event, if it does. */\nexport function verdictEventMismatch(event: ReviewEvent, body: string | undefined): string | undefined {\n const match = /^verdict: ?(approve|request changes|changes requested)\\b/.exec(normalizedVerdictLine(body) ?? '');\n if (!match) return undefined;\n const verdict = match[1] === 'approve' ? 'approve' : 'request changes';\n // GitLab has no request-changes state, so a blocking verdict is published as a comment review.\n const allowed: ReviewEvent[] = verdict === 'approve' ? ['approve'] : ['request-changes', 'comment'];\n if (allowed.includes(event)) return undefined;\n return `Review body opens with \"Verdict: ${verdict}\" but event is \"${event}\". Nothing was posted. Use event ${allowed\n .map(e => `\"${e}\"`)\n .join(' or ')} for this body, or regenerate the body for the verdict you intend.`;\n}\n\nconst REVIEWED_HEAD_LINE = /^[\\s*_>-]*reviewed head[*_]*:[*_]*\\s*(.*)$/gim;\nconst FULL_SHA = /^`?([0-9a-f]{40}|[0-9a-f]{64})`?(?:\\s|$)/i;\n\n/**\n * Returns the full SHA named by the body's `Reviewed head:` lines, `null` when any line is malformed or the lines\n * disagree, or `undefined` when absent.\n */\nexport function reviewedHeadFromBody(body: string | undefined): string | null | undefined {\n const shas = new Set(\n [...(body ?? '').matchAll(REVIEWED_HEAD_LINE)].map(\n line => FULL_SHA.exec(line[1]!.trim())?.[1]?.toLowerCase() ?? null,\n ),\n );\n if (shas.size === 0) return undefined;\n if (shas.size > 1) return null;\n return [...shas][0];\n}\n\nfunction authIdentity(requestContext: RequestContext) {\n const user = getFactoryAuthUserFromContext(requestContext);\n return { orgId: getFactoryAuthOrgId(user), userId: getFactoryAuthUserId(user) };\n}\n\nasync function resolveSessionTarget(\n requestContext: RequestContext,\n providers: readonly SourceControlToolProvider[],\n): Promise<SessionTarget> {\n const context = requestContext.get('controller') as AgentControllerRequestContext<RepositorySessionState> | undefined;\n const { orgId, userId } = authIdentity(requestContext);\n if (!context?.resourceId || !orgId || !userId) {\n throw new Error('Source-control tools require an authenticated repository session.');\n }\n\n const matches = (\n await Promise.all(\n providers.map(async provider => ({\n provider,\n session: await provider.storage.sessions.getBySessionId(context.resourceId),\n })),\n )\n ).filter(\n (match): match is { provider: SourceControlToolProvider; session: SourceControlSession } => match.session !== null,\n );\n if (matches.length !== 1) {\n throw new Error(\n matches.length === 0\n ? 'The active session is not backed by a source-control repository.'\n : 'The active session is ambiguous across source-control providers.',\n );\n }\n\n const { provider, session } = matches[0]!;\n if (session.orgId !== orgId || (session.visibility === 'private' && session.userId !== userId)) {\n throw new Error('The active source-control session is not available to the authenticated user.');\n }\n const projectRepository = await provider.storage.projectRepositories.get({\n orgId,\n id: session.projectRepositoryId,\n });\n if (!projectRepository) throw new Error('The active project repository was not found.');\n const state = context.getState();\n if (state.projectRepositoryId && state.projectRepositoryId !== projectRepository.id) {\n throw new Error('The active source-control session does not match its controller repository.');\n }\n const connection = await provider.storage.connections.get({ orgId, id: projectRepository.connectionId });\n if (!connection) throw new Error('The active source-control connection was not found.');\n if (state.factoryProjectId && state.factoryProjectId !== connection.factoryProjectId) {\n throw new Error('The active source-control session does not match its Factory project.');\n }\n const repository = await provider.storage.repositories.get({ orgId, id: projectRepository.repositoryId });\n if (!repository) throw new Error('The active source-control repository was not found.');\n return { context, provider, session, projectRepository, repository, orgId, userId };\n}\n\nfunction changeRequestId(value: string | number): string {\n return String(value);\n}\n\nfunction executableSandbox(value: unknown): WorkspaceSandbox & ExecutableSandbox {\n const sandbox = value as Partial<ExecutableSandbox> | undefined;\n if (!sandbox?.executeCommand) throw new Error('The active Factory workspace has no executable sandbox.');\n return sandbox as WorkspaceSandbox & ExecutableSandbox;\n}\n\nasync function emitAgentAudit(\n audit: AuditAgentEmitter,\n requestContext: RequestContext,\n input: Parameters<AuditAgentEmitter['emitAgent']>[0]['input'],\n): Promise<void> {\n try {\n await audit.emitAgent({ requestContext, input });\n } catch (error) {\n console.warn('[Audit] Failed to record brokered source-control action', {\n action: input.action,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nconst changeRequestSchema = z.object({\n changeRequestId: z.union([z.string().trim().min(1), z.number().int().positive()]),\n});\n\nexport function createSourceControlTools({\n requestContext,\n providers,\n audit,\n}: {\n requestContext: RequestContext;\n providers: readonly SourceControlToolProvider[];\n audit: AuditAgentEmitter;\n}): IntegrationTools {\n if (!requestContext || typeof (requestContext as { get?: unknown }).get !== 'function') return {};\n const controller = requestContext.get('controller') as\n | AgentControllerRequestContext<RepositorySessionState>\n | undefined;\n const identity = authIdentity(requestContext);\n if (!controller?.resourceId || !identity.orgId || !identity.userId || providers.length === 0) return {};\n\n const withTarget = () => resolveSessionTarget(requestContext, providers);\n const reference = async (target: SessionTarget) => ({\n ...(await target.provider.versionControl.getRepositoryTarget({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n })),\n actingUserId: target.userId,\n });\n\n return {\n source_control_refresh_change_request_checkout: createTool({\n id: 'source_control_refresh_change_request_checkout',\n description:\n 'Refresh the active GitLab review session checkout to its current MR head. The MR, repository, branch, and credential are resolved server-side; no provider credentials enter the agent workspace.',\n inputSchema: z.object({}),\n execute: async (_input, { workspace }) => {\n const target = await withTarget();\n const mergeRequestNumber = mergeRequestNumberFromBranch(target.session.branch);\n if (target.provider.id !== 'gitlab' || mergeRequestNumber === undefined) {\n throw new Error('Checkout refresh is only available in a bound GitLab merge-request review session.');\n }\n const ref = await reference(target);\n const mergeRequest = await target.provider.versionControl.getPullRequest({\n ...ref,\n pullRequestId: String(mergeRequestNumber),\n });\n if (!mergeRequest || mergeRequest.state !== 'open' || mergeRequest.merged) {\n throw new Error('The bound GitLab merge request is no longer open.');\n }\n const sandbox = executableSandbox(workspace?.sandbox);\n const workdir = await resolveSessionWorkdir(target.session.id, sandbox, target.repository.slug);\n const access = await target.provider.versionControl.getRepositoryAccess({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n });\n const result = await refreshMergeRequestCheckout(sandbox, workdir, {\n branch: target.session.branch,\n mergeRequestNumber,\n expectedHeadSha: mergeRequest.headSha,\n access,\n });\n return result;\n },\n }),\n source_control_push_branch: createTool({\n id: 'source_control_push_branch',\n description:\n 'Push the active Factory session branch to its connected source-control provider. Credentials are resolved and scrubbed server-side; this tool takes no token, repository, remote, or branch arguments.',\n inputSchema: z.object({}),\n execute: async (_input, { workspace }) => {\n const target = await withTarget();\n const sandbox = executableSandbox(workspace?.sandbox);\n const workdir = await resolveSessionWorkdir(target.session.id, sandbox, target.repository.slug);\n const access = await target.provider.versionControl.getRepositoryAccess({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n });\n await pushRepositoryBranch(sandbox, workdir, target.session.branch, access, target.repository.slug);\n await emitAgentAudit(audit, requestContext, {\n action: 'factory.agent.push',\n targets: [{ type: 'repository', id: target.repository.slug }],\n metadata: { branch: target.session.branch, provider: target.provider.id },\n });\n return { pushed: true, branch: target.session.branch, repository: target.repository.slug };\n },\n }),\n source_control_get_change_request: createTool({\n id: 'source_control_get_change_request',\n description:\n 'Read a pull request or merge request in the active Factory repository by its numeric repository-local ID.',\n inputSchema: changeRequestSchema,\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.getPullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n });\n },\n }),\n source_control_list_change_request_reviews: createTool({\n id: 'source_control_list_change_request_reviews',\n description: 'List submitted reviews and approvals on a pull request or merge request in the active repository.',\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.listReviews({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_create_change_request: createTool({\n id: 'source_control_create_change_request',\n description:\n 'Open a pull request or merge request from the active Factory session branch into its persisted base branch. Push the branch with source_control_push_branch first.',\n inputSchema: z.object({\n title: z.string().trim().min(1),\n body: z.string().optional(),\n draft: z.boolean().optional(),\n }),\n execute: async input => {\n const target = await withTarget();\n const created = await target.provider.versionControl.createPullRequest({\n ...(await reference(target)),\n title: input.title,\n ...(input.body !== undefined ? { body: input.body } : {}),\n baseBranch: target.session.baseBranch,\n headBranch: target.session.branch,\n ...(input.draft !== undefined ? { draft: input.draft } : {}),\n });\n await emitAgentAudit(audit, requestContext, {\n action: 'factory.agent.pr_opened',\n targets: [\n { type: 'pull_request', id: created.url },\n { type: 'repository', id: target.repository.slug },\n ],\n metadata: { url: created.url, provider: target.provider.id },\n });\n return created;\n },\n }),\n source_control_update_change_request: createTool({\n id: 'source_control_update_change_request',\n description: 'Update the title, body, target branch, or open/closed state of a change request.',\n inputSchema: changeRequestSchema.extend({\n title: z.string().trim().min(1).optional(),\n body: z.string().nullable().optional(),\n baseBranch: z.string().trim().min(1).optional(),\n state: z.enum(['open', 'closed']).optional(),\n }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.updatePullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.body !== undefined ? { body: input.body } : {}),\n ...(input.baseBranch !== undefined ? { baseBranch: input.baseBranch } : {}),\n ...(input.state !== undefined ? { state: input.state } : {}),\n });\n },\n }),\n source_control_comment_change_request: createTool({\n id: 'source_control_comment_change_request',\n description: 'Add a top-level comment to a pull request or merge request in the active repository.',\n inputSchema: changeRequestSchema.extend({ body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.createComment({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n body: input.body,\n });\n },\n }),\n source_control_list_change_request_comments: createTool({\n id: 'source_control_list_change_request_comments',\n description: 'List top-level comments on a pull request or merge request in the active repository.',\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.listComments({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_update_change_request_comment: createTool({\n id: 'source_control_update_change_request_comment',\n description: 'Edit a top-level pull-request or merge-request comment in the active repository.',\n inputSchema: z.object({ commentId: z.string().trim().min(1), body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.updateComment({\n ...(await reference(target)),\n commentId: input.commentId,\n body: input.body,\n });\n },\n }),\n source_control_delete_change_request_comment: createTool({\n id: 'source_control_delete_change_request_comment',\n description: 'Delete a top-level pull-request or merge-request comment in the active repository.',\n inputSchema: z.object({ commentId: z.string().trim().min(1) }),\n execute: async input => {\n const target = await withTarget();\n await target.provider.versionControl.deleteComment({\n ...(await reference(target)),\n commentId: input.commentId,\n });\n return { deleted: true };\n },\n }),\n source_control_list_diff_comments: createTool({\n id: 'source_control_list_diff_comments',\n description:\n 'List line-anchored review comments and discussion replies on a pull request or merge request in the active repository.',\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.listReviewComments({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_create_diff_comment: createTool({\n id: 'source_control_create_diff_comment',\n description:\n 'Create a line-anchored review comment or reply to an existing diff discussion. Use replyToId alone for a reply; otherwise provide commitId, path, line, and side.',\n // A root-level union is not representable as provider function parameters, which must be\n // an object schema, so both modes share one object shape and a refinement.\n inputSchema: changeRequestSchema\n .extend({\n body: z.string().trim().min(1),\n replyToId: z.string().trim().min(1).optional(),\n commitId: z.string().trim().min(1).optional(),\n path: z.string().trim().min(1).optional(),\n line: z.number().int().positive().optional(),\n side: z.enum(['left', 'right']).optional(),\n startLine: z.number().int().positive().optional(),\n startSide: z.enum(['left', 'right']).optional(),\n })\n .refine(\n input => {\n const anchorFields = [input.commitId, input.path, input.line, input.side];\n const anchor = anchorFields.every(field => field !== undefined);\n const reply = input.replyToId !== undefined;\n return (\n (reply ? anchorFields.every(field => field === undefined) : anchor) &&\n (input.startLine === undefined) === (input.startSide === undefined)\n );\n },\n {\n message:\n 'Provide replyToId alone to reply to a diff thread, or commitId, path, line, and side to start one. startLine and startSide must be provided together.',\n },\n ),\n execute: async input => {\n const target = await withTarget();\n const base = {\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n body: input.body,\n };\n if (input.replyToId !== undefined) {\n return target.provider.versionControl.createReviewComment({ ...base, replyToId: input.replyToId });\n }\n if (\n input.commitId === undefined ||\n input.path === undefined ||\n input.line === undefined ||\n input.side === undefined\n ) {\n throw new Error('commitId, path, line, and side are required to start a new diff thread.');\n }\n return target.provider.versionControl.createReviewComment({\n ...base,\n commitId: input.commitId,\n path: input.path,\n line: input.line,\n side: input.side,\n ...(input.startLine !== undefined && input.startSide !== undefined\n ? { startLine: input.startLine, startSide: input.startSide }\n : {}),\n });\n },\n }),\n source_control_update_diff_comment: createTool({\n id: 'source_control_update_diff_comment',\n description: 'Edit a line-anchored review comment or discussion reply in the active repository.',\n inputSchema: z.object({ commentId: z.string().trim().min(1), body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.updateReviewComment({\n ...(await reference(target)),\n commentId: input.commentId,\n body: input.body,\n });\n },\n }),\n source_control_delete_diff_comment: createTool({\n id: 'source_control_delete_diff_comment',\n description: 'Delete a line-anchored review comment or discussion reply in the active repository.',\n inputSchema: z.object({ commentId: z.string().trim().min(1) }),\n execute: async input => {\n const target = await withTarget();\n await target.provider.versionControl.deleteReviewComment({\n ...(await reference(target)),\n commentId: input.commentId,\n });\n return { deleted: true };\n },\n }),\n source_control_resolve_diff_thread: createTool({\n id: 'source_control_resolve_diff_thread',\n description:\n 'Resolve or reopen the review thread containing a diff comment. Providers without resolvable threads return an explicit limitation.',\n inputSchema: z.object({\n commentId: z.string().trim().min(1),\n resolved: z.boolean().default(true),\n }),\n execute: async input => {\n const target = await withTarget();\n const resolveReviewThread = target.provider.versionControl.resolveReviewThread;\n if (!resolveReviewThread) {\n throw new Error(`${target.provider.id} does not support resolving review threads.`);\n }\n await resolveReviewThread({\n ...(await reference(target)),\n commentId: input.commentId,\n resolved: input.resolved,\n });\n return { resolved: input.resolved };\n },\n }),\n source_control_review_change_request: createTool({\n id: 'source_control_review_change_request',\n description:\n 'Submit an approve, request-changes, or comment review to a change request. Provider limitations are returned explicitly.',\n inputSchema: changeRequestSchema\n .extend({\n event: z.enum(['approve', 'request-changes', 'comment']),\n body: z.string().optional(),\n commitId: z.string().trim().min(1).optional(),\n })\n .refine(input => input.event === 'approve' || Boolean(input.body?.trim()), {\n path: ['body'],\n message: 'request-changes and comment reviews require a body.',\n })\n .superRefine((input, ctx) => {\n const mismatch = verdictEventMismatch(input.event, input.body);\n if (mismatch) ctx.addIssue({ code: 'custom', path: ['body'], message: mismatch });\n const reviewedHead = reviewedHeadFromBody(input.body);\n if (reviewedHead === null) {\n ctx.addIssue({\n code: 'custom',\n path: ['body'],\n message: 'Every \"Reviewed head:\" line must name the same full 40- or 64-character commit SHA.',\n });\n } else if (reviewedHead && input.commitId && input.commitId.toLowerCase() !== reviewedHead) {\n ctx.addIssue({\n code: 'custom',\n path: ['commitId'],\n message: `Review body says \"Reviewed head: ${reviewedHead}\" but commitId is ${input.commitId}. Nothing was posted. Re-review the current head and regenerate the body before publishing.`,\n });\n }\n }),\n execute: async input => {\n const target = await withTarget();\n const reviewedHead = reviewedHeadFromBody(input.body);\n if (reviewedHead) {\n const pullRequest = await target.provider.versionControl.getPullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n });\n if (!pullRequest) {\n throw new Error(`Change request ${input.changeRequestId} was not found; nothing was posted.`);\n }\n if (pullRequest.headSha && pullRequest.headSha.toLowerCase() !== reviewedHead) {\n throw new Error(\n `Review body says \"Reviewed head: ${reviewedHead}\" but the current change-request head is ${pullRequest.headSha}. Nothing was posted. Re-review the current head and regenerate the body before publishing.`,\n );\n }\n }\n const base = {\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.commitId !== undefined\n ? { commitId: input.commitId }\n : reviewedHead\n ? { commitId: reviewedHead }\n : {}),\n };\n if (input.event === 'approve') {\n return target.provider.versionControl.createReview({\n ...base,\n event: 'approve',\n ...(input.body !== undefined ? { body: input.body } : {}),\n });\n }\n return target.provider.versionControl.createReview({ ...base, event: input.event, body: input.body! });\n },\n }),\n source_control_request_reviewers: createTool({\n id: 'source_control_request_reviewers',\n description:\n 'Request individual or team reviewers on a pull request or merge request. Provider limitations are returned explicitly.',\n inputSchema: changeRequestSchema.extend({\n users: z.array(z.string().trim().min(1)).default([]),\n teams: z.array(z.string().trim().min(1)).default([]),\n }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.requestReviewers({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n users: input.users,\n teams: input.teams,\n });\n },\n }),\n source_control_merge_change_request: createTool({\n id: 'source_control_merge_change_request',\n description: 'Merge a pull request or merge request using the requested provider-supported merge method.',\n inputSchema: changeRequestSchema.extend({\n method: z.enum(['merge', 'squash', 'rebase']).optional(),\n commitTitle: z.string().optional(),\n commitMessage: z.string().optional(),\n }),\n execute: async input => {\n const target = await withTarget();\n return target.provider.versionControl.mergePullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.method !== undefined ? { method: input.method } : {}),\n ...(input.commitTitle !== undefined ? { commitTitle: input.commitTitle } : {}),\n ...(input.commitMessage !== undefined ? { commitMessage: input.commitMessage } : {}),\n });\n },\n }),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"source-control-tools.js","names":[],"sources":["../../src/session/source-control-tools.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { createTool } from '@mastra/core/tools';\nimport type { WorkspaceSandbox } from '@mastra/core/workspace';\nimport { z } from 'zod';\n\nimport { getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from '../auth.js';\nimport type { VersionControl } from '../capabilities/version-control.js';\nimport type { IntegrationTools } from '../integrations/base.js';\nimport {\n ensureLocalBranch,\n isCheckoutOf,\n pushRepositoryBranch,\n refreshMergeRequestCheckout,\n} from '../integrations/github/sandbox.js';\nimport { normalizedVerdictLine } from '../review-verdict.js';\nimport type { ExecutableSandbox } from '../sandbox/materialization.js';\nimport { resolveSessionWorkdir } from '../sandbox/session-sandbox.js';\nimport type { AuditAgentEmitter } from '../storage/domains/audit/domain.js';\nimport type {\n ProjectRepository,\n SourceControlRepository,\n SourceControlSession,\n SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport { mergeRequestNumberFromBranch } from '../work-item-branch.js';\nimport { environmentSlugs, findEnvironmentRepository, resolveSessionRepositories } from './environment-repositories.js';\nimport { updateSessionEnvironmentRepository } from './environment-state-processor.js';\n\ntype RepositorySessionState = {\n factoryProjectId?: string;\n projectRepositoryId?: string;\n};\n\nexport interface SourceControlToolProvider {\n id: string;\n storage: SourceControlStorageHandle;\n versionControl: VersionControl;\n}\n\ninterface SessionTarget {\n context: AgentControllerRequestContext<RepositorySessionState>;\n provider: SourceControlToolProvider;\n session: SourceControlSession;\n projectRepository: ProjectRepository;\n repository: SourceControlRepository;\n orgId: string;\n userId: string;\n /** True when the target is the link the session is filed under, the default. */\n ownRepository: boolean;\n}\n\ntype ReviewEvent = 'approve' | 'request-changes' | 'comment';\n\n/** Returns why a review's leading `Verdict:` line contradicts the submitted event, if it does. */\nexport function verdictEventMismatch(event: ReviewEvent, body: string | undefined): string | undefined {\n const match = /^verdict: ?(approve|request changes|changes requested)\\b/.exec(normalizedVerdictLine(body) ?? '');\n if (!match) return undefined;\n const verdict = match[1] === 'approve' ? 'approve' : 'request changes';\n // GitLab has no request-changes state, so a blocking verdict is published as a comment review.\n const allowed: ReviewEvent[] = verdict === 'approve' ? ['approve'] : ['request-changes', 'comment'];\n if (allowed.includes(event)) return undefined;\n return `Review body opens with \"Verdict: ${verdict}\" but event is \"${event}\". Nothing was posted. Use event ${allowed\n .map(e => `\"${e}\"`)\n .join(' or ')} for this body, or regenerate the body for the verdict you intend.`;\n}\n\nconst REVIEWED_HEAD_LINE = /^[\\s*_>-]*reviewed head[*_]*:[*_]*\\s*(.*)$/gim;\nconst FULL_SHA = /^`?([0-9a-f]{40}|[0-9a-f]{64})`?(?:\\s|$)/i;\n\n/**\n * Returns the full SHA named by the body's `Reviewed head:` lines, `null` when any line is malformed or the lines\n * disagree, or `undefined` when absent.\n */\nexport function reviewedHeadFromBody(body: string | undefined): string | null | undefined {\n const shas = new Set(\n [...(body ?? '').matchAll(REVIEWED_HEAD_LINE)].map(\n line => FULL_SHA.exec(line[1]!.trim())?.[1]?.toLowerCase() ?? null,\n ),\n );\n if (shas.size === 0) return undefined;\n if (shas.size > 1) return null;\n return [...shas][0];\n}\n\nfunction authIdentity(requestContext: RequestContext) {\n const user = getFactoryAuthUserFromContext(requestContext);\n return { orgId: getFactoryAuthOrgId(user), userId: getFactoryAuthUserId(user) };\n}\n\nasync function resolveProviderSession(\n resourceId: string,\n providers: readonly SourceControlToolProvider[],\n): Promise<{ provider: SourceControlToolProvider; session: SourceControlSession }> {\n const matches = (\n await Promise.all(\n providers.map(async provider => ({\n provider,\n session: await provider.storage.sessions.getBySessionId(resourceId),\n })),\n )\n ).filter(\n (match): match is { provider: SourceControlToolProvider; session: SourceControlSession } => match.session !== null,\n );\n if (matches.length !== 1) {\n throw new Error(\n matches.length === 0\n ? 'The active session is not backed by a source-control repository.'\n : 'The active session is ambiguous across source-control providers.',\n );\n }\n return matches[0]!;\n}\n\nasync function resolveSessionTarget(\n requestContext: RequestContext,\n providers: readonly SourceControlToolProvider[],\n options: { repository?: string } = {},\n): Promise<SessionTarget> {\n const context = requestContext.get('controller') as AgentControllerRequestContext<RepositorySessionState> | undefined;\n const { orgId, userId } = authIdentity(requestContext);\n if (!context?.resourceId || !orgId || !userId) {\n throw new Error('Source-control tools require an authenticated repository session.');\n }\n\n const { provider, session } = await resolveProviderSession(context.resourceId, providers);\n if (session.orgId !== orgId || (session.visibility === 'private' && session.userId !== userId)) {\n throw new Error('The active source-control session is not available to the authenticated user.');\n }\n const ownRepository = session.projectRepositoryId\n ? await provider.storage.projectRepositories.get({ orgId, id: session.projectRepositoryId })\n : null;\n if (!ownRepository) throw new Error('The active project repository was not found.');\n const state = context.getState();\n if (state.projectRepositoryId && state.projectRepositoryId !== ownRepository.id) {\n throw new Error('The active source-control session does not match its controller repository.');\n }\n const ownConnection = await provider.storage.connections.get({ orgId, id: ownRepository.connectionId });\n if (!ownConnection) throw new Error('The active source-control connection was not found.');\n if (state.factoryProjectId && state.factoryProjectId !== ownConnection.factoryProjectId) {\n throw new Error('The active source-control session does not match its Factory project.');\n }\n\n if (options.repository !== undefined) {\n const candidates = await resolveSessionRepositories({ sourceControl: provider.storage, session });\n const match = findEnvironmentRepository(candidates, options.repository);\n if (!match) {\n throw new Error(\n `Repository '${options.repository}' is not in this Factory's environment. Valid repositories: ${environmentSlugs(candidates).join(', ')}.`,\n );\n }\n return {\n context,\n provider,\n session,\n projectRepository: match.link,\n repository: match.repository,\n orgId,\n userId,\n ownRepository: match.link.id === ownRepository.id,\n };\n }\n\n const repository = await provider.storage.repositories.get({ orgId, id: ownRepository.repositoryId });\n if (!repository) throw new Error('The active source-control repository was not found.');\n return {\n context,\n provider,\n session,\n projectRepository: ownRepository,\n repository,\n orgId,\n userId,\n ownRepository: true,\n };\n}\n\n/**\n * The slugs a session may target and the one it is filed under, for the tool\n * descriptions. `undefined` when the session cannot be resolved; the tools\n * then describe the default without naming it.\n */\nasync function describeSessionRepositories(\n resourceId: string,\n providers: readonly SourceControlToolProvider[],\n): Promise<{ slugs: string[]; own: string | undefined } | undefined> {\n try {\n const { provider, session } = await resolveProviderSession(resourceId, providers);\n const repositories = await resolveSessionRepositories({ sourceControl: provider.storage, session });\n const own = repositories.find(candidate => candidate.link.id === session.projectRepositoryId);\n return { slugs: environmentSlugs(repositories), own: own?.repository.slug };\n } catch {\n return undefined;\n }\n}\n\nfunction repositoryArgumentDescription(described: { slugs: string[]; own: string | undefined } | undefined): string {\n if (!described || described.slugs.length === 0) {\n return \"Optional `repository` (owner/name) selects another repository of this Factory's environment; defaults to this session's repository.\";\n }\n const fallback = described.own ? `${described.own}, this session's repository` : \"this session's repository\";\n return `Optional \\`repository\\` (owner/name) selects one of this Factory's environment repositories: ${described.slugs.join(', ')}. Defaults to ${fallback}.`;\n}\n\nfunction changeRequestId(value: string | number): string {\n return String(value);\n}\n\nfunction executableSandbox(value: unknown): WorkspaceSandbox & ExecutableSandbox {\n const sandbox = value as Partial<ExecutableSandbox> | undefined;\n if (!sandbox?.executeCommand) throw new Error('The active Factory workspace has no executable sandbox.');\n return sandbox as WorkspaceSandbox & ExecutableSandbox;\n}\n\nasync function emitAgentAudit(\n audit: AuditAgentEmitter,\n requestContext: RequestContext,\n input: Parameters<AuditAgentEmitter['emitAgent']>[0]['input'],\n): Promise<void> {\n try {\n await audit.emitAgent({ requestContext, input });\n } catch (error) {\n console.warn('[Audit] Failed to record brokered source-control action', {\n action: input.action,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nconst repositorySchema = z.object({ repository: z.string().trim().min(1).optional() });\nconst changeRequestSchema = repositorySchema.extend({\n changeRequestId: z.union([z.string().trim().min(1), z.number().int().positive()]),\n});\n\nexport async function createSourceControlTools({\n requestContext,\n providers,\n audit,\n}: {\n requestContext: RequestContext;\n providers: readonly SourceControlToolProvider[];\n audit: AuditAgentEmitter;\n}): Promise<IntegrationTools> {\n if (!requestContext || typeof (requestContext as { get?: unknown }).get !== 'function') return {};\n const controller = requestContext.get('controller') as\n | AgentControllerRequestContext<RepositorySessionState>\n | undefined;\n const identity = authIdentity(requestContext);\n if (!controller?.resourceId || !identity.orgId || !identity.userId || providers.length === 0) return {};\n\n const repositoryArgument = repositoryArgumentDescription(\n await describeSessionRepositories(controller.resourceId, providers),\n );\n const withTarget = (options?: { repository?: string }) => resolveSessionTarget(requestContext, providers, options);\n const targetFor = (input: { repository?: string }) =>\n withTarget(input.repository !== undefined ? { repository: input.repository } : undefined);\n const reference = async (target: SessionTarget) => ({\n ...(await target.provider.versionControl.getRepositoryTarget({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n })),\n actingUserId: target.userId,\n });\n\n return {\n source_control_refresh_change_request_checkout: createTool({\n id: 'source_control_refresh_change_request_checkout',\n description:\n 'Refresh the active GitLab review session checkout to its current MR head. The MR, repository, branch, and credential are resolved server-side; no provider credentials enter the agent workspace.',\n inputSchema: z.object({}),\n execute: async (_input, { workspace }) => {\n const target = await withTarget();\n const mergeRequestNumber = mergeRequestNumberFromBranch(target.session.branch);\n if (target.provider.id !== 'gitlab' || mergeRequestNumber === undefined) {\n throw new Error('Checkout refresh is only available in a bound GitLab merge-request review session.');\n }\n const ref = await reference(target);\n const mergeRequest = await target.provider.versionControl.getPullRequest({\n ...ref,\n pullRequestId: String(mergeRequestNumber),\n });\n if (!mergeRequest || mergeRequest.state !== 'open' || mergeRequest.merged) {\n throw new Error('The bound GitLab merge request is no longer open.');\n }\n const sandbox = executableSandbox(workspace?.sandbox);\n const workdir = await resolveSessionWorkdir(target.session.id, sandbox, target.repository.slug);\n const access = await target.provider.versionControl.getRepositoryAccess({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n });\n const result = await refreshMergeRequestCheckout(sandbox, workdir, {\n branch: target.session.branch,\n mergeRequestNumber,\n expectedHeadSha: mergeRequest.headSha,\n access,\n });\n return result;\n },\n }),\n source_control_push_branch: createTool({\n id: 'source_control_push_branch',\n description: `Push the active Factory session branch to its connected source-control provider. Credentials are resolved and scrubbed server-side; this tool takes no token, remote, or branch arguments. ${repositoryArgument}`,\n inputSchema: repositorySchema,\n execute: async (input, { workspace }) => {\n const target = await targetFor(input);\n const sandbox = executableSandbox(workspace?.sandbox);\n const workdir = await resolveSessionWorkdir(target.session.id, sandbox, target.repository.slug);\n const access = await target.provider.versionControl.getRepositoryAccess({\n orgId: target.orgId,\n repositoryId: target.repository.id,\n });\n // Another environment repository's directory may not be its checkout:\n // a boot skips a link whose directory name collides with another's, and\n // a session that booted single-repository has no siblings at all.\n if (!target.ownRepository && !(await isCheckoutOf(sandbox, workdir, access.cloneUrl))) {\n throw new Error(`There is no checkout of ${target.repository.slug} in this session.`);\n }\n const branch = target.session.branch;\n // Push the local session branch, whatever is checked out. A repository\n // where it was never created gets it at HEAD first, so a later push\n // never sends some other branch's commits.\n await ensureLocalBranch(sandbox, workdir, branch);\n await pushRepositoryBranch(sandbox, workdir, branch, access, target.repository.slug);\n await target.provider.storage.sessionRepositories.upsert({\n sessionId: target.session.sessionId,\n projectRepositoryId: target.projectRepository.id,\n branch,\n });\n updateSessionEnvironmentRepository(target.session.sessionId, target.repository.slug, { branch });\n await emitAgentAudit(audit, requestContext, {\n action: 'factory.agent.push',\n targets: [{ type: 'repository', id: target.repository.slug }],\n metadata: { branch, provider: target.provider.id, repository: target.repository.slug },\n });\n return { pushed: true, branch, repository: target.repository.slug };\n },\n }),\n source_control_get_change_request: createTool({\n id: 'source_control_get_change_request',\n description: `Read a pull request or merge request in the active Factory repository by its numeric repository-local ID. ${repositoryArgument}`,\n inputSchema: changeRequestSchema,\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.getPullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n });\n },\n }),\n source_control_list_change_request_reviews: createTool({\n id: 'source_control_list_change_request_reviews',\n description: `List submitted reviews and approvals on a pull request or merge request in the active repository. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.listReviews({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_create_change_request: createTool({\n id: 'source_control_create_change_request',\n description: `Open a pull request or merge request from the active Factory session branch into the repository's base branch (the session's persisted base branch in its own repository, the linked or default branch elsewhere). Push the branch with source_control_push_branch first. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({\n title: z.string().trim().min(1),\n body: z.string().optional(),\n draft: z.boolean().optional(),\n }),\n execute: async input => {\n const target = await targetFor(input);\n const baseBranch = target.ownRepository\n ? target.session.baseBranch\n : (target.projectRepository.branch ?? target.repository.defaultBranch);\n const created = await target.provider.versionControl.createPullRequest({\n ...(await reference(target)),\n title: input.title,\n ...(input.body !== undefined ? { body: input.body } : {}),\n baseBranch,\n headBranch: target.session.branch,\n ...(input.draft !== undefined ? { draft: input.draft } : {}),\n });\n await target.provider.storage.sessionRepositories.upsert({\n sessionId: target.session.sessionId,\n projectRepositoryId: target.projectRepository.id,\n // Opening a change request pushes nothing: an existing row keeps its\n // `pushedAt`; the branch only seeds a row no push wrote yet.\n fallbackBranch: target.session.branch,\n changeRequestId: changeRequestId(created.id),\n changeRequestUrl: created.url,\n });\n updateSessionEnvironmentRepository(target.session.sessionId, target.repository.slug, {\n changeRequestUrl: created.url,\n });\n await emitAgentAudit(audit, requestContext, {\n action: 'factory.agent.pr_opened',\n targets: [\n { type: 'pull_request', id: created.url },\n { type: 'repository', id: target.repository.slug },\n ],\n metadata: { url: created.url, provider: target.provider.id, repository: target.repository.slug },\n });\n return created;\n },\n }),\n source_control_update_change_request: createTool({\n id: 'source_control_update_change_request',\n description: `Update the title, body, target branch, or open/closed state of a change request. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({\n title: z.string().trim().min(1).optional(),\n body: z.string().nullable().optional(),\n baseBranch: z.string().trim().min(1).optional(),\n state: z.enum(['open', 'closed']).optional(),\n }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.updatePullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.body !== undefined ? { body: input.body } : {}),\n ...(input.baseBranch !== undefined ? { baseBranch: input.baseBranch } : {}),\n ...(input.state !== undefined ? { state: input.state } : {}),\n });\n },\n }),\n source_control_comment_change_request: createTool({\n id: 'source_control_comment_change_request',\n description: `Add a top-level comment to a pull request or merge request in the active repository. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({ body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.createComment({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n body: input.body,\n });\n },\n }),\n source_control_list_change_request_comments: createTool({\n id: 'source_control_list_change_request_comments',\n description: `List top-level comments on a pull request or merge request in the active repository. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.listComments({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_update_change_request_comment: createTool({\n id: 'source_control_update_change_request_comment',\n description: `Edit a top-level pull-request or merge-request comment in the active repository. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({ commentId: z.string().trim().min(1), body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.updateComment({\n ...(await reference(target)),\n commentId: input.commentId,\n body: input.body,\n });\n },\n }),\n source_control_delete_change_request_comment: createTool({\n id: 'source_control_delete_change_request_comment',\n description: `Delete a top-level pull-request or merge-request comment in the active repository. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({ commentId: z.string().trim().min(1) }),\n execute: async input => {\n const target = await targetFor(input);\n await target.provider.versionControl.deleteComment({\n ...(await reference(target)),\n commentId: input.commentId,\n });\n return { deleted: true };\n },\n }),\n source_control_list_diff_comments: createTool({\n id: 'source_control_list_diff_comments',\n description: `List line-anchored review comments and discussion replies on a pull request or merge request in the active repository. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({ cursor: z.string().trim().min(1).optional() }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.listReviewComments({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.cursor !== undefined ? { cursor: input.cursor } : {}),\n });\n },\n }),\n source_control_create_diff_comment: createTool({\n id: 'source_control_create_diff_comment',\n description: `Create a line-anchored review comment or reply to an existing diff discussion. Use replyToId alone for a reply; otherwise provide commitId, path, line, and side. ${repositoryArgument}`,\n // A root-level union is not representable as provider function parameters, which must be\n // an object schema, so both modes share one object shape and a refinement.\n inputSchema: changeRequestSchema\n .extend({\n body: z.string().trim().min(1),\n replyToId: z.string().trim().min(1).optional(),\n commitId: z.string().trim().min(1).optional(),\n path: z.string().trim().min(1).optional(),\n line: z.number().int().positive().optional(),\n side: z.enum(['left', 'right']).optional(),\n startLine: z.number().int().positive().optional(),\n startSide: z.enum(['left', 'right']).optional(),\n })\n .refine(\n input => {\n const anchorFields = [input.commitId, input.path, input.line, input.side];\n const anchor = anchorFields.every(field => field !== undefined);\n const reply = input.replyToId !== undefined;\n return (\n (reply ? anchorFields.every(field => field === undefined) : anchor) &&\n (input.startLine === undefined) === (input.startSide === undefined)\n );\n },\n {\n message:\n 'Provide replyToId alone to reply to a diff thread, or commitId, path, line, and side to start one. startLine and startSide must be provided together.',\n },\n ),\n execute: async input => {\n const target = await targetFor(input);\n const base = {\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n body: input.body,\n };\n if (input.replyToId !== undefined) {\n return target.provider.versionControl.createReviewComment({ ...base, replyToId: input.replyToId });\n }\n if (\n input.commitId === undefined ||\n input.path === undefined ||\n input.line === undefined ||\n input.side === undefined\n ) {\n throw new Error('commitId, path, line, and side are required to start a new diff thread.');\n }\n return target.provider.versionControl.createReviewComment({\n ...base,\n commitId: input.commitId,\n path: input.path,\n line: input.line,\n side: input.side,\n ...(input.startLine !== undefined && input.startSide !== undefined\n ? { startLine: input.startLine, startSide: input.startSide }\n : {}),\n });\n },\n }),\n source_control_update_diff_comment: createTool({\n id: 'source_control_update_diff_comment',\n description: `Edit a line-anchored review comment or discussion reply in the active repository. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({ commentId: z.string().trim().min(1), body: z.string().trim().min(1) }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.updateReviewComment({\n ...(await reference(target)),\n commentId: input.commentId,\n body: input.body,\n });\n },\n }),\n source_control_delete_diff_comment: createTool({\n id: 'source_control_delete_diff_comment',\n description: `Delete a line-anchored review comment or discussion reply in the active repository. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({ commentId: z.string().trim().min(1) }),\n execute: async input => {\n const target = await targetFor(input);\n await target.provider.versionControl.deleteReviewComment({\n ...(await reference(target)),\n commentId: input.commentId,\n });\n return { deleted: true };\n },\n }),\n source_control_resolve_diff_thread: createTool({\n id: 'source_control_resolve_diff_thread',\n description: `Resolve or reopen the review thread containing a diff comment. Providers without resolvable threads return an explicit limitation. ${repositoryArgument}`,\n inputSchema: repositorySchema.extend({\n commentId: z.string().trim().min(1),\n resolved: z.boolean().default(true),\n }),\n execute: async input => {\n const target = await targetFor(input);\n const resolveReviewThread = target.provider.versionControl.resolveReviewThread;\n if (!resolveReviewThread) {\n throw new Error(`${target.provider.id} does not support resolving review threads.`);\n }\n await resolveReviewThread({\n ...(await reference(target)),\n commentId: input.commentId,\n resolved: input.resolved,\n });\n return { resolved: input.resolved };\n },\n }),\n source_control_review_change_request: createTool({\n id: 'source_control_review_change_request',\n description: `Submit an approve, request-changes, or comment review to a change request. Provider limitations are returned explicitly. ${repositoryArgument}`,\n inputSchema: changeRequestSchema\n .extend({\n event: z.enum(['approve', 'request-changes', 'comment']),\n body: z.string().optional(),\n commitId: z.string().trim().min(1).optional(),\n })\n .refine(input => input.event === 'approve' || Boolean(input.body?.trim()), {\n path: ['body'],\n message: 'request-changes and comment reviews require a body.',\n })\n .superRefine((input, ctx) => {\n const mismatch = verdictEventMismatch(input.event, input.body);\n if (mismatch) ctx.addIssue({ code: 'custom', path: ['body'], message: mismatch });\n const reviewedHead = reviewedHeadFromBody(input.body);\n if (reviewedHead === null) {\n ctx.addIssue({\n code: 'custom',\n path: ['body'],\n message: 'Every \"Reviewed head:\" line must name the same full 40- or 64-character commit SHA.',\n });\n } else if (reviewedHead && input.commitId && input.commitId.toLowerCase() !== reviewedHead) {\n ctx.addIssue({\n code: 'custom',\n path: ['commitId'],\n message: `Review body says \"Reviewed head: ${reviewedHead}\" but commitId is ${input.commitId}. Nothing was posted. Re-review the current head and regenerate the body before publishing.`,\n });\n }\n }),\n execute: async input => {\n const target = await targetFor(input);\n const reviewedHead = reviewedHeadFromBody(input.body);\n if (reviewedHead) {\n const pullRequest = await target.provider.versionControl.getPullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n });\n if (!pullRequest) {\n throw new Error(`Change request ${input.changeRequestId} was not found; nothing was posted.`);\n }\n if (pullRequest.headSha && pullRequest.headSha.toLowerCase() !== reviewedHead) {\n throw new Error(\n `Review body says \"Reviewed head: ${reviewedHead}\" but the current change-request head is ${pullRequest.headSha}. Nothing was posted. Re-review the current head and regenerate the body before publishing.`,\n );\n }\n }\n const base = {\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.commitId !== undefined\n ? { commitId: input.commitId }\n : reviewedHead\n ? { commitId: reviewedHead }\n : {}),\n };\n if (input.event === 'approve') {\n return target.provider.versionControl.createReview({\n ...base,\n event: 'approve',\n ...(input.body !== undefined ? { body: input.body } : {}),\n });\n }\n return target.provider.versionControl.createReview({ ...base, event: input.event, body: input.body! });\n },\n }),\n source_control_request_reviewers: createTool({\n id: 'source_control_request_reviewers',\n description: `Request individual or team reviewers on a pull request or merge request. Provider limitations are returned explicitly. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({\n users: z.array(z.string().trim().min(1)).default([]),\n teams: z.array(z.string().trim().min(1)).default([]),\n }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.requestReviewers({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n users: input.users,\n teams: input.teams,\n });\n },\n }),\n source_control_merge_change_request: createTool({\n id: 'source_control_merge_change_request',\n description: `Merge a pull request or merge request using the requested provider-supported merge method. ${repositoryArgument}`,\n inputSchema: changeRequestSchema.extend({\n method: z.enum(['merge', 'squash', 'rebase']).optional(),\n commitTitle: z.string().optional(),\n commitMessage: z.string().optional(),\n }),\n execute: async input => {\n const target = await targetFor(input);\n return target.provider.versionControl.mergePullRequest({\n ...(await reference(target)),\n pullRequestId: changeRequestId(input.changeRequestId),\n ...(input.method !== undefined ? { method: input.method } : {}),\n ...(input.commitTitle !== undefined ? { commitTitle: input.commitTitle } : {}),\n ...(input.commitMessage !== undefined ? { commitMessage: input.commitMessage } : {}),\n });\n },\n }),\n };\n}\n"],"mappings":"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"}
|
package/dist/spa-static.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { dirname, extname, join, normalize, resolve, sep } from "path";
|
|
2
|
-
import { readFile, stat } from "fs/promises";
|
|
3
1
|
import { existsSync } from "fs";
|
|
2
|
+
import { dirname, extname, join, normalize, resolve, sep } from "path";
|
|
4
3
|
import { fileURLToPath } from "url";
|
|
4
|
+
import { readFile, stat } from "fs/promises";
|
|
5
5
|
//#region src/spa-static.ts
|
|
6
6
|
/**
|
|
7
7
|
* Same-origin SPA serving for production.
|
|
@@ -16,10 +16,15 @@ interface ToolObserverContext {
|
|
|
16
16
|
* Detect externally-visible git and GitHub side effects in a completed tool
|
|
17
17
|
* call and record `factory.agent.*` audit events for them. One command can emit
|
|
18
18
|
* multiple events (`git commit && git push` emits both). Never throws.
|
|
19
|
+
*
|
|
20
|
+
* `resolveRepositorySlugs` names the repositories the session may target so a
|
|
21
|
+
* pull request can be attributed to one of them; a URL elsewhere is still
|
|
22
|
+
* audited, with a warning and no `repository`.
|
|
19
23
|
*/
|
|
20
|
-
export declare function observeAgentGitAction({ audit, toolContext, }: {
|
|
24
|
+
export declare function observeAgentGitAction({ audit, toolContext, resolveRepositorySlugs, }: {
|
|
21
25
|
audit: AuditAgentEmitter;
|
|
22
26
|
toolContext: ToolObserverContext;
|
|
27
|
+
resolveRepositorySlugs?: (sessionId: string) => Promise<string[]>;
|
|
23
28
|
}): Promise<void>;
|
|
24
29
|
export {};
|
|
25
30
|
//# sourceMappingURL=agent-audit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-audit.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"agent-audit.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;CACzB;AAgCD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,KAAK,EACL,WAAW,EACX,sBAAsB,GACvB,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,mBAAmB,CAAC;IACjC,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACnE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDhB"}
|
|
@@ -19,18 +19,27 @@ function createdPullRequestUrl(output) {
|
|
|
19
19
|
function parsePushedBranch(command) {
|
|
20
20
|
return command.match(/(?:^|\n|;|&&|\|\|)\s*git\s+push\s+(?:-[^\s]+\s+)*([^\s;&|-][^\s;&|]*)\s+([^\s;&|-][^\s;&|]*)/)?.[2];
|
|
21
21
|
}
|
|
22
|
+
/** The `owner/repo` a pull request URL names, as GitHub prints it. */
|
|
23
|
+
function pullRequestRepository(url) {
|
|
24
|
+
return url.match(/^https:\/\/[^/]+\/([^/]+\/[^/]+)\/pull\/\d+$/)?.[1];
|
|
25
|
+
}
|
|
22
26
|
/**
|
|
23
27
|
* Detect externally-visible git and GitHub side effects in a completed tool
|
|
24
28
|
* call and record `factory.agent.*` audit events for them. One command can emit
|
|
25
29
|
* multiple events (`git commit && git push` emits both). Never throws.
|
|
30
|
+
*
|
|
31
|
+
* `resolveRepositorySlugs` names the repositories the session may target so a
|
|
32
|
+
* pull request can be attributed to one of them; a URL elsewhere is still
|
|
33
|
+
* audited, with a warning and no `repository`.
|
|
26
34
|
*/
|
|
27
|
-
async function observeAgentGitAction({ audit, toolContext }) {
|
|
35
|
+
async function observeAgentGitAction({ audit, toolContext, resolveRepositorySlugs }) {
|
|
28
36
|
try {
|
|
29
37
|
if (toolContext.toolName !== "execute_command" || toolContext.error) return;
|
|
30
38
|
const rawCommand = toolContext.input?.command;
|
|
31
39
|
if (typeof rawCommand !== "string") return;
|
|
32
40
|
const command = executableCommand(rawCommand);
|
|
33
|
-
const
|
|
41
|
+
const controller = toolContext.context.get("controller");
|
|
42
|
+
const worktreePath = controller?.scope;
|
|
34
43
|
const targets = worktreePath ? [{
|
|
35
44
|
type: "worktree",
|
|
36
45
|
id: worktreePath
|
|
@@ -54,17 +63,26 @@ async function observeAgentGitAction({ audit, toolContext }) {
|
|
|
54
63
|
});
|
|
55
64
|
}
|
|
56
65
|
const pullRequestUrl = runsPullRequestCreate(rawCommand) ? createdPullRequestUrl(toolContext.output) : void 0;
|
|
57
|
-
if (pullRequestUrl)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
if (pullRequestUrl) {
|
|
67
|
+
const slug = pullRequestRepository(pullRequestUrl);
|
|
68
|
+
const slugs = resolveRepositorySlugs && controller?.resourceId ? await resolveRepositorySlugs(controller.resourceId) : [];
|
|
69
|
+
const repository = slug && slugs.find((candidate) => candidate.toLowerCase() === slug.toLowerCase());
|
|
70
|
+
if (slugs.length > 0 && !repository) console.warn("[Audit] Pull request URL is not in this Factory's environment", { url: pullRequestUrl });
|
|
71
|
+
await audit.emitAgent({
|
|
72
|
+
requestContext: toolContext.context,
|
|
73
|
+
input: {
|
|
74
|
+
action: "factory.agent.pr_opened",
|
|
75
|
+
targets: [{
|
|
76
|
+
type: "pull_request",
|
|
77
|
+
id: pullRequestUrl
|
|
78
|
+
}, ...targets],
|
|
79
|
+
metadata: {
|
|
80
|
+
url: pullRequestUrl,
|
|
81
|
+
...repository ? { repository } : {}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
68
86
|
} catch (err) {
|
|
69
87
|
console.warn("[Audit] Failed to observe agent git action", { error: err instanceof Error ? err.message : String(err) });
|
|
70
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-audit.js","names":[],"sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"sourcesContent":["/**\n * Git and GitHub actions performed by agents inside runs never touch web routes,\n * so this observer detects their externally-visible side effects in the command\n * and delegates recording to the factory-owned audit domain.\n */\n\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nimport { executableCommand, runsPullRequestCreate } from '../../../session/shell-commands.js';\nimport type { AuditAgentEmitter } from './domain.js';\n\ntype FactorySessionState = { factoryProjectId?: string; projectRepositoryId?: string };\n\ninterface ToolObserverContext {\n toolName: string;\n input: unknown;\n output?: unknown;\n error?: unknown;\n context: RequestContext;\n}\n\n/** Match command-start positions while ignoring command text embedded in heredoc bodies. */\nconst GIT_COMMIT_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+commit(?:\\s|$)/;\nconst GIT_PUSH_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push(?:\\s|$)/;\n/** `gh pr create` prints the new pull request URL alone on the last line, and nothing else does. */\nconst CREATED_PULL_REQUEST_URL_RE = /^https:\\/\\/\\S+\\/pull\\/\\d+$/;\n\n/**\n * The pull request `gh pr create` actually opened, or nothing. A command that\n * printed no URL created no pull request: `--dry-run` prints a preview, `--web`\n * prints a `/compare/` link, and a failure prints its exit code last.\n */\nfunction createdPullRequestUrl(output: unknown): string | undefined {\n if (typeof output !== 'string') return undefined;\n const lastLine = output.trimEnd().split('\\n').at(-1)?.trim();\n return lastLine !== undefined && CREATED_PULL_REQUEST_URL_RE.test(lastLine) ? lastLine : undefined;\n}\n\n/** Parse the branch from a plain `git push <remote> <branch>` invocation. */\nfunction parsePushedBranch(command: string): string | undefined {\n const match = command.match(\n /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push\\s+(?:-[^\\s]+\\s+)*([^\\s;&|-][^\\s;&|]*)\\s+([^\\s;&|-][^\\s;&|]*)/,\n );\n return match?.[2];\n}\n\n/**\n * Detect externally-visible git and GitHub side effects in a completed tool\n * call and record `factory.agent.*` audit events for them. One command can emit\n * multiple events (`git commit && git push` emits both). Never throws.\n */\nexport async function observeAgentGitAction({\n audit,\n toolContext,\n}: {\n audit: AuditAgentEmitter;\n toolContext: ToolObserverContext;\n}): Promise<void> {\n try {\n if (toolContext.toolName !== 'execute_command' || toolContext.error) return;\n const rawCommand = (toolContext.input as { command?: unknown } | undefined)?.command;\n if (typeof rawCommand !== 'string') return;\n const command = executableCommand(rawCommand);\n\n const controller = toolContext.context.get('controller') as\n | AgentControllerRequestContext<FactorySessionState>\n | undefined;\n const worktreePath = controller?.scope;\n const targets = worktreePath ? [{ type: 'worktree', id: worktreePath }] : [];\n\n if (GIT_COMMIT_RE.test(command)) {\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: { action: 'factory.agent.commit', targets },\n });\n }\n\n if (GIT_PUSH_RE.test(command)) {\n const branch = parsePushedBranch(command);\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: { action: 'factory.agent.push', targets, ...(branch ? { metadata: { branch } } : {}) },\n });\n }\n\n const pullRequestUrl = runsPullRequestCreate(rawCommand) ? createdPullRequestUrl(toolContext.output) : undefined;\n if (pullRequestUrl) {\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: {\n action: 'factory.agent.pr_opened',\n targets: [{ type: 'pull_request', id: pullRequestUrl }, ...targets],\n metadata: { url: pullRequestUrl },\n },\n });\n }\n } catch (err) {\n console.warn('[Audit] Failed to observe agent git action', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n"],"mappings":";;;AAuBA,MAAM,gBAAgB;AACtB,MAAM,cAAc;;AAEpB,MAAM,8BAA8B;;;;;;AAOpC,SAAS,sBAAsB,QAAqC;CAClE,IAAI,OAAO,WAAW,UAAU,OAAO,KAAA;CACvC,MAAM,WAAW,OAAO,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK;CAC3D,OAAO,aAAa,KAAA,KAAa,4BAA4B,KAAK,QAAQ,IAAI,WAAW,KAAA;AAC3F;;AAGA,SAAS,kBAAkB,SAAqC;CAI9D,OAHc,QAAQ,MACpB,8FAES,CAAC,GAAG;AACjB
|
|
1
|
+
{"version":3,"file":"agent-audit.js","names":[],"sources":["../../../../src/storage/domains/audit/agent-audit.ts"],"sourcesContent":["/**\n * Git and GitHub actions performed by agents inside runs never touch web routes,\n * so this observer detects their externally-visible side effects in the command\n * and delegates recording to the factory-owned audit domain.\n */\n\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\n\nimport { executableCommand, runsPullRequestCreate } from '../../../session/shell-commands.js';\nimport type { AuditAgentEmitter } from './domain.js';\n\ntype FactorySessionState = { factoryProjectId?: string; projectRepositoryId?: string };\n\ninterface ToolObserverContext {\n toolName: string;\n input: unknown;\n output?: unknown;\n error?: unknown;\n context: RequestContext;\n}\n\n/** Match command-start positions while ignoring command text embedded in heredoc bodies. */\nconst GIT_COMMIT_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+commit(?:\\s|$)/;\nconst GIT_PUSH_RE = /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push(?:\\s|$)/;\n/** `gh pr create` prints the new pull request URL alone on the last line, and nothing else does. */\nconst CREATED_PULL_REQUEST_URL_RE = /^https:\\/\\/\\S+\\/pull\\/\\d+$/;\n\n/**\n * The pull request `gh pr create` actually opened, or nothing. A command that\n * printed no URL created no pull request: `--dry-run` prints a preview, `--web`\n * prints a `/compare/` link, and a failure prints its exit code last.\n */\nfunction createdPullRequestUrl(output: unknown): string | undefined {\n if (typeof output !== 'string') return undefined;\n const lastLine = output.trimEnd().split('\\n').at(-1)?.trim();\n return lastLine !== undefined && CREATED_PULL_REQUEST_URL_RE.test(lastLine) ? lastLine : undefined;\n}\n\n/** Parse the branch from a plain `git push <remote> <branch>` invocation. */\nfunction parsePushedBranch(command: string): string | undefined {\n const match = command.match(\n /(?:^|\\n|;|&&|\\|\\|)\\s*git\\s+push\\s+(?:-[^\\s]+\\s+)*([^\\s;&|-][^\\s;&|]*)\\s+([^\\s;&|-][^\\s;&|]*)/,\n );\n return match?.[2];\n}\n\n/** The `owner/repo` a pull request URL names, as GitHub prints it. */\nfunction pullRequestRepository(url: string): string | undefined {\n return url.match(/^https:\\/\\/[^/]+\\/([^/]+\\/[^/]+)\\/pull\\/\\d+$/)?.[1];\n}\n\n/**\n * Detect externally-visible git and GitHub side effects in a completed tool\n * call and record `factory.agent.*` audit events for them. One command can emit\n * multiple events (`git commit && git push` emits both). Never throws.\n *\n * `resolveRepositorySlugs` names the repositories the session may target so a\n * pull request can be attributed to one of them; a URL elsewhere is still\n * audited, with a warning and no `repository`.\n */\nexport async function observeAgentGitAction({\n audit,\n toolContext,\n resolveRepositorySlugs,\n}: {\n audit: AuditAgentEmitter;\n toolContext: ToolObserverContext;\n resolveRepositorySlugs?: (sessionId: string) => Promise<string[]>;\n}): Promise<void> {\n try {\n if (toolContext.toolName !== 'execute_command' || toolContext.error) return;\n const rawCommand = (toolContext.input as { command?: unknown } | undefined)?.command;\n if (typeof rawCommand !== 'string') return;\n const command = executableCommand(rawCommand);\n\n const controller = toolContext.context.get('controller') as\n | AgentControllerRequestContext<FactorySessionState>\n | undefined;\n const worktreePath = controller?.scope;\n const targets = worktreePath ? [{ type: 'worktree', id: worktreePath }] : [];\n\n if (GIT_COMMIT_RE.test(command)) {\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: { action: 'factory.agent.commit', targets },\n });\n }\n\n if (GIT_PUSH_RE.test(command)) {\n const branch = parsePushedBranch(command);\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: { action: 'factory.agent.push', targets, ...(branch ? { metadata: { branch } } : {}) },\n });\n }\n\n const pullRequestUrl = runsPullRequestCreate(rawCommand) ? createdPullRequestUrl(toolContext.output) : undefined;\n if (pullRequestUrl) {\n const slug = pullRequestRepository(pullRequestUrl);\n const slugs =\n resolveRepositorySlugs && controller?.resourceId ? await resolveRepositorySlugs(controller.resourceId) : [];\n const repository = slug && slugs.find(candidate => candidate.toLowerCase() === slug.toLowerCase());\n if (slugs.length > 0 && !repository) {\n console.warn(\"[Audit] Pull request URL is not in this Factory's environment\", { url: pullRequestUrl });\n }\n await audit.emitAgent({\n requestContext: toolContext.context,\n input: {\n action: 'factory.agent.pr_opened',\n targets: [{ type: 'pull_request', id: pullRequestUrl }, ...targets],\n metadata: { url: pullRequestUrl, ...(repository ? { repository } : {}) },\n },\n });\n }\n } catch (err) {\n console.warn('[Audit] Failed to observe agent git action', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n"],"mappings":";;;AAuBA,MAAM,gBAAgB;AACtB,MAAM,cAAc;;AAEpB,MAAM,8BAA8B;;;;;;AAOpC,SAAS,sBAAsB,QAAqC;CAClE,IAAI,OAAO,WAAW,UAAU,OAAO,KAAA;CACvC,MAAM,WAAW,OAAO,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK;CAC3D,OAAO,aAAa,KAAA,KAAa,4BAA4B,KAAK,QAAQ,IAAI,WAAW,KAAA;AAC3F;;AAGA,SAAS,kBAAkB,SAAqC;CAI9D,OAHc,QAAQ,MACpB,8FAES,CAAC,GAAG;AACjB;;AAGA,SAAS,sBAAsB,KAAiC;CAC9D,OAAO,IAAI,MAAM,8CAA8C,CAAC,GAAG;AACrE;;;;;;;;;;AAWA,eAAsB,sBAAsB,EAC1C,OACA,aACA,0BAKgB;CAChB,IAAI;EACF,IAAI,YAAY,aAAa,qBAAqB,YAAY,OAAO;EACrE,MAAM,aAAc,YAAY,OAA6C;EAC7E,IAAI,OAAO,eAAe,UAAU;EACpC,MAAM,UAAU,kBAAkB,UAAU;EAE5C,MAAM,aAAa,YAAY,QAAQ,IAAI,YAAY;EAGvD,MAAM,eAAe,YAAY;EACjC,MAAM,UAAU,eAAe,CAAC;GAAE,MAAM;GAAY,IAAI;EAAa,CAAC,IAAI,CAAC;EAE3E,IAAI,cAAc,KAAK,OAAO,GAC5B,MAAM,MAAM,UAAU;GACpB,gBAAgB,YAAY;GAC5B,OAAO;IAAE,QAAQ;IAAwB;GAAQ;EACnD,CAAC;EAGH,IAAI,YAAY,KAAK,OAAO,GAAG;GAC7B,MAAM,SAAS,kBAAkB,OAAO;GACxC,MAAM,MAAM,UAAU;IACpB,gBAAgB,YAAY;IAC5B,OAAO;KAAE,QAAQ;KAAsB;KAAS,GAAI,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;IAAG;GAC9F,CAAC;EACH;EAEA,MAAM,iBAAiB,sBAAsB,UAAU,IAAI,sBAAsB,YAAY,MAAM,IAAI,KAAA;EACvG,IAAI,gBAAgB;GAClB,MAAM,OAAO,sBAAsB,cAAc;GACjD,MAAM,QACJ,0BAA0B,YAAY,aAAa,MAAM,uBAAuB,WAAW,UAAU,IAAI,CAAC;GAC5G,MAAM,aAAa,QAAQ,MAAM,MAAK,cAAa,UAAU,YAAY,MAAM,KAAK,YAAY,CAAC;GACjG,IAAI,MAAM,SAAS,KAAK,CAAC,YACvB,QAAQ,KAAK,iEAAiE,EAAE,KAAK,eAAe,CAAC;GAEvG,MAAM,MAAM,UAAU;IACpB,gBAAgB,YAAY;IAC5B,OAAO;KACL,QAAQ;KACR,SAAS,CAAC;MAAE,MAAM;MAAgB,IAAI;KAAe,GAAG,GAAG,OAAO;KAClE,UAAU;MAAE,KAAK;MAAgB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;KAAG;IACzE;GACF,CAAC;EACH;CACF,SAAS,KAAK;EACZ,QAAQ,KAAK,8CAA8C,EACzD,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EACxD,CAAC;CACH;AACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FactoryStorageDomain } from '@mastra/core/storage';
|
|
2
|
-
import type { CollectionSchema } from '@mastra/core/storage';
|
|
2
|
+
import type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';
|
|
3
|
+
export declare const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;
|
|
3
4
|
export declare const FACTORY_MODEL_SCOPES: readonly ["factory", "user"];
|
|
4
5
|
export type FactoryModelScope = (typeof FACTORY_MODEL_SCOPES)[number];
|
|
5
6
|
export interface FactoryProject {
|
|
@@ -18,6 +19,35 @@ export interface FactoryProject {
|
|
|
18
19
|
autoRunEnabled: boolean;
|
|
19
20
|
/** Whether the Factory answers a run's plan itself instead of waiting for a person. */
|
|
20
21
|
autoApprovePlans: boolean;
|
|
22
|
+
/** Workspace root in the sandbox; linked repositories are checked out beneath it. */
|
|
23
|
+
sandboxWorkingDirectory: string | null;
|
|
24
|
+
/** Provider settings document validated by the configured FactorySandbox. Only keys the user set. */
|
|
25
|
+
sandboxSettings: Record<string, unknown> | null;
|
|
26
|
+
/** Command run once in the workspace root after every repository's own setup. */
|
|
27
|
+
workspaceSetupCommand: string | null;
|
|
28
|
+
/** Template id of the environment's current build, written by the build path. */
|
|
29
|
+
activeTemplateId: string | null;
|
|
30
|
+
/** Repository slug → commit the active template was built at. */
|
|
31
|
+
activeTemplateHeads: Record<string, string> | null;
|
|
32
|
+
/** Provider build id of the most recent build attempt; its status is read live from the provider. */
|
|
33
|
+
lastBuildId: string | null;
|
|
34
|
+
/** Repository slug → commit the most recent build attempt pinned, so its status can be read back. */
|
|
35
|
+
lastBuildHeads: Record<string, string> | null;
|
|
36
|
+
/** Fingerprint of the settings, repositories and setup commands the most recent build attempt used. */
|
|
37
|
+
lastBuildInputs: string | null;
|
|
38
|
+
/** When the most recent build attempt started, whatever triggered it. */
|
|
39
|
+
lastBuildAttemptedAt: Date | null;
|
|
40
|
+
/** When a push last started a build: the leading edge of the push debounce window. */
|
|
41
|
+
lastPushBuildAt: Date | null;
|
|
42
|
+
/**
|
|
43
|
+
* A run's build-start lease lapsed, so a build it may have started is not
|
|
44
|
+
* on record. Cleared once a run reconciles it with a provider that lists builds.
|
|
45
|
+
*/
|
|
46
|
+
buildStartUncertain: boolean;
|
|
47
|
+
/** Whether a push to an environment repository's default branch starts a build. */
|
|
48
|
+
buildOnPushEnabled: boolean;
|
|
49
|
+
/** Minutes after a push-triggered attempt during which further pushes do not build. */
|
|
50
|
+
buildPushDebounceMinutes: number;
|
|
21
51
|
createdAt: Date;
|
|
22
52
|
updatedAt: Date;
|
|
23
53
|
}
|
|
@@ -34,6 +64,17 @@ export interface UpdateFactoryProjectInput {
|
|
|
34
64
|
slackWorkItemsEnabled?: boolean;
|
|
35
65
|
autoRunEnabled?: boolean;
|
|
36
66
|
autoApprovePlans?: boolean;
|
|
67
|
+
sandboxWorkingDirectory?: string | null;
|
|
68
|
+
sandboxSettings?: Record<string, unknown> | null;
|
|
69
|
+
workspaceSetupCommand?: string | null;
|
|
70
|
+
activeTemplateId?: string | null;
|
|
71
|
+
activeTemplateHeads?: Record<string, string> | null;
|
|
72
|
+
lastBuildId?: string | null;
|
|
73
|
+
lastBuildHeads?: Record<string, string> | null;
|
|
74
|
+
lastBuildInputs?: string | null;
|
|
75
|
+
lastBuildAttemptedAt?: Date | null;
|
|
76
|
+
buildOnPushEnabled?: boolean;
|
|
77
|
+
buildPushDebounceMinutes?: number;
|
|
37
78
|
}
|
|
38
79
|
export declare const FACTORY_PROJECTS_SCHEMA: CollectionSchema;
|
|
39
80
|
export declare class FactoryProjectsStorage extends FactoryStorageDomain {
|
|
@@ -60,8 +101,80 @@ export declare class FactoryProjectsStorage extends FactoryStorageDomain {
|
|
|
60
101
|
update({ orgId, id, input, }: {
|
|
61
102
|
orgId: string;
|
|
62
103
|
id: string;
|
|
63
|
-
input
|
|
104
|
+
/** A function input runs in a transaction; writes through its `ops` commit or roll back with the project. */
|
|
105
|
+
input: UpdateFactoryProjectInput | ((current: FactoryProject, ops: FactoryStorageOps) => Promise<UpdateFactoryProjectInput | null>);
|
|
64
106
|
}): Promise<FactoryProject | null>;
|
|
107
|
+
/**
|
|
108
|
+
* Leading-edge debounce for push-triggered builds: stamps
|
|
109
|
+
* `last_push_build_at = now` and resolves true when no push started a build
|
|
110
|
+
* within the last `debounceMinutes`, else writes nothing and resolves
|
|
111
|
+
* false. Taken right before the provider start, so a push that skips
|
|
112
|
+
* (another run starting, a build in progress) never closes the window. The read and the write run in one transaction, so two concurrent
|
|
113
|
+
* webhooks never both win, even on different database connections.
|
|
114
|
+
*/
|
|
115
|
+
claimBuildAttempt({ id, debounceMinutes, now, }: {
|
|
116
|
+
id: string;
|
|
117
|
+
debounceMinutes: number;
|
|
118
|
+
now?: Date;
|
|
119
|
+
}): Promise<boolean>;
|
|
120
|
+
/**
|
|
121
|
+
* Takes the project's build-start lease for `token`. Every trigger (manual,
|
|
122
|
+
* schedule, push) takes it before reading build state and holds it through
|
|
123
|
+
* `builds.start` and recording the result, so two runs never both start a
|
|
124
|
+
* build. `claimed` is false while another run holds an unexpired lease. The
|
|
125
|
+
* holder renews the lease while it works (`renewBuildStart`), so a lease
|
|
126
|
+
* only expires when its run died or stalled. Taking over an expired lease
|
|
127
|
+
* marks the start uncertain (that run's build may have reached the provider
|
|
128
|
+
* unrecorded), and the mark stays until a release resolves it; `uncertain`
|
|
129
|
+
* reports it. Only the claim is transactional; provider calls run outside it.
|
|
130
|
+
*/
|
|
131
|
+
claimBuildStart({ id, token, leaseMs, now, }: {
|
|
132
|
+
id: string;
|
|
133
|
+
token: string;
|
|
134
|
+
leaseMs: number;
|
|
135
|
+
now?: Date;
|
|
136
|
+
}): Promise<{
|
|
137
|
+
claimed: boolean;
|
|
138
|
+
uncertain: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Extends the build-start lease held by `token` to `now + leaseMs`. Resolves
|
|
142
|
+
* false, writing nothing, when `token` no longer holds it.
|
|
143
|
+
*/
|
|
144
|
+
renewBuildStart({ id, token, leaseMs, now, }: {
|
|
145
|
+
id: string;
|
|
146
|
+
token: string;
|
|
147
|
+
leaseMs: number;
|
|
148
|
+
now?: Date;
|
|
149
|
+
}): Promise<boolean>;
|
|
150
|
+
/**
|
|
151
|
+
* Releases the build-start lease taken with `token` and writes `changes` in
|
|
152
|
+
* the same transaction, but only while `token` still holds the lease. A run
|
|
153
|
+
* whose lease expired and was taken by a newer run writes nothing, so it
|
|
154
|
+
* never clears or overwrites that run's build. `resolved` clears an
|
|
155
|
+
* uncertain start. Resolves false when skipped.
|
|
156
|
+
*/
|
|
157
|
+
releaseBuildStart({ id, token, changes, resolved, now, }: {
|
|
158
|
+
id: string;
|
|
159
|
+
token: string;
|
|
160
|
+
resolved?: boolean;
|
|
161
|
+
changes?: Pick<UpdateFactoryProjectInput, 'lastBuildId' | 'lastBuildHeads' | 'lastBuildInputs' | 'lastBuildAttemptedAt'>;
|
|
162
|
+
now?: Date;
|
|
163
|
+
}): Promise<boolean>;
|
|
164
|
+
/**
|
|
165
|
+
* Pins the active template to a finished build, but only while that build is
|
|
166
|
+
* still the project's last one. Overlapping runs (Build now during a push
|
|
167
|
+
* build) can finish out of order; the write and the `last_build_id` check
|
|
168
|
+
* run in one transaction so a stale run never overwrites a newer build's
|
|
169
|
+
* pin. Resolves false when the pin was skipped.
|
|
170
|
+
*/
|
|
171
|
+
pinActiveTemplate({ id, buildId, templateId, heads, now, }: {
|
|
172
|
+
id: string;
|
|
173
|
+
buildId: string;
|
|
174
|
+
templateId: string;
|
|
175
|
+
heads: Record<string, string>;
|
|
176
|
+
now?: Date;
|
|
177
|
+
}): Promise<boolean>;
|
|
65
178
|
delete({ orgId, id }: {
|
|
66
179
|
orgId: string;
|
|
67
180
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/projects/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/projects/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEhF,eAAO,MAAM,mCAAmC,KAAK,CAAC;AACtD,eAAO,MAAM,oBAAoB,8BAA+B,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2FAA2F;IAC3F,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,sFAAsF;IACtF,UAAU,EAAE,iBAAiB,CAAC;IAC9B,2EAA2E;IAC3E,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kGAAkG;IAClG,cAAc,EAAE,OAAO,CAAC;IACxB,uFAAuF;IACvF,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qFAAqF;IACrF,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,qGAAqG;IACrG,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,iFAAiF;IACjF,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iFAAiF;IACjF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACnD,qGAAqG;IACrG,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qGAAqG;IACrG,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC9C,uGAAuG;IACvG,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yEAAyE;IACzE,oBAAoB,EAAE,IAAI,GAAG,IAAI,CAAC;IAClC,sFAAsF;IACtF,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mFAAmF;IACnF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,uFAAuF;IACvF,wBAAwB,EAAE,MAAM,CAAC;IACjC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjD,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACpD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oBAAoB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,eAAO,MAAM,uBAAuB,EAAE,gBAkCrC,CAAC;AA+DF,qBAAa,sBAAuB,SAAQ,oBAAoB;;;IAKxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC,MAAM,CAAC,EACX,KAAK,EACL,MAAM,EACN,KAAK,GACN,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,yBAAyB,CAAC;KAClC,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBrB,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAS7D,OAAO,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IASpC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAKjF,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAK/D,MAAM,CAAC,EACX,KAAK,EACL,EAAE,EACF,KAAK,GACN,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,6GAA6G;QAC7G,KAAK,EACD,yBAAyB,GACzB,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC,CAAC;KACtG,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA2ClC;;;;;;;OAOG;IACG,iBAAiB,CAAC,EACtB,EAAE,EACF,eAAe,EACf,GAAgB,GACjB,EAAE;QACD,EAAE,EAAE,MAAM,CAAC;QACX,eAAe,EAAE,MAAM,CAAC;QACxB,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC,OAAO,CAAC;IAapB;;;;;;;;;;OAUG;IACG,eAAe,CAAC,EACpB,EAAE,EACF,KAAK,EACL,OAAO,EACP,GAAgB,GACjB,EAAE;QACD,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAmBrD;;;OAGG;IACG,eAAe,CAAC,EACpB,EAAE,EACF,KAAK,EACL,OAAO,EACP,GAAgB,GACjB,EAAE;QACD,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC,OAAO,CAAC;IAYpB;;;;;;OAMG;IACG,iBAAiB,CAAC,EACtB,EAAE,EACF,KAAK,EACL,OAAY,EACZ,QAAgB,EAChB,GAAgB,GACjB,EAAE;QACD,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,IAAI,CACZ,yBAAyB,EACzB,aAAa,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,sBAAsB,CAC9E,CAAC;QACF,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBpB;;;;;;OAMG;IACG,iBAAiB,CAAC,EACtB,EAAE,EACF,OAAO,EACP,UAAU,EACV,KAAK,EACL,GAAgB,GACjB,EAAE;QACD,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC,OAAO,CAAC;IAYd,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAM3F"}
|