@@ -926,6 +926,66 @@ async function buildEnhancedPrompt(template, basePrompt, options = {}) {
926926 return enhancedPrompt
927927}
928928
929+ /**
930+ * Filter CI logs to extract only relevant failure information
931+ * Removes runner setup noise and focuses on actual errors
932+ */
933+ function filterCILogs ( rawLogs ) {
934+ const lines = rawLogs . split ( '\n' )
935+ const relevantLines = [ ]
936+ let inErrorSection = false
937+
938+ for ( const line of lines ) {
939+ // Skip runner metadata and setup
940+ if (
941+ line . includes ( 'Current runner version:' ) ||
942+ line . includes ( 'Runner Image' ) ||
943+ line . includes ( 'Operating System' ) ||
944+ line . includes ( 'GITHUB_TOKEN' ) ||
945+ line . includes ( 'Prepare workflow' ) ||
946+ line . includes ( 'Prepare all required' ) ||
947+ line . includes ( '##[group]' ) ||
948+ line . includes ( '##[endgroup]' ) ||
949+ line . includes ( 'Post job cleanup' ) ||
950+ line . includes ( 'git config' ) ||
951+ line . includes ( 'git submodule' ) ||
952+ line . includes ( 'Cleaning up orphan' ) ||
953+ line . includes ( 'secret source:' ) ||
954+ line . includes ( '[command]/usr/bin/git' )
955+ ) {
956+ continue
957+ }
958+
959+ // Detect error sections
960+ if (
961+ line . includes ( '##[error]' ) ||
962+ line . includes ( 'Error:' ) ||
963+ line . includes ( 'error TS' ) ||
964+ line . includes ( 'FAIL' ) ||
965+ line . includes ( '✗' ) ||
966+ line . includes ( '❌' ) ||
967+ line . includes ( 'failed' ) ||
968+ line . includes ( 'ELIFECYCLE' )
969+ ) {
970+ inErrorSection = true
971+ relevantLines . push ( line )
972+ } else if ( inErrorSection && line . trim ( ) !== '' ) {
973+ relevantLines . push ( line )
974+ // Keep context for 5 lines after error
975+ if ( relevantLines . length > 100 ) {
976+ inErrorSection = false
977+ }
978+ }
979+ }
980+
981+ // If no errors found, return last 50 lines (might contain useful context)
982+ if ( relevantLines . length === 0 ) {
983+ return lines . slice ( - 50 ) . join ( '\n' )
984+ }
985+
986+ return relevantLines . join ( '\n' )
987+ }
988+
929989/**
930990 * Prepare Claude command arguments for Claude Code.
931991 * Claude Code uses natural language prompts, not the same flags.
@@ -3249,9 +3309,23 @@ Let's work through this together to get CI passing.`
32493309 // Add newline after progress indicator before next output
32503310 console . log ( '' )
32513311
3312+ // Filter and show summary of logs
3313+ const rawLogs = logsResult . stdout || 'No logs available'
3314+ const filteredLogs = filterCILogs ( rawLogs )
3315+
3316+ const logLines = filteredLogs . split ( '\n' ) . slice ( 0 , 10 )
3317+ log . substep ( 'Error summary:' )
3318+ for ( const line of logLines ) {
3319+ if ( line . trim ( ) ) {
3320+ log . substep ( ` ${ line . trim ( ) . substring ( 0 , 100 ) } ` )
3321+ }
3322+ }
3323+ if ( filteredLogs . split ( '\n' ) . length > 10 ) {
3324+ log . substep ( ` ... (${ filteredLogs . split ( '\n' ) . length - 10 } more lines)` )
3325+ }
3326+
32523327 // Check if we've seen this CI error before
3253- const ciErrorOutput = logsResult . stdout || 'No logs available'
3254- const ciErrorHash = hashError ( ciErrorOutput )
3328+ const ciErrorHash = hashError ( filteredLogs )
32553329
32563330 if ( ciErrorHistory . has ( lastRunId ) ) {
32573331 log . error ( `Already attempted fix for run ${ lastRunId } ` )
@@ -3274,29 +3348,18 @@ Let's work through this together to get CI passing.`
32743348
32753349 // Analyze and fix with Claude
32763350 log . progress ( 'Analyzing CI failure with Claude' )
3277- const fixPrompt = `You are automatically fixing CI failures. The CI workflow failed for commit ${ currentSha } in ${ owner } /${ repo } .
32783351
3279- Failure logs:
3280- ${ logsResult . stdout || 'No logs available' }
3352+ // Keep logs under 2000 chars to avoid context issues
3353+ const truncatedLogs = filteredLogs . length > 2000
3354+ ? filteredLogs . substring ( 0 , 2000 ) + '\n... (truncated)'
3355+ : filteredLogs
32813356
3282- Your task:
3283- 1. Analyze these CI logs
3284- 2. Identify the root cause of failures
3285- 3. Apply fixes directly to resolve the issues
3357+ const fixPrompt = `Fix CI failures for commit ${ currentSha . substring ( 0 , 7 ) } in ${ owner } /${ repo } .
32863358
3287- Focus on:
3288- - Test failures: Update snapshots, fix test logic, or correct test data
3289- - Lint errors: Fix code style and formatting issues
3290- - Type checking: Fix type errors and missing type annotations
3291- - Build problems: Fix import errors, missing pinned dependencies, or syntax issues
3359+ Error logs:
3360+ ${ truncatedLogs }
32923361
3293- IMPORTANT:
3294- - Be direct and apply fixes immediately
3295- - Don't ask for clarification or permission
3296- - Make all necessary file changes to fix the CI
3297- - If multiple issues exist, fix them all
3298-
3299- Fix all CI failures now by making the necessary changes.`
3362+ Fix all issues by making necessary file changes. Be direct, don't ask questions.`
33003363
33013364 // Run Claude non-interactively to apply fixes
33023365 log . substep ( 'Applying CI fixes...' )
@@ -3355,11 +3418,20 @@ Fix all CI failures now by making the necessary changes.`
33553418 shell : true ,
33563419 } )
33573420
3421+ // Handle Ctrl+C gracefully
3422+ const sigintHandler = ( ) => {
3423+ child . kill ( 'SIGINT' )
3424+ resolve ( 130 )
3425+ }
3426+ process . on ( 'SIGINT' , sigintHandler )
3427+
33583428 child . on ( 'exit' , code => {
3429+ process . off ( 'SIGINT' , sigintHandler )
33593430 resolve ( code || 0 )
33603431 } )
33613432
33623433 child . on ( 'error' , ( ) => {
3434+ process . off ( 'SIGINT' , sigintHandler )
33633435 resolve ( 1 )
33643436 } )
33653437 } )
@@ -3505,34 +3577,38 @@ Fix all CI failures now by making the necessary changes.`
35053577 )
35063578 console . log ( '' )
35073579
3580+ // Filter logs to extract relevant errors
3581+ const rawLogs = logsResult . stdout || 'No logs available'
3582+ const filteredLogs = filterCILogs ( rawLogs )
3583+
3584+ // Show summary to user (not full logs)
3585+ const logLines = filteredLogs . split ( '\n' ) . slice ( 0 , 10 )
3586+ log . substep ( 'Error summary:' )
3587+ for ( const line of logLines ) {
3588+ if ( line . trim ( ) ) {
3589+ log . substep ( ` ${ line . trim ( ) . substring ( 0 , 100 ) } ` )
3590+ }
3591+ }
3592+ if ( filteredLogs . split ( '\n' ) . length > 10 ) {
3593+ log . substep ( ` ... (${ filteredLogs . split ( '\n' ) . length - 10 } more lines)` )
3594+ }
3595+
35083596 // Analyze and fix with Claude
35093597 log . progress ( `Analyzing failure in ${ job . name } ` )
3510- const fixPrompt = `You are automatically fixing CI failures. The job "${ job . name } " failed in workflow run ${ lastRunId } for commit ${ currentSha } in ${ owner } /${ repo } .
35113598
3512- Job: ${ job . name }
3513- Status: ${ job . conclusion }
3599+ // Keep logs under 2000 chars to avoid context issues
3600+ const truncatedLogs = filteredLogs . length > 2000
3601+ ? filteredLogs . substring ( 0 , 2000 ) + '\n... (truncated)'
3602+ : filteredLogs
35143603
3515- Failure logs:
3516- ${ logsResult . stdout || 'No logs available' }
3604+ const fixPrompt = `Fix CI failure in "${ job . name } " (run ${ lastRunId } , commit ${ currentSha . substring ( 0 , 7 ) } ).
35173605
3518- Your task:
3519- 1. Analyze these CI logs for the "${ job . name } " job
3520- 2. Identify the root cause of the failure
3521- 3. Apply fixes directly to resolve the issue
3522-
3523- Focus on:
3524- - Test failures: Update snapshots, fix test logic, or correct test data
3525- - Lint errors: Fix code style and formatting issues
3526- - Type checking: Fix type errors and missing type annotations
3527- - Build problems: Fix import errors, missing pinned dependencies, or syntax issues
3606+ Status: ${ job . conclusion }
35283607
3529- IMPORTANT:
3530- - Be direct and apply fixes immediately
3531- - Don't ask for clarification or permission
3532- - Make all necessary file changes to fix this specific failure
3533- - Focus ONLY on fixing the "${ job . name } " job
3608+ Error logs:
3609+ ${ truncatedLogs }
35343610
3535- Fix the failure now by making the necessary changes.`
3611+ Fix the issue by making necessary file changes. Be direct, don't ask questions .`
35363612
35373613 // Run Claude non-interactively to apply fixes
35383614 log . substep ( `Applying fix for ${ job . name } ...` )
@@ -3563,6 +3639,11 @@ Fix the failure now by making the necessary changes.`
35633639 ? `${ claudeCmd } ${ claudeArgs } `
35643640 : claudeCmd
35653641
3642+ // Debug: Show command being run
3643+ if ( claudeArgs ) {
3644+ log . substep ( `Running: claude ${ claudeArgs } ` )
3645+ }
3646+
35663647 // Use script command to create pseudo-TTY for Ink compatibility
35673648 // Platform-specific script command syntax
35683649 let scriptCmd
@@ -3587,11 +3668,20 @@ Fix the failure now by making the necessary changes.`
35873668 shell : true ,
35883669 } )
35893670
3671+ // Handle Ctrl+C gracefully
3672+ const sigintHandler = ( ) => {
3673+ child . kill ( 'SIGINT' )
3674+ resolve ( 130 )
3675+ }
3676+ process . on ( 'SIGINT' , sigintHandler )
3677+
35903678 child . on ( 'exit' , code => {
3679+ process . off ( 'SIGINT' , sigintHandler )
35913680 resolve ( code || 0 )
35923681 } )
35933682
35943683 child . on ( 'error' , ( ) => {
3684+ process . off ( 'SIGINT' , sigintHandler )
35953685 resolve ( 1 )
35963686 } )
35973687 } )
0 commit comments