@@ -3397,7 +3397,15 @@ Let's work through this together to get CI passing.`
33973397 currentSha = newShaResult . stdout . trim ( )
33983398 pushTime = Date . now ( )
33993399
3400- retryCount ++
3400+ // Reset retry count for new commit - it deserves its own attempts
3401+ log . substep (
3402+ `New commit ${ currentSha . substring ( 0 , 7 ) } , resetting retry counter` ,
3403+ )
3404+ retryCount = 0
3405+
3406+ // Wait for new CI run to start
3407+ log . substep ( 'Waiting 15 seconds for new CI run to start...' )
3408+ await new Promise ( resolve => setTimeout ( resolve , 15_000 ) )
34013409 continue
34023410 }
34033411
@@ -3591,6 +3599,8 @@ Fix all issues by making necessary file changes. Be direct, don't ask questions.
35913599 } ,
35923600 )
35933601
3602+ let pushedNewCommit = false
3603+
35943604 if ( fixStatusResult . stdout . trim ( ) ) {
35953605 log . progress ( 'Committing CI fixes' )
35963606
@@ -3602,72 +3612,28 @@ Fix all issues by making necessary file changes. Be direct, don't ask questions.
36023612 . join ( ', ' )
36033613 log . substep ( `Changed files: ${ changedFiles } ` )
36043614
3605- // Use Claude to create proper commits (logical groupings, no AI attribution)
3606- const commitPrompt = `Review the changes and create commits with logical groupings.
3607-
3608- Changed files: ${ changedFiles }
3609-
3610- Requirements:
3611- - Create one or more commits as needed for logical grouping
3612- - No AI attribution in commit messages
3613- - Follow conventional commit style from the repo
3614- - Be concise and descriptive
3615-
3616- Commit the changes now.`
3615+ // Stage all changes
3616+ await runCommand ( 'git' , [ 'add' , '.' ] , { cwd : rootPath } )
36173617
3618- const commitTmpFile = path . join (
3618+ // Generate commit message using Claude (non-interactive)
3619+ log . progress ( 'Generating CI fix commit message with Claude' )
3620+ const commitMessage = await generateCommitMessage (
3621+ claudeCmd ,
36193622 rootPath ,
3620- `.claude-commit- ${ Date . now ( ) } .txt` ,
3623+ opts ,
36213624 )
3622- await fs . writeFile ( commitTmpFile , commitPrompt , 'utf8' )
3623-
3624- const commitArgs = prepareClaudeArgs ( [ ] , opts )
3625- const commitArgsStr = commitArgs . join ( ' ' )
3626- const commitCommand = commitArgsStr
3627- ? `${ claudeCmd } ${ commitArgsStr } `
3628- : claudeCmd
3625+ log . substep ( `Commit message: ${ commitMessage } ` )
36293626
3630- let commitScriptCmd
3631- if ( WIN32 ) {
3632- const winptyCheck = await runCommandWithOutput ( 'where' , [ 'winpty' ] )
3633- if ( winptyCheck . exitCode === 0 ) {
3634- commitScriptCmd = `winpty ${ commitCommand } < "${ commitTmpFile } "`
3635- } else {
3636- commitScriptCmd = `${ commitCommand } < "${ commitTmpFile } "`
3637- }
3638- } else {
3639- commitScriptCmd = `script -q /dev/null sh -c '${ commitCommand } < "${ commitTmpFile } "'`
3627+ // Commit with generated message
3628+ const commitArgs = [ 'commit' , '-m' , commitMessage ]
3629+ if ( useNoVerify ) {
3630+ commitArgs . push ( '--no-verify' )
36403631 }
3641-
3642- const commitExitCode = await new Promise ( ( resolve , _reject ) => {
3643- const child = spawn ( commitScriptCmd , [ ] , {
3644- stdio : 'inherit' ,
3645- cwd : rootPath ,
3646- shell : true ,
3647- } )
3648-
3649- const sigintHandler = ( ) => {
3650- child . kill ( 'SIGINT' )
3651- resolve ( 130 )
3652- }
3653- process . on ( 'SIGINT' , sigintHandler )
3654-
3655- child . on ( 'exit' , code => {
3656- process . off ( 'SIGINT' , sigintHandler )
3657- resolve ( code || 0 )
3658- } )
3659-
3660- child . on ( 'error' , ( ) => {
3661- process . off ( 'SIGINT' , sigintHandler )
3662- resolve ( 1 )
3663- } )
3632+ const commitResult = await runCommandWithOutput ( 'git' , commitArgs , {
3633+ cwd : rootPath ,
36643634 } )
36653635
3666- try {
3667- await fs . unlink ( commitTmpFile )
3668- } catch { }
3669-
3670- if ( commitExitCode === 0 ) {
3636+ if ( commitResult . exitCode === 0 ) {
36713637 // Push the commits
36723638 await runCommand ( 'git' , [ 'push' ] , { cwd : rootPath } )
36733639 log . done ( 'Pushed fix commits' )
@@ -3682,12 +3648,28 @@ Commit the changes now.`
36823648 )
36833649 currentSha = newShaResult . stdout . trim ( )
36843650 pushTime = Date . now ( )
3651+ pushedNewCommit = true
3652+
3653+ // Reset retry count for new commit - it deserves its own attempts
3654+ log . substep (
3655+ `New commit ${ currentSha . substring ( 0 , 7 ) } , resetting retry counter` ,
3656+ )
3657+ retryCount = 0
3658+
3659+ // Wait for new CI run to start
3660+ log . substep ( 'Waiting 15 seconds for new CI run to start...' )
3661+ await new Promise ( resolve => setTimeout ( resolve , 15_000 ) )
36853662 } else {
3686- log . warn ( `Claude commit failed with exit code ${ commitExitCode } ` )
3663+ log . warn (
3664+ `Git commit failed: ${ commitResult . stderr || commitResult . stdout } ` ,
3665+ )
36873666 }
36883667 }
36893668
3690- retryCount ++
3669+ // Only increment retry count if we didn't push a new commit
3670+ if ( ! pushedNewCommit ) {
3671+ retryCount ++
3672+ }
36913673 } else {
36923674 log . error ( `CI still failing after ${ maxRetries } attempts` )
36933675 log . substep (
@@ -3920,79 +3902,39 @@ Fix the issue by making necessary file changes. Be direct, don't ask questions.`
39203902 . join ( ', ' )
39213903 log . substep ( `Changed files: ${ changedFiles } ` )
39223904
3923- // Use Claude to create proper commits (logical groupings, no AI attribution)
3924- const commitPrompt = `Review the changes and create commits with logical groupings.
3925-
3926- Changed files: ${ changedFiles }
3905+ // Stage all changes
3906+ await runCommand ( 'git' , [ 'add' , '.' ] , { cwd : rootPath } )
39273907
3928- Requirements:
3929- - Create one or more commits as needed for logical grouping
3930- - No AI attribution in commit messages
3931- - Follow conventional commit style from the repo
3932- - Be concise and descriptive
3933-
3934- Commit the changes now.`
3935-
3936- const commitTmpFile = path . join (
3908+ // Generate commit message using Claude (non-interactive)
3909+ log . progress (
3910+ `Generating commit message for ${ job . name } fix with Claude` ,
3911+ )
3912+ const commitMessage = await generateCommitMessage (
3913+ claudeCmd ,
39373914 rootPath ,
3938- `.claude-commit- ${ Date . now ( ) } .txt` ,
3915+ opts ,
39393916 )
3940- await fs . writeFile ( commitTmpFile , commitPrompt , 'utf8' )
3941-
3942- const commitArgs = prepareClaudeArgs ( [ ] , opts )
3943- const commitArgsStr = commitArgs . join ( ' ' )
3944- const commitCommand = commitArgsStr
3945- ? `${ claudeCmd } ${ commitArgsStr } `
3946- : claudeCmd
3917+ log . substep ( `Commit message: ${ commitMessage } ` )
39473918
3948- let commitScriptCmd
3949- if ( WIN32 ) {
3950- const winptyCheck = await runCommandWithOutput ( 'where' , [
3951- 'winpty' ,
3952- ] )
3953- if ( winptyCheck . exitCode === 0 ) {
3954- commitScriptCmd = `winpty ${ commitCommand } < "${ commitTmpFile } "`
3955- } else {
3956- commitScriptCmd = `${ commitCommand } < "${ commitTmpFile } "`
3957- }
3958- } else {
3959- commitScriptCmd = `script -q /dev/null sh -c '${ commitCommand } < "${ commitTmpFile } "'`
3919+ // Commit with generated message
3920+ const commitArgs = [ 'commit' , '-m' , commitMessage ]
3921+ if ( useNoVerify ) {
3922+ commitArgs . push ( '--no-verify' )
39603923 }
3961-
3962- const commitExitCode = await new Promise ( ( resolve , _reject ) => {
3963- const child = spawn ( commitScriptCmd , [ ] , {
3964- stdio : 'inherit' ,
3924+ const commitResult = await runCommandWithOutput (
3925+ 'git' ,
3926+ commitArgs ,
3927+ {
39653928 cwd : rootPath ,
3966- shell : true ,
3967- } )
3968-
3969- const sigintHandler = ( ) => {
3970- child . kill ( 'SIGINT' )
3971- resolve ( 130 )
3972- }
3973- process . on ( 'SIGINT' , sigintHandler )
3974-
3975- child . on ( 'exit' , code => {
3976- process . off ( 'SIGINT' , sigintHandler )
3977- resolve ( code || 0 )
3978- } )
3979-
3980- child . on ( 'error' , ( ) => {
3981- process . off ( 'SIGINT' , sigintHandler )
3982- resolve ( 1 )
3983- } )
3984- } )
3985-
3986- try {
3987- await fs . unlink ( commitTmpFile )
3988- } catch { }
3929+ } ,
3930+ )
39893931
3990- if ( commitExitCode === 0 ) {
3932+ if ( commitResult . exitCode === 0 ) {
39913933 log . done ( `Committed fix for ${ job . name } ` )
39923934 hasPendingCommits = true
39933935 } else {
39943936 log . warn (
3995- `Claude commit failed with exit code ${ commitExitCode } ` ,
3937+ `Git commit failed: ${ commitResult . stderr || commitResult . stdout } ` ,
39963938 )
39973939 }
39983940 } else {
0 commit comments