Skip to content

Commit 9cae180

Browse files
committed
Improve --green auto-fix behavior with 10 automatic attempts before interactive mode
1 parent 607d962 commit 9cae180

File tree

1 file changed

+126
-28
lines changed

1 file changed

+126
-28
lines changed

scripts/claude.mjs

Lines changed: 126 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,7 @@ async function runGreen(claudeCmd, options = {}) {
15241524
const opts = { __proto__: null, ...options }
15251525
const maxRetries = parseInt(opts['max-retries'] || '3', 10)
15261526
const isDryRun = opts['dry-run']
1527+
const MAX_AUTO_FIX_ATTEMPTS = parseInt(opts['max-auto-fixes'] || '10', 10)
15271528

15281529
printHeader('Green CI Pipeline')
15291530

@@ -1537,6 +1538,8 @@ async function runGreen(claudeCmd, options = {}) {
15371538
{ name: 'Run tests', cmd: 'pnpm', args: ['run', 'test', '--', '--update'] }
15381539
]
15391540

1541+
let autoFixAttempts = 0
1542+
15401543
for (const check of localChecks) {
15411544
log.progress(check.name)
15421545

@@ -1552,30 +1555,103 @@ async function runGreen(claudeCmd, options = {}) {
15521555

15531556
if (result.exitCode !== 0) {
15541557
log.failed(`${check.name} failed`)
1558+
autoFixAttempts++
15551559

1556-
// Attempt to fix with Claude
1557-
log.progress('Attempting auto-fix with Claude')
1558-
const fixPrompt = `The command "${check.cmd} ${check.args.join(' ')}" failed in the ${path.basename(rootPath)} project.
1560+
// Decide whether to auto-fix or go interactive
1561+
const isAutoMode = autoFixAttempts <= MAX_AUTO_FIX_ATTEMPTS
1562+
const errorOutput = result.stderr || result.stdout || 'No error output available'
15591563

1560-
Please analyze the error and provide a fix. The error output was:
1561-
${result.stderr || result.stdout}
1564+
if (isAutoMode) {
1565+
// Attempt automatic fix
1566+
log.progress(`Attempting auto-fix with Claude (attempt ${autoFixAttempts}/${MAX_AUTO_FIX_ATTEMPTS})`)
15621567

1563-
Provide specific file edits or commands to fix this issue.`
1568+
const fixPrompt = `You are fixing a CI/build issue automatically. The command "${check.cmd} ${check.args.join(' ')}" failed in the ${path.basename(rootPath)} project.
15641569
1565-
await runCommand(claudeCmd, prepareClaudeArgs([], opts), {
1566-
input: fixPrompt,
1567-
stdio: 'inherit',
1568-
cwd: rootPath
1569-
})
1570+
Error output:
1571+
${errorOutput}
15701572
1571-
// Retry the check
1572-
log.progress(`Retrying ${check.name}`)
1573-
const retryResult = await runCommandWithOutput(check.cmd, check.args, {
1574-
cwd: rootPath
1575-
})
1573+
Your task:
1574+
1. Analyze the error
1575+
2. Provide the exact fix needed
1576+
3. Use file edits, commands, or both to resolve the issue
1577+
1578+
IMPORTANT:
1579+
- Be direct and specific - don't ask questions
1580+
- Provide complete solutions that will fix the error
1581+
- If the error is about missing dependencies, install them
1582+
- If it's a type error, fix the code
1583+
- If it's a lint error, fix the formatting
1584+
- If tests are failing, update snapshots or fix the test
1585+
1586+
Fix this issue now by making the necessary changes.`
1587+
1588+
// Run Claude non-interactively to get the fix
1589+
log.substep('Analyzing error and applying fixes...')
1590+
await runCommand(claudeCmd, prepareClaudeArgs([], opts), {
1591+
input: fixPrompt,
1592+
cwd: rootPath,
1593+
stdio: 'pipe' // Don't inherit stdio - run silently
1594+
})
1595+
1596+
// Give Claude's changes a moment to complete
1597+
await new Promise(resolve => setTimeout(resolve, 2000))
1598+
1599+
// Retry the check
1600+
log.progress(`Retrying ${check.name}`)
1601+
const retryResult = await runCommandWithOutput(check.cmd, check.args, {
1602+
cwd: rootPath
1603+
})
15761604

1577-
if (retryResult.exitCode !== 0) {
1578-
log.error(`Failed to fix ${check.name} automatically`)
1605+
if (retryResult.exitCode !== 0) {
1606+
// Auto-fix didn't work
1607+
if (autoFixAttempts >= MAX_AUTO_FIX_ATTEMPTS) {
1608+
// Switch to interactive mode
1609+
log.warn(`Auto-fix failed after ${MAX_AUTO_FIX_ATTEMPTS} attempts`)
1610+
log.info('Switching to interactive mode for manual assistance')
1611+
1612+
const interactivePrompt = `The command "${check.cmd} ${check.args.join(' ')}" is still failing after ${MAX_AUTO_FIX_ATTEMPTS} automatic fix attempts.
1613+
1614+
Latest error output:
1615+
${retryResult.stderr || retryResult.stdout || 'No error output'}
1616+
1617+
Previous automatic fixes were attempted but did not resolve the issue. This appears to be a more complex problem that requires interactive debugging.
1618+
1619+
Please help me fix this issue. You can:
1620+
1. Analyze the error more carefully
1621+
2. Try different approaches
1622+
3. Ask me questions if needed
1623+
4. Suggest manual steps I should take
1624+
1625+
Let's work through this together to get CI passing.`
1626+
1627+
log.progress('Launching interactive Claude session')
1628+
await runCommand(claudeCmd, prepareClaudeArgs([], opts), {
1629+
input: interactivePrompt,
1630+
cwd: rootPath,
1631+
stdio: 'inherit' // Interactive mode
1632+
})
1633+
1634+
// Try once more after interactive session
1635+
log.progress(`Final retry of ${check.name}`)
1636+
const finalResult = await runCommandWithOutput(check.cmd, check.args, {
1637+
cwd: rootPath
1638+
})
1639+
1640+
if (finalResult.exitCode !== 0) {
1641+
log.error(`${check.name} still failing after manual intervention`)
1642+
log.substep('Consider running the command manually to debug further')
1643+
return false
1644+
}
1645+
} else {
1646+
log.warn(`Auto-fix attempt ${autoFixAttempts} failed, will retry`)
1647+
// Will try again on next iteration
1648+
continue
1649+
}
1650+
}
1651+
} else {
1652+
// Already exceeded auto attempts, go straight to interactive
1653+
log.warn('Maximum auto-fix attempts exceeded')
1654+
log.info('Please fix this issue interactively')
15791655
return false
15801656
}
15811657
}
@@ -1723,25 +1799,41 @@ Provide specific file edits or commands to fix this issue.`
17231799

17241800
// Analyze and fix with Claude
17251801
log.progress('Analyzing CI failure with Claude')
1726-
const fixPrompt = `The CI workflow failed for commit ${currentSha} in ${owner}/${repo}.
1802+
const fixPrompt = `You are automatically fixing CI failures. The CI workflow failed for commit ${currentSha} in ${owner}/${repo}.
17271803
17281804
Failure logs:
17291805
${logsResult.stdout || 'No logs available'}
17301806
1731-
Please analyze these CI logs and provide specific fixes for the failures. Focus on:
1732-
1. Test failures
1733-
2. Lint errors
1734-
3. Type checking issues
1735-
4. Build problems
1807+
Your task:
1808+
1. Analyze these CI logs
1809+
2. Identify the root cause of failures
1810+
3. Apply fixes directly to resolve the issues
17361811
1737-
Provide exact file changes needed to fix these issues.`
1812+
Focus on:
1813+
- Test failures: Update snapshots, fix test logic, or correct test data
1814+
- Lint errors: Fix code style and formatting issues
1815+
- Type checking: Fix type errors and missing type annotations
1816+
- Build problems: Fix import errors, missing dependencies, or syntax issues
1817+
1818+
IMPORTANT:
1819+
- Be direct and apply fixes immediately
1820+
- Don't ask for clarification or permission
1821+
- Make all necessary file changes to fix the CI
1822+
- If multiple issues exist, fix them all
17381823
1824+
Fix all CI failures now by making the necessary changes.`
1825+
1826+
// Run Claude non-interactively to apply fixes
1827+
log.substep('Applying CI fixes...')
17391828
await runCommand(claudeCmd, prepareClaudeArgs([], opts), {
17401829
input: fixPrompt,
1741-
stdio: 'inherit',
1742-
cwd: rootPath
1830+
cwd: rootPath,
1831+
stdio: 'pipe' // Run silently
17431832
})
17441833

1834+
// Give Claude's changes a moment to complete
1835+
await new Promise(resolve => setTimeout(resolve, 3000))
1836+
17451837
// Run local checks again
17461838
log.progress('Running local checks after fixes')
17471839
for (const check of localChecks) {
@@ -1930,6 +2022,10 @@ async function main() {
19302022
type: 'string',
19312023
default: '3',
19322024
},
2025+
'max-auto-fixes': {
2026+
type: 'string',
2027+
default: '10',
2028+
},
19332029
},
19342030
allowPositionals: true,
19352031
strict: false,
@@ -1956,12 +2052,14 @@ async function main() {
19562052
console.log(' --seq Run sequentially (default: parallel)')
19572053
console.log(' --no-darkwing Disable "Let\'s get dangerous!" mode')
19582054
console.log(' --max-retries N Max CI fix attempts (--green, default: 3)')
2055+
console.log(' --max-auto-fixes N Max auto-fix attempts before interactive (--green, default: 10)')
19592056
console.log('\nExamples:')
19602057
console.log(' pnpm claude --review # Review staged changes')
19612058
console.log(' pnpm claude --fix # Scan for issues')
19622059
console.log(' pnpm claude --green # Ensure CI passes')
19632060
console.log(' pnpm claude --green --dry-run # Test green without real CI')
1964-
console.log(' pnpm claude --green --max-retries 5 # More fix attempts')
2061+
console.log(' pnpm claude --green --max-retries 5 # More CI retry attempts')
2062+
console.log(' pnpm claude --green --max-auto-fixes 3 # Fewer auto-fix attempts')
19652063
console.log(' pnpm claude --test lib/utils.js # Generate tests for a file')
19662064
console.log(' pnpm claude --explain path.join # Explain a concept')
19672065
console.log(' pnpm claude --refactor src/index.js # Suggest refactoring')

0 commit comments

Comments
 (0)