@open330/oac 2026.221.2 → 2026.222.2
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/README.md +170 -1
- package/dist/budget/index.js +1 -1
- package/dist/{chunk-EYUQMPVO.js → chunk-27FEE5KS.js} +86 -34
- package/dist/chunk-27FEE5KS.js.map +1 -0
- package/dist/{chunk-5GAUWC3L.js → chunk-ALBVUNUY.js} +1 -1
- package/dist/chunk-ALBVUNUY.js.map +1 -0
- package/dist/{chunk-VK33A5L4.js → chunk-ATVWSG75.js} +480 -232
- package/dist/chunk-ATVWSG75.js.map +1 -0
- package/dist/{chunk-7C7SC4TZ.js → chunk-I3TKNT4M.js} +9 -2
- package/dist/chunk-I3TKNT4M.js.map +1 -0
- package/dist/{chunk-6A37SKAJ.js → chunk-JDFAJP45.js} +1 -1
- package/dist/{chunk-6A37SKAJ.js.map → chunk-JDFAJP45.js.map} +1 -1
- package/dist/{chunk-OS3XDHOJ.js → chunk-UCYK4Z6O.js} +1 -1
- package/dist/chunk-UCYK4Z6O.js.map +1 -0
- package/dist/{chunk-OCCMKAJI.js → chunk-ZJBLRKCV.js} +3 -3
- package/dist/chunk-ZJBLRKCV.js.map +1 -0
- package/dist/cli/cli.js +7 -7
- package/dist/cli/index.js +7 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/completion/index.d.ts +1 -1
- package/dist/completion/index.js +2 -2
- package/dist/completion/index.js.map +1 -1
- package/dist/{config-DequKoFA.d.ts → config-DnzZ7w92.d.ts} +60 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +4 -2
- package/dist/dashboard/index.js +72 -23
- package/dist/dashboard/index.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -1
- package/dist/discovery/index.js +2 -2
- package/dist/execution/index.js +3 -3
- package/dist/repo/index.js +1 -1
- package/package.json +13 -15
- package/dist/chunk-5GAUWC3L.js.map +0 -1
- package/dist/chunk-7C7SC4TZ.js.map +0 -1
- package/dist/chunk-EYUQMPVO.js.map +0 -1
- package/dist/chunk-OCCMKAJI.js.map +0 -1
- package/dist/chunk-OS3XDHOJ.js.map +0 -1
- package/dist/chunk-VK33A5L4.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/completion/github-pr.ts","../../src/completion/issue-linker.ts","../../src/completion/diff-validator.ts","../../src/completion/handler.ts"],"sourcesContent":["import type { Octokit } from \"@octokit/rest\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport { type ResolvedRepo, completionError } from \"../core/index.js\";\n\nimport type { CreatedPR, PRCreationParams } from \"./types.js\";\n\ninterface PRDiffStats {\n filesChanged: number;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport async function createPR(params: PRCreationParams, octokit: Octokit): Promise<CreatedPR> {\n const { repo, task, result, branchName, baseBranch } = params;\n const pushedSha = await pushBranch(repo, branchName);\n const body = await buildPrBody(params);\n\n try {\n const created = await octokit.pulls.create({\n owner: repo.owner,\n repo: repo.name,\n title: `[OAC] ${task.title}`,\n body,\n head: branchName,\n base: baseBranch,\n draft: false,\n });\n\n await addLabels(octokit, repo, created.data.number, [\"oac-contribution\", task.source]);\n\n return {\n number: created.data.number,\n url: created.data.html_url,\n sha: created.data.head.sha || pushedSha,\n };\n } catch (error) {\n throw completionError(\n \"PR_CREATION_FAILED\",\n `Failed to create PR for \"${repo.fullName}\" on branch \"${branchName}\".`,\n {\n cause: error,\n context: {\n repo: repo.fullName,\n branchName,\n baseBranch,\n taskId: task.id,\n },\n },\n );\n }\n}\n\nexport async function pushBranch(repo: ResolvedRepo, branchName: string): Promise<string> {\n const git = simpleGit(resolveGitPath(repo));\n const headSha = (await git.revparse([\"HEAD\"])).trim();\n\n try {\n const remoteSha = await readRemoteBranchSha(git, branchName);\n if (remoteSha !== headSha) {\n await git.push(\"origin\", branchName);\n }\n } catch (error) {\n try {\n await git.raw([\"push\", \"--set-upstream\", \"origin\", branchName]);\n } catch (retryError) {\n throw completionError(\n \"PR_PUSH_REJECTED\",\n `Failed to push branch \"${branchName}\" for \"${repo.fullName}\".`,\n {\n cause: retryError,\n context: {\n repo: repo.fullName,\n branchName,\n headSha,\n initialError: error instanceof Error ? error.message : \"unknown push error\",\n },\n },\n );\n }\n }\n\n return headSha;\n}\n\nasync function buildPrBody(params: PRCreationParams): Promise<string> {\n const { repo, task, result, baseBranch, branchName } = params;\n const diffStats = await resolveDiffStats(repo, baseBranch, branchName);\n const linkedIssue = task.linkedIssue ? `\\nFixes #${task.linkedIssue.number}\\n` : \"\\n\";\n const agentLabel = resolveAgentLabel(task.metadata);\n const durationText = formatDurationSeconds(result.duration);\n const summaryText =\n task.description.trim().length > 0\n ? task.description.trim()\n : `Automated contribution for task \"${task.title}\".`;\n const filesChanged = result.filesChanged.length || diffStats.filesChanged;\n const filesPreview = renderFilesPreview(result.filesChanged);\n\n return [\n \"## Summary\",\n \"\",\n summaryText,\n \"\",\n \"## Changes\",\n \"\",\n filesPreview,\n \"\",\n `- **Files changed:** ${filesChanged}`,\n `- **Lines added:** ${diffStats.linesAdded}`,\n `- **Lines removed:** ${diffStats.linesRemoved}`,\n \"\",\n \"## Context\",\n \"\",\n `- **Task source:** ${task.source}`,\n `- **Agent:** ${agentLabel}`,\n `- **Tokens used:** ${result.totalTokensUsed}`,\n `- **Execution time:** ${durationText}`,\n linkedIssue.trimEnd(),\n \"\",\n \"---\",\n \"*This PR was automatically generated by OAC.*\",\n ].join(\"\\n\");\n}\n\nasync function resolveDiffStats(\n repo: ResolvedRepo,\n baseBranch: string,\n branchName: string,\n): Promise<PRDiffStats> {\n const git = simpleGit(resolveGitPath(repo));\n const ranges = [\n [`origin/${baseBranch}...${branchName}`],\n [`${baseBranch}...${branchName}`],\n [\"HEAD\"],\n [],\n ] as string[][];\n\n for (const range of ranges) {\n try {\n const summary = await git.diffSummary(range);\n return {\n filesChanged: summary.changed,\n linesAdded: summary.insertions,\n linesRemoved: summary.deletions,\n };\n } catch {} // best-effort: diff stats are optional\n }\n\n return {\n filesChanged: 0,\n linesAdded: 0,\n linesRemoved: 0,\n };\n}\n\nasync function addLabels(\n octokit: Octokit,\n repo: ResolvedRepo,\n prNumber: number,\n labels: string[],\n): Promise<void> {\n const uniqueLabels = [...new Set(labels.map((label) => label.trim()).filter(Boolean))];\n if (uniqueLabels.length === 0) {\n return;\n }\n\n try {\n await octokit.issues.addLabels({\n owner: repo.owner,\n repo: repo.name,\n issue_number: prNumber,\n labels: uniqueLabels,\n });\n } catch {\n // Labeling failure should not block PR creation.\n }\n}\n\nfunction resolveGitPath(repo: ResolvedRepo): string {\n return repo.worktreePath.trim().length > 0 ? repo.worktreePath : repo.localPath;\n}\n\nasync function readRemoteBranchSha(\n git: SimpleGit,\n branchName: string,\n): Promise<string | undefined> {\n const remoteHeads = await git.listRemote([\"--heads\", \"origin\", branchName]);\n const firstLine = remoteHeads\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n\n if (!firstLine) {\n return undefined;\n }\n\n const [sha] = firstLine.split(/\\s+/);\n return sha;\n}\n\nfunction resolveAgentLabel(metadata: Record<string, unknown>): string {\n const fromAgent = readMetadataString(metadata, [\"agent\", \"agentName\", \"provider\"]);\n return fromAgent ?? \"unknown\";\n}\n\nfunction readMetadataString(metadata: Record<string, unknown>, keys: string[]): string | undefined {\n for (const key of keys) {\n const value = metadata[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return undefined;\n}\n\nfunction renderFilesPreview(files: string[]): string {\n if (files.length === 0) {\n return \"- No file list was reported by the execution step.\";\n }\n\n const preview = files.slice(0, 15).map((path) => `- \\`${path}\\``);\n if (files.length > 15) {\n preview.push(`- ...and ${files.length - 15} more file(s)`);\n }\n\n return preview.join(\"\\n\");\n}\n\nfunction formatDurationSeconds(duration: number): string {\n if (!Number.isFinite(duration) || duration <= 0) {\n return \"0s\";\n }\n\n const seconds = duration > 1_000 ? duration / 1_000 : duration;\n if (seconds >= 100) {\n return `${Math.round(seconds)}s`;\n }\n\n return `${seconds.toFixed(1)}s`;\n}\n","import type { Octokit } from \"@octokit/rest\";\nimport { type ResolvedRepo, type Task, completionError } from \"../core/index.js\";\n\nimport type { CreatedPR } from \"./types.js\";\n\nexport async function linkIssueToePR(\n repo: ResolvedRepo,\n task: Task,\n pr: CreatedPR,\n octokit: Octokit,\n): Promise<void> {\n if (!task.linkedIssue) {\n return;\n }\n\n const issueNumber = task.linkedIssue.number;\n\n try {\n const issue = await octokit.issues.get({\n owner: repo.owner,\n repo: repo.name,\n issue_number: issueNumber,\n });\n\n if (issue.data.state === \"closed\") {\n return;\n }\n\n await octokit.issues.createComment({\n owner: repo.owner,\n repo: repo.name,\n issue_number: issueNumber,\n body: `OAC opened a PR for this issue: ${pr.url}`,\n });\n } catch (error) {\n if (isNonBlockingIssueError(error)) {\n return;\n }\n\n throw completionError(\n \"PR_CREATION_FAILED\",\n `Failed to link issue #${issueNumber} to PR #${pr.number}.`,\n {\n cause: error,\n context: {\n repo: repo.fullName,\n issueNumber,\n prNumber: pr.number,\n },\n },\n );\n }\n}\n\nexport const linkIssueToPR = linkIssueToePR;\n\nfunction isNonBlockingIssueError(error: unknown): boolean {\n if (!isStatusError(error)) {\n return false;\n }\n\n return error.status === 404 || error.status === 410 || error.status === 422;\n}\n\nfunction isStatusError(error: unknown): error is { status?: number } {\n return typeof error === \"object\" && error !== null && \"status\" in error;\n}\n","import { basename } from \"node:path\";\n\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport type { OacConfig } from \"../core/index.js\";\nimport { truncate } from \"../core/utils.js\";\n\nconst DEFAULT_MAX_DIFF_LINES = 500;\nconst DEFAULT_FORBIDDEN_PATTERNS: RegExp[] = [\n /eval\\s*\\(/,\n /new\\s+Function\\s*\\(/,\n /child_process/,\n /\\bexecSync\\s*\\(/,\n /\\bspawnSync\\s*\\(/,\n];\nconst DEFAULT_PROTECTED_FILES = [\".env*\", \"*.pem\", \"*.key\"];\n\ninterface ResolvedValidationConfig {\n maxDiffLines: number;\n forbiddenPatterns: RegExp[];\n protectedFiles: string[];\n}\n\nexport interface DiffValidationConfig {\n maxDiffLines?: number;\n forbiddenPatterns?: RegExp[];\n protectedFiles?: string[];\n}\n\nexport interface ValidationResult {\n valid: boolean;\n warnings: string[];\n errors: string[];\n}\n\nexport async function validateDiff(\n repoPath: string,\n config?: DiffValidationConfig | OacConfig,\n): Promise<ValidationResult> {\n const git = simpleGit(repoPath);\n const settings = resolveValidationConfig(config);\n const warnings: string[] = [];\n const errors: string[] = [];\n\n const [diffSummary, changedFiles, patch] = await Promise.all([\n readDiffSummary(git),\n readChangedFiles(git),\n readPatch(git),\n ]);\n\n const totalLinesChanged = diffSummary.insertions + diffSummary.deletions;\n if (totalLinesChanged > settings.maxDiffLines) {\n errors.push(\n `Diff too large: ${totalLinesChanged} changed lines exceeds maxDiffLines=${settings.maxDiffLines}.`,\n );\n } else if (totalLinesChanged > Math.floor(settings.maxDiffLines * 0.8)) {\n warnings.push(\n `Diff is near the maximum size (${totalLinesChanged}/${settings.maxDiffLines} changed lines).`,\n );\n }\n\n if (totalLinesChanged === 0) {\n warnings.push(\"No changed lines detected in the current diff.\");\n }\n\n const protectedFileHits = changedFiles.filter((path) =>\n settings.protectedFiles.some((pattern) => matchesGlob(path, pattern)),\n );\n if (protectedFileHits.length > 0) {\n errors.push(`Protected files were modified: ${protectedFileHits.join(\", \")}.`);\n }\n\n const forbiddenHits = findForbiddenPatternHits(patch, settings.forbiddenPatterns);\n errors.push(...forbiddenHits);\n\n return {\n valid: errors.length === 0,\n warnings,\n errors,\n };\n}\n\nasync function readDiffSummary(git: SimpleGit) {\n try {\n return await git.diffSummary([\"HEAD\"]);\n } catch {\n return git.diffSummary();\n }\n}\n\nasync function readChangedFiles(git: SimpleGit): Promise<string[]> {\n const withHead = await tryGitDiff(git, [\"--name-only\", \"HEAD\"]);\n const output = withHead ?? (await git.diff([\"--name-only\"]));\n\n return output\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\nasync function readPatch(git: SimpleGit): Promise<string> {\n const withHead = await tryGitDiff(git, [\"--no-color\", \"--unified=0\", \"HEAD\"]);\n if (withHead !== undefined) {\n return withHead;\n }\n return git.diff([\"--no-color\", \"--unified=0\"]);\n}\n\nasync function tryGitDiff(git: SimpleGit, args: string[]): Promise<string | undefined> {\n try {\n return await git.diff(args);\n } catch {\n return undefined;\n }\n}\n\nfunction resolveValidationConfig(\n config?: DiffValidationConfig | OacConfig,\n): ResolvedValidationConfig {\n const diffConfig = isOacConfig(config) ? undefined : config;\n const maxDiffLines = isOacConfig(config)\n ? config.execution.validation.maxDiffLines\n : diffConfig?.maxDiffLines;\n\n return {\n maxDiffLines:\n typeof maxDiffLines === \"number\" && maxDiffLines > 0\n ? Math.floor(maxDiffLines)\n : DEFAULT_MAX_DIFF_LINES,\n forbiddenPatterns:\n Array.isArray(diffConfig?.forbiddenPatterns) && diffConfig.forbiddenPatterns.length > 0\n ? diffConfig.forbiddenPatterns\n : DEFAULT_FORBIDDEN_PATTERNS,\n protectedFiles:\n Array.isArray(diffConfig?.protectedFiles) && diffConfig.protectedFiles.length > 0\n ? diffConfig.protectedFiles\n : DEFAULT_PROTECTED_FILES,\n };\n}\n\nfunction isOacConfig(value: DiffValidationConfig | OacConfig | undefined): value is OacConfig {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execution\" in value &&\n typeof (value as { execution?: unknown }).execution === \"object\"\n );\n}\n\nfunction findForbiddenPatternHits(diffPatch: string, patterns: RegExp[]): string[] {\n const hits = new Set<string>();\n let currentFile = \"(unknown)\";\n\n for (const line of diffPatch.split(\"\\n\")) {\n if (line.startsWith(\"+++ b/\")) {\n currentFile = line.slice(\"+++ b/\".length).trim();\n continue;\n }\n\n if (!line.startsWith(\"+\") || line.startsWith(\"+++\")) {\n continue;\n }\n\n const addedLine = line.slice(1);\n for (const pattern of patterns) {\n if (patternMatches(pattern, addedLine)) {\n const preview = truncate(addedLine.trim(), 120);\n hits.add(`Forbidden pattern \"${pattern}\" found in ${currentFile}: \"${preview}\".`);\n }\n }\n }\n\n return [...hits];\n}\n\nfunction patternMatches(pattern: RegExp, input: string): boolean {\n const normalizedFlags = pattern.flags.replaceAll(\"g\", \"\");\n const matcher = new RegExp(pattern.source, normalizedFlags);\n return matcher.test(input);\n}\n\nfunction matchesGlob(path: string, pattern: string): boolean {\n const regex = globToRegex(pattern);\n const filename = basename(path);\n return regex.test(path) || regex.test(filename);\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replaceAll(/[-/\\\\^$+?.()|[\\]{}]/g, \"\\\\$&\").replaceAll(\"*\", \".*\");\n return new RegExp(`^${escaped}$`);\n}\n\n\n","import type { Octokit } from \"@octokit/rest\";\nimport {\n type OacConfig,\n OacError,\n type OacEventBus,\n type ResolvedRepo,\n type Task,\n completionError,\n executionError,\n} from \"../core/index.js\";\n\nimport {\n type DiffValidationConfig,\n type ValidationResult,\n validateDiff,\n} from \"./diff-validator.js\";\nimport { createPR, pushBranch } from \"./github-pr.js\";\nimport { linkIssueToePR } from \"./issue-linker.js\";\nimport type {\n CompletionResult,\n CreatedPR,\n ExternalTaskRef,\n PRCreationParams,\n ProjectManagementProvider,\n} from \"./types.js\";\n\nexport interface CompletionHandlerOptions {\n octokit: Octokit;\n eventBus: OacEventBus;\n providers?: ProjectManagementProvider[];\n diffValidationConfig?: DiffValidationConfig | OacConfig;\n}\n\nexport interface CompletionHandlerParams extends PRCreationParams {\n jobId: string;\n externalTaskRef?: ExternalTaskRef;\n diffValidationConfig?: DiffValidationConfig | OacConfig;\n}\n\nexport class CompletionHandler {\n private readonly octokit: Octokit;\n private readonly eventBus: OacEventBus;\n private readonly providers: ProjectManagementProvider[];\n private readonly diffValidationConfig?: DiffValidationConfig | OacConfig;\n\n public constructor(options: CompletionHandlerOptions) {\n this.octokit = options.octokit;\n this.eventBus = options.eventBus;\n this.providers = options.providers ?? [];\n this.diffValidationConfig = options.diffValidationConfig;\n }\n\n public async handle(params: CompletionHandlerParams): Promise<CompletionResult> {\n return this.complete(params);\n }\n\n public async complete(params: CompletionHandlerParams): Promise<CompletionResult> {\n const warnings: string[] = [];\n const externalTaskRef = this.resolveExternalTaskRef(params.task, params.externalTaskRef);\n\n try {\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:validateDiff\");\n const validation = await validateDiff(\n resolveRepoPath(params.repo),\n params.diffValidationConfig ?? this.diffValidationConfig,\n );\n this.handleValidationResult(validation);\n warnings.push(...validation.warnings);\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:duplicatePRGuard\");\n const duplicatePr = await this.findExistingOacPR(params.repo, params.task);\n if (duplicatePr) {\n const skipMsg = `Skipped: existing OAC PR #${duplicatePr} already targets issue #${params.task.linkedIssue?.number ?? \"unknown\"}.`;\n warnings.push(skipMsg);\n return {\n summary: skipMsg,\n filesChanged: params.result.filesChanged.length,\n tokensUsed: params.result.totalTokensUsed,\n };\n }\n\n warnings.push(...(await this.notifyStarted(externalTaskRef)));\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:pushBranch\");\n await pushBranch(params.repo, params.branchName);\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:createPR\");\n const pr = await createPR(params, this.octokit);\n this.eventBus.emit(\"pr:created\", { jobId: params.jobId, prUrl: pr.url });\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:linkIssue\");\n const linkIssueWarning = await this.tryLinkIssue(params.repo, params.task, pr);\n if (linkIssueWarning) {\n warnings.push(linkIssueWarning);\n }\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:notifyWebhooks\");\n warnings.push(...(await this.notifyPRCreated(externalTaskRef, pr)));\n\n const completionResult = buildCompletionResult(params, pr, warnings);\n warnings.push(...(await this.notifyCompleted(externalTaskRef, completionResult)));\n\n return completionResult;\n } catch (error) {\n const normalizedError = this.normalizePipelineError(error, params);\n this.eventBus.emit(\"execution:failed\", {\n jobId: params.jobId,\n error: normalizedError,\n });\n await this.notifyFailed(externalTaskRef, normalizedError.message);\n throw normalizedError;\n }\n }\n\n private emitProgress(jobId: string, tokensUsed: number, stage: string): void {\n this.eventBus.emit(\"execution:progress\", {\n jobId,\n tokensUsed,\n stage,\n });\n }\n\n private handleValidationResult(validation: ValidationResult): void {\n if (validation.valid) {\n return;\n }\n\n const hasForbiddenPattern = validation.errors.some((message) =>\n message.toLowerCase().includes(\"forbidden pattern\"),\n );\n const errorCode = hasForbiddenPattern\n ? \"VALIDATION_FORBIDDEN_PATTERN\"\n : \"VALIDATION_DIFF_TOO_LARGE\";\n\n throw executionError(errorCode, \"Diff validation failed.\", {\n context: {\n errors: validation.errors,\n warnings: validation.warnings,\n },\n });\n }\n\n private async tryLinkIssue(\n repo: ResolvedRepo,\n task: Task,\n pr: CreatedPR,\n ): Promise<string | undefined> {\n try {\n await linkIssueToePR(repo, task, pr, this.octokit);\n return undefined;\n } catch (error) {\n return `Issue linking warning: ${toErrorMessage(error)}`;\n }\n }\n\n private async notifyStarted(ref: ExternalTaskRef | undefined): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyStarted\", (provider, taskRef) =>\n provider.notifyStarted(taskRef),\n );\n }\n\n private async notifyPRCreated(\n ref: ExternalTaskRef | undefined,\n pr: CreatedPR,\n ): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyPRCreated\", (provider, taskRef) =>\n provider.notifyPRCreated(taskRef, pr.url),\n );\n }\n\n private async notifyCompleted(\n ref: ExternalTaskRef | undefined,\n result: CompletionResult,\n ): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyCompleted\", (provider, taskRef) =>\n provider.notifyCompleted(taskRef, result),\n );\n }\n\n private async notifyFailed(ref: ExternalTaskRef | undefined, message: string): Promise<void> {\n await this.notifyProviders(ref, \"notifyFailed\", (provider, taskRef) =>\n provider.notifyFailed(taskRef, message),\n );\n }\n\n private async notifyProviders(\n ref: ExternalTaskRef | undefined,\n operationName: string,\n operation: (provider: ProjectManagementProvider, taskRef: ExternalTaskRef) => Promise<void>,\n ): Promise<string[]> {\n if (!ref) {\n return [];\n }\n\n const selectedProviders = this.providers.filter((provider) => provider.id === ref.provider);\n if (selectedProviders.length === 0) {\n return [];\n }\n\n const results = await Promise.allSettled(\n selectedProviders.map(async (provider) => {\n const isReachable = await provider.ping();\n if (!isReachable) {\n throw new Error(`Provider \"${provider.id}\" is unreachable.`);\n }\n await operation(provider, ref);\n }),\n );\n\n const warnings: string[] = [];\n for (let index = 0; index < results.length; index += 1) {\n const result = results[index];\n if (result.status === \"fulfilled\") {\n continue;\n }\n\n warnings.push(\n `${operationName} failed for provider \"${\n selectedProviders[index].id\n }\": ${toErrorMessage(result.reason)}`,\n );\n }\n\n return warnings;\n }\n\n /**\n * Pre-PR guard: checks for an existing open OAC pull request that already\n * targets the same issue. Returns the PR number if a duplicate exists.\n */\n private async findExistingOacPR(\n repo: ResolvedRepo,\n task: Task,\n ): Promise<number | undefined> {\n if (!task.linkedIssue) {\n return undefined;\n }\n\n const issueNumber = task.linkedIssue.number;\n\n try {\n const { data: pulls } = await this.octokit.pulls.list({\n owner: repo.owner,\n repo: repo.name,\n state: \"open\",\n per_page: 100,\n sort: \"updated\",\n direction: \"desc\",\n });\n\n const issueRefPattern = /(?:Fixes|Closes|Resolves)\\s+#(\\d+)/gi;\n for (const pr of pulls) {\n if (!pr.title.startsWith(\"[OAC]\")) continue;\n\n const body = pr.body ?? \"\";\n for (const match of body.matchAll(issueRefPattern)) {\n const num = Number.parseInt(match[1], 10);\n if (num === issueNumber) {\n return pr.number;\n }\n }\n }\n\n return undefined;\n } catch {\n // Guard failure should not block PR creation.\n return undefined;\n }\n }\n\n private resolveExternalTaskRef(\n task: Task,\n providedRef?: ExternalTaskRef,\n ): ExternalTaskRef | undefined {\n if (providedRef) {\n return providedRef;\n }\n\n if (task.linkedIssue) {\n return {\n provider: \"github\",\n externalId: `#${task.linkedIssue.number}`,\n url: task.linkedIssue.url,\n };\n }\n\n const metadata = task.metadata as Record<string, unknown>;\n const provider = readMetadataString(metadata, \"externalProvider\");\n const externalId = readMetadataString(metadata, \"externalId\");\n const url = readMetadataString(metadata, \"externalUrl\");\n\n if (!provider || !externalId) {\n return undefined;\n }\n\n return { provider, externalId, url };\n }\n\n private normalizePipelineError(error: unknown, params: CompletionHandlerParams): OacError {\n if (error instanceof OacError) {\n return error;\n }\n\n return completionError(\n \"PR_CREATION_FAILED\",\n `Completion pipeline failed for task \"${params.task.id}\" in \"${params.repo.fullName}\": ${toErrorMessage(\n error,\n )}`,\n {\n cause: error,\n context: {\n jobId: params.jobId,\n taskId: params.task.id,\n repo: params.repo.fullName,\n branchName: params.branchName,\n },\n },\n );\n }\n}\n\nfunction buildCompletionResult(\n params: CompletionHandlerParams,\n pr: CreatedPR,\n warnings: string[],\n): CompletionResult {\n const filesChanged = params.result.filesChanged.length;\n const warningSuffix = warnings.length > 0 ? ` Completed with ${warnings.length} warning(s).` : \"\";\n\n return {\n prUrl: pr.url,\n commitSha: pr.sha,\n summary: `Created PR #${pr.number} for \"${params.task.title}\".${warningSuffix}`,\n filesChanged,\n tokensUsed: params.result.totalTokensUsed,\n };\n}\n\nfunction resolveRepoPath(repo: ResolvedRepo): string {\n return repo.worktreePath.trim().length > 0 ? repo.worktreePath : repo.localPath;\n}\n\nfunction readMetadataString(metadata: Record<string, unknown>, key: string): string | undefined {\n const value = metadata[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n return undefined;\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message.trim();\n }\n return \"Unknown error\";\n}\n"],"mappings":"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","names":["simpleGit","simpleGit","readMetadataString"]}
|
|
1
|
+
{"version":3,"sources":["../../src/completion/github-pr.ts","../../src/completion/issue-linker.ts","../../src/completion/diff-validator.ts","../../src/completion/handler.ts"],"sourcesContent":["import type { Octokit } from \"@octokit/rest\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport { type ResolvedRepo, completionError } from \"../core/index.js\";\n\nimport type { CreatedPR, PRCreationParams } from \"./types.js\";\n\ninterface PRDiffStats {\n filesChanged: number;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport async function createPR(params: PRCreationParams, octokit: Octokit): Promise<CreatedPR> {\n const { repo, task, result, branchName, baseBranch } = params;\n const pushedSha = await pushBranch(repo, branchName);\n const body = await buildPrBody(params);\n\n try {\n const created = await octokit.pulls.create({\n owner: repo.owner,\n repo: repo.name,\n title: `[OAC] ${task.title}`,\n body,\n head: branchName,\n base: baseBranch,\n draft: false,\n });\n\n await addLabels(octokit, repo, created.data.number, [\"oac-contribution\", task.source]);\n\n return {\n number: created.data.number,\n url: created.data.html_url,\n sha: created.data.head.sha || pushedSha,\n };\n } catch (error) {\n throw completionError(\n \"PR_CREATION_FAILED\",\n `Failed to create PR for \"${repo.fullName}\" on branch \"${branchName}\".`,\n {\n cause: error,\n context: {\n repo: repo.fullName,\n branchName,\n baseBranch,\n taskId: task.id,\n },\n },\n );\n }\n}\n\nexport async function pushBranch(repo: ResolvedRepo, branchName: string): Promise<string> {\n const git = simpleGit(resolveGitPath(repo));\n const headSha = (await git.revparse([\"HEAD\"])).trim();\n\n try {\n const remoteSha = await readRemoteBranchSha(git, branchName);\n if (remoteSha !== headSha) {\n await git.push(\"origin\", branchName);\n }\n } catch (error) {\n try {\n await git.raw([\"push\", \"--set-upstream\", \"origin\", branchName]);\n } catch (retryError) {\n throw completionError(\n \"PR_PUSH_REJECTED\",\n `Failed to push branch \"${branchName}\" for \"${repo.fullName}\".`,\n {\n cause: retryError,\n context: {\n repo: repo.fullName,\n branchName,\n headSha,\n initialError: error instanceof Error ? error.message : \"unknown push error\",\n },\n },\n );\n }\n }\n\n return headSha;\n}\n\nasync function buildPrBody(params: PRCreationParams): Promise<string> {\n const { repo, task, result, baseBranch, branchName } = params;\n const diffStats = await resolveDiffStats(repo, baseBranch, branchName);\n const linkedIssue = task.linkedIssue ? `\\nFixes #${task.linkedIssue.number}\\n` : \"\\n\";\n const agentLabel = resolveAgentLabel(task.metadata);\n const durationText = formatDurationSeconds(result.duration);\n const summaryText =\n task.description.trim().length > 0\n ? task.description.trim()\n : `Automated contribution for task \"${task.title}\".`;\n const filesChanged = result.filesChanged.length || diffStats.filesChanged;\n const filesPreview = renderFilesPreview(result.filesChanged);\n\n return [\n \"## Summary\",\n \"\",\n summaryText,\n \"\",\n \"## Changes\",\n \"\",\n filesPreview,\n \"\",\n `- **Files changed:** ${filesChanged}`,\n `- **Lines added:** ${diffStats.linesAdded}`,\n `- **Lines removed:** ${diffStats.linesRemoved}`,\n \"\",\n \"## Context\",\n \"\",\n `- **Task source:** ${task.source}`,\n `- **Agent:** ${agentLabel}`,\n `- **Tokens used:** ${result.totalTokensUsed}`,\n `- **Execution time:** ${durationText}`,\n linkedIssue.trimEnd(),\n \"\",\n \"---\",\n \"*This PR was automatically generated by OAC.*\",\n ].join(\"\\n\");\n}\n\nasync function resolveDiffStats(\n repo: ResolvedRepo,\n baseBranch: string,\n branchName: string,\n): Promise<PRDiffStats> {\n const git = simpleGit(resolveGitPath(repo));\n const ranges = [\n [`origin/${baseBranch}...${branchName}`],\n [`${baseBranch}...${branchName}`],\n [\"HEAD\"],\n [],\n ] as string[][];\n\n for (const range of ranges) {\n try {\n const summary = await git.diffSummary(range);\n return {\n filesChanged: summary.changed,\n linesAdded: summary.insertions,\n linesRemoved: summary.deletions,\n };\n } catch {} // best-effort: diff stats are optional\n }\n\n return {\n filesChanged: 0,\n linesAdded: 0,\n linesRemoved: 0,\n };\n}\n\nasync function addLabels(\n octokit: Octokit,\n repo: ResolvedRepo,\n prNumber: number,\n labels: string[],\n): Promise<void> {\n const uniqueLabels = [...new Set(labels.map((label) => label.trim()).filter(Boolean))];\n if (uniqueLabels.length === 0) {\n return;\n }\n\n try {\n await octokit.issues.addLabels({\n owner: repo.owner,\n repo: repo.name,\n issue_number: prNumber,\n labels: uniqueLabels,\n });\n } catch {\n // Labeling failure should not block PR creation.\n }\n}\n\nfunction resolveGitPath(repo: ResolvedRepo): string {\n return repo.worktreePath.trim().length > 0 ? repo.worktreePath : repo.localPath;\n}\n\nasync function readRemoteBranchSha(\n git: SimpleGit,\n branchName: string,\n): Promise<string | undefined> {\n const remoteHeads = await git.listRemote([\"--heads\", \"origin\", branchName]);\n const firstLine = remoteHeads\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n\n if (!firstLine) {\n return undefined;\n }\n\n const [sha] = firstLine.split(/\\s+/);\n return sha;\n}\n\nfunction resolveAgentLabel(metadata: Record<string, unknown>): string {\n const fromAgent = readMetadataString(metadata, [\"agent\", \"agentName\", \"provider\"]);\n return fromAgent ?? \"unknown\";\n}\n\nfunction readMetadataString(metadata: Record<string, unknown>, keys: string[]): string | undefined {\n for (const key of keys) {\n const value = metadata[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return undefined;\n}\n\nfunction renderFilesPreview(files: string[]): string {\n if (files.length === 0) {\n return \"- No file list was reported by the execution step.\";\n }\n\n const preview = files.slice(0, 15).map((path) => `- \\`${path}\\``);\n if (files.length > 15) {\n preview.push(`- ...and ${files.length - 15} more file(s)`);\n }\n\n return preview.join(\"\\n\");\n}\n\nfunction formatDurationSeconds(duration: number): string {\n if (!Number.isFinite(duration) || duration <= 0) {\n return \"0s\";\n }\n\n const seconds = duration > 1_000 ? duration / 1_000 : duration;\n if (seconds >= 100) {\n return `${Math.round(seconds)}s`;\n }\n\n return `${seconds.toFixed(1)}s`;\n}\n","import type { Octokit } from \"@octokit/rest\";\nimport { type ResolvedRepo, type Task, completionError } from \"../core/index.js\";\n\nimport type { CreatedPR } from \"./types.js\";\n\nexport async function linkIssueToePR(\n repo: ResolvedRepo,\n task: Task,\n pr: CreatedPR,\n octokit: Octokit,\n): Promise<void> {\n if (!task.linkedIssue) {\n return;\n }\n\n const issueNumber = task.linkedIssue.number;\n\n try {\n const issue = await octokit.issues.get({\n owner: repo.owner,\n repo: repo.name,\n issue_number: issueNumber,\n });\n\n if (issue.data.state === \"closed\") {\n return;\n }\n\n await octokit.issues.createComment({\n owner: repo.owner,\n repo: repo.name,\n issue_number: issueNumber,\n body: `OAC opened a PR for this issue: ${pr.url}`,\n });\n } catch (error) {\n if (isNonBlockingIssueError(error)) {\n return;\n }\n\n throw completionError(\n \"PR_CREATION_FAILED\",\n `Failed to link issue #${issueNumber} to PR #${pr.number}.`,\n {\n cause: error,\n context: {\n repo: repo.fullName,\n issueNumber,\n prNumber: pr.number,\n },\n },\n );\n }\n}\n\nexport const linkIssueToPR = linkIssueToePR;\n\nfunction isNonBlockingIssueError(error: unknown): boolean {\n if (!isStatusError(error)) {\n return false;\n }\n\n return error.status === 404 || error.status === 410 || error.status === 422;\n}\n\nfunction isStatusError(error: unknown): error is { status?: number } {\n return typeof error === \"object\" && error !== null && \"status\" in error;\n}\n","import { basename } from \"node:path\";\n\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport type { OacConfig } from \"../core/index.js\";\nimport { truncate } from \"../core/utils.js\";\n\nconst DEFAULT_MAX_DIFF_LINES = 500;\nconst DEFAULT_FORBIDDEN_PATTERNS: RegExp[] = [\n /eval\\s*\\(/,\n /new\\s+Function\\s*\\(/,\n /child_process/,\n /\\bexecSync\\s*\\(/,\n /\\bspawnSync\\s*\\(/,\n];\nconst DEFAULT_PROTECTED_FILES = [\".env*\", \"*.pem\", \"*.key\"];\n\ninterface ResolvedValidationConfig {\n maxDiffLines: number;\n forbiddenPatterns: RegExp[];\n protectedFiles: string[];\n}\n\nexport interface DiffValidationConfig {\n maxDiffLines?: number;\n forbiddenPatterns?: RegExp[];\n protectedFiles?: string[];\n}\n\nexport interface ValidationResult {\n valid: boolean;\n warnings: string[];\n errors: string[];\n}\n\nexport async function validateDiff(\n repoPath: string,\n config?: DiffValidationConfig | OacConfig,\n): Promise<ValidationResult> {\n const git = simpleGit(repoPath);\n const settings = resolveValidationConfig(config);\n const warnings: string[] = [];\n const errors: string[] = [];\n\n const [diffSummary, changedFiles, patch] = await Promise.all([\n readDiffSummary(git),\n readChangedFiles(git),\n readPatch(git),\n ]);\n\n const totalLinesChanged = diffSummary.insertions + diffSummary.deletions;\n if (totalLinesChanged > settings.maxDiffLines) {\n errors.push(\n `Diff too large: ${totalLinesChanged} changed lines exceeds maxDiffLines=${settings.maxDiffLines}.`,\n );\n } else if (totalLinesChanged > Math.floor(settings.maxDiffLines * 0.8)) {\n warnings.push(\n `Diff is near the maximum size (${totalLinesChanged}/${settings.maxDiffLines} changed lines).`,\n );\n }\n\n if (totalLinesChanged === 0) {\n warnings.push(\"No changed lines detected in the current diff.\");\n }\n\n const protectedFileHits = changedFiles.filter((path) =>\n settings.protectedFiles.some((pattern) => matchesGlob(path, pattern)),\n );\n if (protectedFileHits.length > 0) {\n errors.push(`Protected files were modified: ${protectedFileHits.join(\", \")}.`);\n }\n\n const forbiddenHits = findForbiddenPatternHits(patch, settings.forbiddenPatterns);\n errors.push(...forbiddenHits);\n\n return {\n valid: errors.length === 0,\n warnings,\n errors,\n };\n}\n\nasync function readDiffSummary(git: SimpleGit) {\n try {\n return await git.diffSummary([\"HEAD\"]);\n } catch {\n return git.diffSummary();\n }\n}\n\nasync function readChangedFiles(git: SimpleGit): Promise<string[]> {\n const withHead = await tryGitDiff(git, [\"--name-only\", \"HEAD\"]);\n const output = withHead ?? (await git.diff([\"--name-only\"]));\n\n return output\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\nasync function readPatch(git: SimpleGit): Promise<string> {\n const withHead = await tryGitDiff(git, [\"--no-color\", \"--unified=0\", \"HEAD\"]);\n if (withHead !== undefined) {\n return withHead;\n }\n return git.diff([\"--no-color\", \"--unified=0\"]);\n}\n\nasync function tryGitDiff(git: SimpleGit, args: string[]): Promise<string | undefined> {\n try {\n return await git.diff(args);\n } catch {\n return undefined;\n }\n}\n\nfunction resolveValidationConfig(\n config?: DiffValidationConfig | OacConfig,\n): ResolvedValidationConfig {\n const diffConfig = isOacConfig(config) ? undefined : config;\n const maxDiffLines = isOacConfig(config)\n ? config.execution.validation.maxDiffLines\n : diffConfig?.maxDiffLines;\n\n return {\n maxDiffLines:\n typeof maxDiffLines === \"number\" && maxDiffLines > 0\n ? Math.floor(maxDiffLines)\n : DEFAULT_MAX_DIFF_LINES,\n forbiddenPatterns:\n Array.isArray(diffConfig?.forbiddenPatterns) && diffConfig.forbiddenPatterns.length > 0\n ? diffConfig.forbiddenPatterns\n : DEFAULT_FORBIDDEN_PATTERNS,\n protectedFiles:\n Array.isArray(diffConfig?.protectedFiles) && diffConfig.protectedFiles.length > 0\n ? diffConfig.protectedFiles\n : DEFAULT_PROTECTED_FILES,\n };\n}\n\nfunction isOacConfig(value: DiffValidationConfig | OacConfig | undefined): value is OacConfig {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execution\" in value &&\n typeof (value as { execution?: unknown }).execution === \"object\"\n );\n}\n\nfunction findForbiddenPatternHits(diffPatch: string, patterns: RegExp[]): string[] {\n const hits = new Set<string>();\n let currentFile = \"(unknown)\";\n\n for (const line of diffPatch.split(\"\\n\")) {\n if (line.startsWith(\"+++ b/\")) {\n currentFile = line.slice(\"+++ b/\".length).trim();\n continue;\n }\n\n if (!line.startsWith(\"+\") || line.startsWith(\"+++\")) {\n continue;\n }\n\n const addedLine = line.slice(1);\n for (const pattern of patterns) {\n if (patternMatches(pattern, addedLine)) {\n const preview = truncate(addedLine.trim(), 120);\n hits.add(`Forbidden pattern \"${pattern}\" found in ${currentFile}: \"${preview}\".`);\n }\n }\n }\n\n return [...hits];\n}\n\nfunction patternMatches(pattern: RegExp, input: string): boolean {\n const normalizedFlags = pattern.flags.replaceAll(\"g\", \"\");\n const matcher = new RegExp(pattern.source, normalizedFlags);\n return matcher.test(input);\n}\n\nfunction matchesGlob(path: string, pattern: string): boolean {\n const regex = globToRegex(pattern);\n const filename = basename(path);\n return regex.test(path) || regex.test(filename);\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replaceAll(/[-/\\\\^$+?.()|[\\]{}]/g, \"\\\\$&\").replaceAll(\"*\", \".*\");\n return new RegExp(`^${escaped}$`);\n}\n","import type { Octokit } from \"@octokit/rest\";\nimport {\n type OacConfig,\n OacError,\n type OacEventBus,\n type ResolvedRepo,\n type Task,\n completionError,\n executionError,\n} from \"../core/index.js\";\n\nimport {\n type DiffValidationConfig,\n type ValidationResult,\n validateDiff,\n} from \"./diff-validator.js\";\nimport { createPR, pushBranch } from \"./github-pr.js\";\nimport { linkIssueToePR } from \"./issue-linker.js\";\nimport type {\n CompletionResult,\n CreatedPR,\n ExternalTaskRef,\n PRCreationParams,\n ProjectManagementProvider,\n} from \"./types.js\";\n\nexport interface CompletionHandlerOptions {\n octokit: Octokit;\n eventBus: OacEventBus;\n providers?: ProjectManagementProvider[];\n diffValidationConfig?: DiffValidationConfig | OacConfig;\n}\n\nexport interface CompletionHandlerParams extends PRCreationParams {\n jobId: string;\n externalTaskRef?: ExternalTaskRef;\n diffValidationConfig?: DiffValidationConfig | OacConfig;\n}\n\nexport class CompletionHandler {\n private readonly octokit: Octokit;\n private readonly eventBus: OacEventBus;\n private readonly providers: ProjectManagementProvider[];\n private readonly diffValidationConfig?: DiffValidationConfig | OacConfig;\n\n public constructor(options: CompletionHandlerOptions) {\n this.octokit = options.octokit;\n this.eventBus = options.eventBus;\n this.providers = options.providers ?? [];\n this.diffValidationConfig = options.diffValidationConfig;\n }\n\n public async handle(params: CompletionHandlerParams): Promise<CompletionResult> {\n return this.complete(params);\n }\n\n public async complete(params: CompletionHandlerParams): Promise<CompletionResult> {\n const warnings: string[] = [];\n const externalTaskRef = this.resolveExternalTaskRef(params.task, params.externalTaskRef);\n\n try {\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:validateDiff\");\n const validation = await validateDiff(\n resolveRepoPath(params.repo),\n params.diffValidationConfig ?? this.diffValidationConfig,\n );\n this.handleValidationResult(validation);\n warnings.push(...validation.warnings);\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:duplicatePRGuard\");\n const duplicatePr = await this.findExistingOacPR(params.repo, params.task);\n if (duplicatePr) {\n const skipMsg = `Skipped: existing OAC PR #${duplicatePr} already targets issue #${params.task.linkedIssue?.number ?? \"unknown\"}.`;\n warnings.push(skipMsg);\n return {\n summary: skipMsg,\n filesChanged: params.result.filesChanged.length,\n tokensUsed: params.result.totalTokensUsed,\n };\n }\n\n warnings.push(...(await this.notifyStarted(externalTaskRef)));\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:pushBranch\");\n await pushBranch(params.repo, params.branchName);\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:createPR\");\n const pr = await createPR(params, this.octokit);\n this.eventBus.emit(\"pr:created\", { jobId: params.jobId, prUrl: pr.url });\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:linkIssue\");\n const linkIssueWarning = await this.tryLinkIssue(params.repo, params.task, pr);\n if (linkIssueWarning) {\n warnings.push(linkIssueWarning);\n }\n\n this.emitProgress(params.jobId, params.result.totalTokensUsed, \"completion:notifyWebhooks\");\n warnings.push(...(await this.notifyPRCreated(externalTaskRef, pr)));\n\n const completionResult = buildCompletionResult(params, pr, warnings);\n warnings.push(...(await this.notifyCompleted(externalTaskRef, completionResult)));\n\n return completionResult;\n } catch (error) {\n const normalizedError = this.normalizePipelineError(error, params);\n this.eventBus.emit(\"execution:failed\", {\n jobId: params.jobId,\n error: normalizedError,\n });\n await this.notifyFailed(externalTaskRef, normalizedError.message);\n throw normalizedError;\n }\n }\n\n private emitProgress(jobId: string, tokensUsed: number, stage: string): void {\n this.eventBus.emit(\"execution:progress\", {\n jobId,\n tokensUsed,\n stage,\n });\n }\n\n private handleValidationResult(validation: ValidationResult): void {\n if (validation.valid) {\n return;\n }\n\n const hasForbiddenPattern = validation.errors.some((message) =>\n message.toLowerCase().includes(\"forbidden pattern\"),\n );\n const errorCode = hasForbiddenPattern\n ? \"VALIDATION_FORBIDDEN_PATTERN\"\n : \"VALIDATION_DIFF_TOO_LARGE\";\n\n throw executionError(errorCode, \"Diff validation failed.\", {\n context: {\n errors: validation.errors,\n warnings: validation.warnings,\n },\n });\n }\n\n private async tryLinkIssue(\n repo: ResolvedRepo,\n task: Task,\n pr: CreatedPR,\n ): Promise<string | undefined> {\n try {\n await linkIssueToePR(repo, task, pr, this.octokit);\n return undefined;\n } catch (error) {\n return `Issue linking warning: ${toErrorMessage(error)}`;\n }\n }\n\n private async notifyStarted(ref: ExternalTaskRef | undefined): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyStarted\", (provider, taskRef) =>\n provider.notifyStarted(taskRef),\n );\n }\n\n private async notifyPRCreated(\n ref: ExternalTaskRef | undefined,\n pr: CreatedPR,\n ): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyPRCreated\", (provider, taskRef) =>\n provider.notifyPRCreated(taskRef, pr.url),\n );\n }\n\n private async notifyCompleted(\n ref: ExternalTaskRef | undefined,\n result: CompletionResult,\n ): Promise<string[]> {\n return this.notifyProviders(ref, \"notifyCompleted\", (provider, taskRef) =>\n provider.notifyCompleted(taskRef, result),\n );\n }\n\n private async notifyFailed(ref: ExternalTaskRef | undefined, message: string): Promise<void> {\n await this.notifyProviders(ref, \"notifyFailed\", (provider, taskRef) =>\n provider.notifyFailed(taskRef, message),\n );\n }\n\n private async notifyProviders(\n ref: ExternalTaskRef | undefined,\n operationName: string,\n operation: (provider: ProjectManagementProvider, taskRef: ExternalTaskRef) => Promise<void>,\n ): Promise<string[]> {\n if (!ref) {\n return [];\n }\n\n const selectedProviders = this.providers.filter((provider) => provider.id === ref.provider);\n if (selectedProviders.length === 0) {\n return [];\n }\n\n const results = await Promise.allSettled(\n selectedProviders.map(async (provider) => {\n const isReachable = await provider.ping();\n if (!isReachable) {\n throw new Error(`Provider \"${provider.id}\" is unreachable.`);\n }\n await operation(provider, ref);\n }),\n );\n\n const warnings: string[] = [];\n for (let index = 0; index < results.length; index += 1) {\n const result = results[index];\n if (result.status === \"fulfilled\") {\n continue;\n }\n\n warnings.push(\n `${operationName} failed for provider \"${\n selectedProviders[index].id\n }\": ${toErrorMessage(result.reason)}`,\n );\n }\n\n return warnings;\n }\n\n /**\n * Pre-PR guard: checks for an existing open OAC pull request that already\n * targets the same issue. Returns the PR number if a duplicate exists.\n */\n private async findExistingOacPR(repo: ResolvedRepo, task: Task): Promise<number | undefined> {\n if (!task.linkedIssue) {\n return undefined;\n }\n\n const issueNumber = task.linkedIssue.number;\n\n try {\n const { data: pulls } = await this.octokit.pulls.list({\n owner: repo.owner,\n repo: repo.name,\n state: \"open\",\n per_page: 100,\n sort: \"updated\",\n direction: \"desc\",\n });\n\n const issueRefPattern = /(?:Fixes|Closes|Resolves)\\s+#(\\d+)/gi;\n for (const pr of pulls) {\n if (!pr.title.startsWith(\"[OAC]\")) continue;\n\n const body = pr.body ?? \"\";\n for (const match of body.matchAll(issueRefPattern)) {\n const num = Number.parseInt(match[1], 10);\n if (num === issueNumber) {\n return pr.number;\n }\n }\n }\n\n return undefined;\n } catch {\n // Guard failure should not block PR creation.\n return undefined;\n }\n }\n\n private resolveExternalTaskRef(\n task: Task,\n providedRef?: ExternalTaskRef,\n ): ExternalTaskRef | undefined {\n if (providedRef) {\n return providedRef;\n }\n\n if (task.linkedIssue) {\n return {\n provider: \"github\",\n externalId: `#${task.linkedIssue.number}`,\n url: task.linkedIssue.url,\n };\n }\n\n const metadata = task.metadata as Record<string, unknown>;\n const provider = readMetadataString(metadata, \"externalProvider\");\n const externalId = readMetadataString(metadata, \"externalId\");\n const url = readMetadataString(metadata, \"externalUrl\");\n\n if (!provider || !externalId) {\n return undefined;\n }\n\n return { provider, externalId, url };\n }\n\n private normalizePipelineError(error: unknown, params: CompletionHandlerParams): OacError {\n if (error instanceof OacError) {\n return error;\n }\n\n return completionError(\n \"PR_CREATION_FAILED\",\n `Completion pipeline failed for task \"${params.task.id}\" in \"${params.repo.fullName}\": ${toErrorMessage(\n error,\n )}`,\n {\n cause: error,\n context: {\n jobId: params.jobId,\n taskId: params.task.id,\n repo: params.repo.fullName,\n branchName: params.branchName,\n },\n },\n );\n }\n}\n\nfunction buildCompletionResult(\n params: CompletionHandlerParams,\n pr: CreatedPR,\n warnings: string[],\n): CompletionResult {\n const filesChanged = params.result.filesChanged.length;\n const warningSuffix = warnings.length > 0 ? ` Completed with ${warnings.length} warning(s).` : \"\";\n\n return {\n prUrl: pr.url,\n commitSha: pr.sha,\n summary: `Created PR #${pr.number} for \"${params.task.title}\".${warningSuffix}`,\n filesChanged,\n tokensUsed: params.result.totalTokensUsed,\n };\n}\n\nfunction resolveRepoPath(repo: ResolvedRepo): string {\n return repo.worktreePath.trim().length > 0 ? repo.worktreePath : repo.localPath;\n}\n\nfunction readMetadataString(metadata: Record<string, unknown>, key: string): string | undefined {\n const value = metadata[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n return undefined;\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message.trim();\n }\n return \"Unknown error\";\n}\n"],"mappings":"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","names":["simpleGit","simpleGit","readMetadataString"]}
|
|
@@ -442,6 +442,19 @@ declare const AnalyzeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
442
442
|
staleAfterMs?: number | undefined;
|
|
443
443
|
contextDir?: string | undefined;
|
|
444
444
|
}>>;
|
|
445
|
+
declare const ContextPolicySchema: z.ZodDefault<z.ZodObject<{
|
|
446
|
+
mode: z.ZodDefault<z.ZodEnum<["off", "warn", "enforce"]>>;
|
|
447
|
+
requiredGlobs: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
448
|
+
maxAckItems: z.ZodDefault<z.ZodNumber>;
|
|
449
|
+
}, "strict", z.ZodTypeAny, {
|
|
450
|
+
mode: "off" | "warn" | "enforce";
|
|
451
|
+
requiredGlobs: string[];
|
|
452
|
+
maxAckItems: number;
|
|
453
|
+
}, {
|
|
454
|
+
mode?: "off" | "warn" | "enforce" | undefined;
|
|
455
|
+
requiredGlobs?: string[] | undefined;
|
|
456
|
+
maxAckItems?: number | undefined;
|
|
457
|
+
}>>;
|
|
445
458
|
declare const OacConfigSchema: z.ZodObject<{
|
|
446
459
|
repos: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
447
460
|
name: z.ZodString;
|
|
@@ -782,6 +795,19 @@ declare const OacConfigSchema: z.ZodObject<{
|
|
|
782
795
|
staleAfterMs?: number | undefined;
|
|
783
796
|
contextDir?: string | undefined;
|
|
784
797
|
}>>;
|
|
798
|
+
context: z.ZodDefault<z.ZodObject<{
|
|
799
|
+
mode: z.ZodDefault<z.ZodEnum<["off", "warn", "enforce"]>>;
|
|
800
|
+
requiredGlobs: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
801
|
+
maxAckItems: z.ZodDefault<z.ZodNumber>;
|
|
802
|
+
}, "strict", z.ZodTypeAny, {
|
|
803
|
+
mode: "off" | "warn" | "enforce";
|
|
804
|
+
requiredGlobs: string[];
|
|
805
|
+
maxAckItems: number;
|
|
806
|
+
}, {
|
|
807
|
+
mode?: "off" | "warn" | "enforce" | undefined;
|
|
808
|
+
requiredGlobs?: string[] | undefined;
|
|
809
|
+
maxAckItems?: number | undefined;
|
|
810
|
+
}>>;
|
|
785
811
|
}, "strict", z.ZodTypeAny, {
|
|
786
812
|
repos: (string | {
|
|
787
813
|
name: string;
|
|
@@ -865,6 +891,11 @@ declare const OacConfigSchema: z.ZodObject<{
|
|
|
865
891
|
staleAfterMs: number;
|
|
866
892
|
contextDir: string;
|
|
867
893
|
};
|
|
894
|
+
context: {
|
|
895
|
+
mode: "off" | "warn" | "enforce";
|
|
896
|
+
requiredGlobs: string[];
|
|
897
|
+
maxAckItems: number;
|
|
898
|
+
};
|
|
868
899
|
}, {
|
|
869
900
|
repos?: (string | {
|
|
870
901
|
name: string;
|
|
@@ -948,6 +979,11 @@ declare const OacConfigSchema: z.ZodObject<{
|
|
|
948
979
|
staleAfterMs?: number | undefined;
|
|
949
980
|
contextDir?: string | undefined;
|
|
950
981
|
} | undefined;
|
|
982
|
+
context?: {
|
|
983
|
+
mode?: "off" | "warn" | "enforce" | undefined;
|
|
984
|
+
requiredGlobs?: string[] | undefined;
|
|
985
|
+
maxAckItems?: number | undefined;
|
|
986
|
+
} | undefined;
|
|
951
987
|
}>;
|
|
952
988
|
declare const OacConfig: z.ZodObject<{
|
|
953
989
|
repos: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
@@ -1289,6 +1325,19 @@ declare const OacConfig: z.ZodObject<{
|
|
|
1289
1325
|
staleAfterMs?: number | undefined;
|
|
1290
1326
|
contextDir?: string | undefined;
|
|
1291
1327
|
}>>;
|
|
1328
|
+
context: z.ZodDefault<z.ZodObject<{
|
|
1329
|
+
mode: z.ZodDefault<z.ZodEnum<["off", "warn", "enforce"]>>;
|
|
1330
|
+
requiredGlobs: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
1331
|
+
maxAckItems: z.ZodDefault<z.ZodNumber>;
|
|
1332
|
+
}, "strict", z.ZodTypeAny, {
|
|
1333
|
+
mode: "off" | "warn" | "enforce";
|
|
1334
|
+
requiredGlobs: string[];
|
|
1335
|
+
maxAckItems: number;
|
|
1336
|
+
}, {
|
|
1337
|
+
mode?: "off" | "warn" | "enforce" | undefined;
|
|
1338
|
+
requiredGlobs?: string[] | undefined;
|
|
1339
|
+
maxAckItems?: number | undefined;
|
|
1340
|
+
}>>;
|
|
1292
1341
|
}, "strict", z.ZodTypeAny, {
|
|
1293
1342
|
repos: (string | {
|
|
1294
1343
|
name: string;
|
|
@@ -1372,6 +1421,11 @@ declare const OacConfig: z.ZodObject<{
|
|
|
1372
1421
|
staleAfterMs: number;
|
|
1373
1422
|
contextDir: string;
|
|
1374
1423
|
};
|
|
1424
|
+
context: {
|
|
1425
|
+
mode: "off" | "warn" | "enforce";
|
|
1426
|
+
requiredGlobs: string[];
|
|
1427
|
+
maxAckItems: number;
|
|
1428
|
+
};
|
|
1375
1429
|
}, {
|
|
1376
1430
|
repos?: (string | {
|
|
1377
1431
|
name: string;
|
|
@@ -1455,6 +1509,11 @@ declare const OacConfig: z.ZodObject<{
|
|
|
1455
1509
|
staleAfterMs?: number | undefined;
|
|
1456
1510
|
contextDir?: string | undefined;
|
|
1457
1511
|
} | undefined;
|
|
1512
|
+
context?: {
|
|
1513
|
+
mode?: "off" | "warn" | "enforce" | undefined;
|
|
1514
|
+
requiredGlobs?: string[] | undefined;
|
|
1515
|
+
maxAckItems?: number | undefined;
|
|
1516
|
+
} | undefined;
|
|
1458
1517
|
}>;
|
|
1459
1518
|
type OacConfig = z.output<typeof OacConfigSchema>;
|
|
1460
1519
|
type OacConfigInput = z.input<typeof OacConfigSchema>;
|
|
@@ -1465,4 +1524,4 @@ declare function defineConfig(config: OacConfigInput): OacConfigInput;
|
|
|
1465
1524
|
declare function interpolateEnvVars(value: string, env?: Record<string, string | undefined>, path?: string[]): string;
|
|
1466
1525
|
declare function loadConfig(config?: unknown, options?: LoadConfigOptions): OacConfig;
|
|
1467
1526
|
|
|
1468
|
-
export { AnalyzeSchema as A, BudgetSchema as B, CompletionSchema as C, DashboardSchema as D, ExecutionSchema as E, JiraIntegrationSchema as J, LinearIntegrationSchema as L, OacConfig as O, PrSchema as P, RepoTargetSchema as R, TrackingSchema as T, ValidationSchema as V,
|
|
1527
|
+
export { AnalyzeSchema as A, BudgetSchema as B, CompletionSchema as C, DashboardSchema as D, ExecutionSchema as E, JiraIntegrationSchema as J, LinearIntegrationSchema as L, OacConfig as O, PrSchema as P, RepoTargetSchema as R, TrackingSchema as T, ValidationSchema as V, ContextPolicySchema as a, DiscoveryScannersSchema as b, DiscoverySchema as c, type LoadConfigOptions as d, type OacConfigInput as e, OacConfigSchema as f, ProviderSchema as g, defineConfig as h, interpolateEnvVars as i, loadConfig as l };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AnalyzeSchema, B as BudgetSchema, C as CompletionSchema, D as DashboardSchema,
|
|
1
|
+
export { A as AnalyzeSchema, B as BudgetSchema, C as CompletionSchema, a as ContextPolicySchema, D as DashboardSchema, b as DiscoveryScannersSchema, c as DiscoverySchema, E as ExecutionSchema, J as JiraIntegrationSchema, L as LinearIntegrationSchema, d as LoadConfigOptions, O as OacConfig, e as OacConfigInput, f as OacConfigSchema, P as PrSchema, g as ProviderSchema, R as RepoTargetSchema, T as TrackingSchema, V as ValidationSchema, h as defineConfig, i as interpolateEnvVars, l as loadConfig } from '../config-DnzZ7w92.js';
|
|
2
2
|
export { B as BUDGET_ERROR_CODES, a as BudgetErrorCode, C as COMPLETION_ERROR_CODES, b as CONFIG_ERROR_CODES, c as CompletionErrorCode, d as ConfigErrorCode, D as DISCOVERY_ERROR_CODES, e as DiscoveryErrorCode, E as EXECUTION_ERROR_CODES, f as ExecutionErrorCode, O as OAC_ERROR_CODES, g as OacError, h as OacErrorCode, i as OacErrorOptions, j as OacErrorSeverity, k as OacEventBus, l as OacEvents, R as REPO_ERROR_CODES, m as RepoErrorCode, S as SYSTEM_ERROR_CODES, n as SystemErrorCode, o as budgetError, p as completionError, q as configError, r as createEventBus, s as discoveryError, t as executionError, u as repoError } from '../event-bus-KiuR6e3P.js';
|
|
3
3
|
export { A as AgentProviderId, C as ContributionLog, a as ContributionTask, E as Epic, b as EpicStatus, c as ExecutionMode, d as ExecutionPlan, e as ExecutionResult, R as ResolvedRepo, f as RunSummary, T as Task, g as TaskComplexity, h as TaskSource, i as TokenEstimate, U as UNLIMITED_BUDGET } from '../types-Ck7IucqK.js';
|
|
4
4
|
import 'zod';
|
package/dist/core/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
COMPLETION_ERROR_CODES,
|
|
6
6
|
CONFIG_ERROR_CODES,
|
|
7
7
|
CompletionSchema,
|
|
8
|
+
ContextPolicySchema,
|
|
8
9
|
DISCOVERY_ERROR_CODES,
|
|
9
10
|
DashboardSchema,
|
|
10
11
|
DiscoveryScannersSchema,
|
|
@@ -35,13 +36,13 @@ import {
|
|
|
35
36
|
interpolateEnvVars,
|
|
36
37
|
loadConfig,
|
|
37
38
|
repoError
|
|
38
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-I3TKNT4M.js";
|
|
39
40
|
import {
|
|
40
41
|
createMemoryMonitor,
|
|
41
42
|
getMemorySnapshot,
|
|
42
43
|
isRecord,
|
|
43
44
|
truncate
|
|
44
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-JDFAJP45.js";
|
|
45
46
|
export {
|
|
46
47
|
AnalyzeSchema,
|
|
47
48
|
BUDGET_ERROR_CODES,
|
|
@@ -49,6 +50,7 @@ export {
|
|
|
49
50
|
COMPLETION_ERROR_CODES,
|
|
50
51
|
CONFIG_ERROR_CODES,
|
|
51
52
|
CompletionSchema,
|
|
53
|
+
ContextPolicySchema,
|
|
52
54
|
DISCOVERY_ERROR_CODES,
|
|
53
55
|
DashboardSchema,
|
|
54
56
|
DiscoveryScannersSchema,
|
package/dist/dashboard/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cloneRepo,
|
|
3
3
|
resolveRepo
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-UCYK4Z6O.js";
|
|
5
5
|
import {
|
|
6
6
|
CompositeScanner,
|
|
7
7
|
GitHubIssuesScanner,
|
|
8
8
|
LintScanner,
|
|
9
9
|
TodoScanner,
|
|
10
10
|
rankTasks
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-ZJBLRKCV.js";
|
|
12
12
|
import {
|
|
13
13
|
buildExecutionPlan,
|
|
14
14
|
estimateTokens
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-ALBVUNUY.js";
|
|
16
16
|
import {
|
|
17
17
|
CodexAdapter,
|
|
18
18
|
createSandbox,
|
|
19
19
|
executeTask
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-27FEE5KS.js";
|
|
21
21
|
import {
|
|
22
22
|
createEventBus
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-I3TKNT4M.js";
|
|
24
|
+
import "../chunk-JDFAJP45.js";
|
|
25
25
|
import {
|
|
26
26
|
buildLeaderboard,
|
|
27
27
|
contributionLogSchema,
|
|
@@ -31,12 +31,14 @@ import {
|
|
|
31
31
|
// src/dashboard/server.ts
|
|
32
32
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
33
33
|
import { readFile, readdir } from "fs/promises";
|
|
34
|
-
import { resolve } from "path";
|
|
34
|
+
import { resolve as resolve2 } from "path";
|
|
35
35
|
import cors from "@fastify/cors";
|
|
36
36
|
import Fastify from "fastify";
|
|
37
37
|
|
|
38
38
|
// src/dashboard/pipeline.ts
|
|
39
39
|
import { randomUUID } from "crypto";
|
|
40
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
41
|
+
import { join, resolve } from "path";
|
|
40
42
|
import { execa } from "execa";
|
|
41
43
|
import PQueue from "p-queue";
|
|
42
44
|
function buildScanners() {
|
|
@@ -64,7 +66,7 @@ async function executeWithCodex(input) {
|
|
|
64
66
|
tokenBudget: input.estimate.totalEstimatedTokens,
|
|
65
67
|
timeoutMs: input.timeoutSeconds * 1e3
|
|
66
68
|
});
|
|
67
|
-
const commitResult = await commitSandboxChanges(sandbox.path, input.task);
|
|
69
|
+
const commitResult = await commitSandboxChanges(sandbox.path, input.task, input.baseBranch);
|
|
68
70
|
const filesChanged = commitResult.filesChanged.length > 0 ? commitResult.filesChanged : result.filesChanged.length > 0 ? result.filesChanged : [];
|
|
69
71
|
return {
|
|
70
72
|
execution: {
|
|
@@ -78,7 +80,7 @@ async function executeWithCodex(input) {
|
|
|
78
80
|
sandbox: sandboxInfo
|
|
79
81
|
};
|
|
80
82
|
} catch (error) {
|
|
81
|
-
const commitResult = await commitSandboxChanges(sandbox.path, input.task);
|
|
83
|
+
const commitResult = await commitSandboxChanges(sandbox.path, input.task, input.baseBranch);
|
|
82
84
|
if (commitResult.hasChanges) {
|
|
83
85
|
return {
|
|
84
86
|
execution: {
|
|
@@ -105,23 +107,24 @@ async function executeWithCodex(input) {
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
|
-
async function commitSandboxChanges(sandboxPath, task) {
|
|
110
|
+
async function commitSandboxChanges(sandboxPath, task, baseBranch) {
|
|
109
111
|
try {
|
|
110
112
|
const statusResult = await execa("git", ["status", "--porcelain"], { cwd: sandboxPath });
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
+
if (statusResult.stdout.trim()) {
|
|
114
|
+
await execa("git", ["add", "-A"], { cwd: sandboxPath });
|
|
115
|
+
await execa(
|
|
116
|
+
"git",
|
|
117
|
+
["commit", "-m", `[OAC] ${task.title}
|
|
118
|
+
|
|
119
|
+
Automated contribution by OAC.`],
|
|
120
|
+
{ cwd: sandboxPath }
|
|
121
|
+
);
|
|
113
122
|
}
|
|
114
|
-
await execa("git", ["
|
|
115
|
-
await execa("git", ["commit", "-m", `[OAC] ${task.title}
|
|
116
|
-
|
|
117
|
-
Automated contribution by OAC.`], {
|
|
118
|
-
cwd: sandboxPath
|
|
119
|
-
});
|
|
120
|
-
const diffResult = await execa("git", ["diff", "--name-only", "HEAD~1", "HEAD"], {
|
|
123
|
+
const diffResult = await execa("git", ["diff", "--name-only", `origin/${baseBranch}`, "HEAD"], {
|
|
121
124
|
cwd: sandboxPath
|
|
122
125
|
});
|
|
123
126
|
const changedFiles = diffResult.stdout.trim().split("\n").filter(Boolean);
|
|
124
|
-
return { hasChanges:
|
|
127
|
+
return { hasChanges: changedFiles.length > 0, filesChanged: changedFiles };
|
|
125
128
|
} catch {
|
|
126
129
|
return { hasChanges: false, filesChanged: [] };
|
|
127
130
|
}
|
|
@@ -206,6 +209,45 @@ function resolveGithubUsername() {
|
|
|
206
209
|
}
|
|
207
210
|
return "oac-user";
|
|
208
211
|
}
|
|
212
|
+
async function writeContributionToSandbox(input) {
|
|
213
|
+
const { sandboxPath, task, execution, runId, repoOwner } = input;
|
|
214
|
+
const contributionsDir = resolve(sandboxPath, ".oac", "contributions");
|
|
215
|
+
await mkdir(contributionsDir, { recursive: true });
|
|
216
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
217
|
+
const contributor = resolveGithubUsername();
|
|
218
|
+
const datePrefix = timestamp.replace(/[:.]/g, "").replace("T", "-").slice(0, 15);
|
|
219
|
+
const safeTaskId = task.id.replace(/[^A-Za-z0-9-]/g, "-").replace(/-+/g, "-").slice(0, 40);
|
|
220
|
+
const filename = `${datePrefix}-${safeTaskId}.json`;
|
|
221
|
+
const metadata = {
|
|
222
|
+
version: "1.0",
|
|
223
|
+
runId,
|
|
224
|
+
timestamp,
|
|
225
|
+
contributor,
|
|
226
|
+
task: {
|
|
227
|
+
id: task.id,
|
|
228
|
+
title: task.title,
|
|
229
|
+
source: task.source,
|
|
230
|
+
complexity: task.complexity,
|
|
231
|
+
linkedIssue: task.linkedIssue ? { number: task.linkedIssue.number, url: task.linkedIssue.url } : void 0
|
|
232
|
+
},
|
|
233
|
+
execution: {
|
|
234
|
+
success: execution.success,
|
|
235
|
+
tokensUsed: execution.totalTokensUsed,
|
|
236
|
+
duration: execution.duration,
|
|
237
|
+
filesChanged: execution.filesChanged
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const filePath = join(contributionsDir, filename);
|
|
241
|
+
await writeFile(filePath, `${JSON.stringify(metadata, null, 2)}
|
|
242
|
+
`, "utf8");
|
|
243
|
+
try {
|
|
244
|
+
await execa("git", ["add", filePath], { cwd: sandboxPath });
|
|
245
|
+
await execa("git", ["commit", "-m", "[OAC] Add contribution metadata"], {
|
|
246
|
+
cwd: sandboxPath
|
|
247
|
+
});
|
|
248
|
+
} catch {
|
|
249
|
+
}
|
|
250
|
+
}
|
|
209
251
|
async function executePipeline(config, onEvent) {
|
|
210
252
|
const runId = randomUUID();
|
|
211
253
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -327,6 +369,13 @@ async function executePipeline(config, onEvent) {
|
|
|
327
369
|
}
|
|
328
370
|
let pr;
|
|
329
371
|
if (execution.success && sandbox && execution.filesChanged.length > 0) {
|
|
372
|
+
await writeContributionToSandbox({
|
|
373
|
+
sandboxPath: sandbox.sandboxPath,
|
|
374
|
+
task: entry.task,
|
|
375
|
+
execution,
|
|
376
|
+
runId,
|
|
377
|
+
repoOwner: resolvedRepo.owner
|
|
378
|
+
});
|
|
330
379
|
emit({
|
|
331
380
|
type: "run:stage",
|
|
332
381
|
stage: "creating-pr",
|
|
@@ -1067,7 +1116,7 @@ function broadcastEvent(event) {
|
|
|
1067
1116
|
}
|
|
1068
1117
|
}
|
|
1069
1118
|
async function readContributionLogs(oacDir) {
|
|
1070
|
-
const contributionsPath =
|
|
1119
|
+
const contributionsPath = resolve2(oacDir, ".oac", "contributions");
|
|
1071
1120
|
let entries;
|
|
1072
1121
|
try {
|
|
1073
1122
|
entries = await readdir(contributionsPath, { withFileTypes: true, encoding: "utf8" });
|
|
@@ -1078,7 +1127,7 @@ async function readContributionLogs(oacDir) {
|
|
|
1078
1127
|
const results = await Promise.all(
|
|
1079
1128
|
files.map(async (fileName) => {
|
|
1080
1129
|
try {
|
|
1081
|
-
const content = await readFile(
|
|
1130
|
+
const content = await readFile(resolve2(contributionsPath, fileName), "utf8");
|
|
1082
1131
|
const parsed = contributionLogSchema.safeParse(JSON.parse(content));
|
|
1083
1132
|
return parsed.success ? parsed.data : null;
|
|
1084
1133
|
} catch {
|
|
@@ -1093,7 +1142,7 @@ async function readRunStatus(oacDir) {
|
|
|
1093
1142
|
return currentRun;
|
|
1094
1143
|
}
|
|
1095
1144
|
try {
|
|
1096
|
-
const content = await readFile(
|
|
1145
|
+
const content = await readFile(resolve2(oacDir, ".oac", "status.json"), "utf8");
|
|
1097
1146
|
return JSON.parse(content);
|
|
1098
1147
|
} catch {
|
|
1099
1148
|
return { status: "idle", message: "No active runs" };
|