11import fs from 'fs'
22import path from 'path'
33import { execSync } from 'child_process'
4+ import { promisify } from 'util'
5+ import { exec } from 'child_process'
6+
7+ const execAsync = promisify ( exec )
48
59import { withTimeout } from '@codebuff/common/util/promise'
610import { CodebuffClient } from '../../sdk/src/client'
711import { withTestRepo } from '../subagents/test-repo-utils'
812
913import type { PrintModeEvent } from '@codebuff/common/types/print-mode'
10- import type { EvalCommitV2 } from './types'
14+ import type { EvalCommitV2 , FinalCheckOutput } from './types'
1115
1216export type AgentStep = PrintModeEvent
1317
@@ -22,6 +26,7 @@ export async function runAgentOnCommit({
2226 env,
2327 localAgentDefinitions,
2428 printEvents,
29+ finalCheckCommands,
2530} : {
2631 client : CodebuffClient
2732 agentId : string
@@ -31,13 +36,15 @@ export async function runAgentOnCommit({
3136 env ?: Record < string , string >
3237 localAgentDefinitions : any [ ]
3338 printEvents : boolean
39+ finalCheckCommands ?: string [ ]
3440} ) : Promise < {
3541 diff : string
3642 contextFiles : Record < string , string >
3743 durationMs : number
3844 cost : number
3945 error ?: string
4046 trace : AgentStep [ ]
47+ finalCheckOutputs ?: FinalCheckOutput [ ]
4148} > {
4249 console . log ( `[${ commit . id } ] Running agent ${ agentId } ...` )
4350 const startTime = Date . now ( )
@@ -46,6 +53,7 @@ export async function runAgentOnCommit({
4653 let error : string | undefined
4754 let cost = 0
4855 const trace : AgentStep [ ] = [ ]
56+ let finalCheckOutputs : FinalCheckOutput [ ] | undefined
4957
5058 try {
5159 await withTestRepo (
@@ -140,6 +148,18 @@ export async function runAgentOnCommit({
140148 contextFiles [ filePath ] = ''
141149 }
142150 }
151+
152+ // Run final check commands if specified
153+ if ( finalCheckCommands && finalCheckCommands . length > 0 ) {
154+ console . log (
155+ `[${ commit . id } ] Running ${ finalCheckCommands . length } final check commands...` ,
156+ )
157+ finalCheckOutputs = await runFinalCheckCommands (
158+ finalCheckCommands ,
159+ repoDir ,
160+ env ,
161+ )
162+ }
143163 } ,
144164 )
145165 } catch ( e ) {
@@ -155,5 +175,44 @@ export async function runAgentOnCommit({
155175 cost,
156176 error,
157177 trace,
178+ finalCheckOutputs,
158179 }
159180}
181+
182+ async function runFinalCheckCommands (
183+ commands : string [ ] ,
184+ cwd : string ,
185+ env ?: Record < string , string > ,
186+ ) : Promise < FinalCheckOutput [ ] > {
187+ const results : FinalCheckOutput [ ] = [ ]
188+
189+ for ( const command of commands ) {
190+ console . log ( ` Running: ${ command } ` )
191+ try {
192+ const { stdout, stderr } = await execAsync ( command , {
193+ cwd,
194+ encoding : 'utf-8' ,
195+ maxBuffer : 10 * 1024 * 1024 , // 10MB buffer
196+ env : { ...process . env , ...env } ,
197+ } )
198+ results . push ( {
199+ command,
200+ exitCode : 0 ,
201+ stdout,
202+ stderr,
203+ } )
204+ console . log ( ` ✓ Command succeeded: ${ command } ` )
205+ } catch ( error : any ) {
206+ // Command failed, but we still capture the output
207+ results . push ( {
208+ command,
209+ exitCode : error . code || 1 ,
210+ stdout : error . stdout || '' ,
211+ stderr : error . stderr || error . message || '' ,
212+ } )
213+ console . log ( ` ✗ Command failed (exit ${ error . code } ): ${ command } ` )
214+ }
215+ }
216+
217+ return results
218+ }
0 commit comments