@@ -273,46 +273,139 @@ export function buildGoodFirstIssuesPrompt(
273273
274274 // Analyze codebase for potential issues
275275 const fileTypes = analyzeFileTypes ( snapshot . commits ) ;
276- // const commonAreas = analyzeCommonAreas(snapshot.commits);
276+ const fileChurn = analyzeFileChurn ( snapshot . commits ) ;
277+ const directoryActivity = analyzeDirectoryActivity ( snapshot . commits ) ;
278+
279+ // Find stable areas good for first contributions
280+ const stableAreas = Object . entries ( directoryActivity )
281+ . filter ( ( [ _ , count ] ) => count >= 2 && count <= 8 )
282+ . sort ( ( a , b ) => a [ 1 ] - b [ 1 ] )
283+ . slice ( 0 , 5 )
284+ . map ( ( [ dir ] ) => dir ) ;
277285
278- return `Analyze this repository and suggest Good First Issues.
286+ // Recent commit patterns for context
287+ const recentCommits = snapshot . commits . slice ( 0 , 30 ) ;
288+ const recentPRs = snapshot . prs . slice ( 0 , 20 ) ;
289+
290+ return `You are an expert at identifying high-quality entry points for new contributors.
291+
292+ Analyze this repository and create a STRATEGIC list of Good First Issues.
279293
280294Repository: ${ snapshot . repo . full_name }
281295Language: ${ snapshot . repo . language || 'Multiple' }
296+ Stars: ${ snapshot . repo . stargazers_count }
282297
283- Existing Good First Issues (${ existingIssues . length } ):
284- ${ existingIssues . map ( i => `- #${ i . number } : ${ i . title } (${ i . comments } comments)` ) . join ( '\n' ) }
298+ ===== EXISTING ISSUES ANALYSIS =====
285299
286- Recent Activity:
287- ${ snapshot . commits . slice ( 0 , 20 ) . map ( c => `- ${ c . message . split ( '\n' ) [ 0 ] } ` ) . join ( '\n' ) }
300+ Current Good First Issues (${ existingIssues . length } ):
301+ ${ existingIssues . length > 0
302+ ? existingIssues . map ( i => `- #${ i . number } : ${ i . title } [Labels: ${ i . labels . join ( ', ' ) } ] (${ i . comments } comments)` ) . join ( '\n' )
303+ : 'No existing good first issues found.' }
304+
305+ ===== CODEBASE ACTIVITY DATA =====
306+
307+ Recent Commits (${ recentCommits . length } ):
308+ ${ recentCommits . map ( c => `- ${ c . sha . slice ( 0 , 7 ) } : ${ c . message . split ( '\n' ) [ 0 ] } [${ c . files ?. slice ( 0 , 3 ) . join ( ', ' ) || 'no files' } ]` ) . join ( '\n' ) }
309+
310+ Recent PRs (${ recentPRs . length } ):
311+ ${ recentPRs . map ( pr => `- #${ pr . number } : ${ pr . title } by @${ pr . author } ` ) . join ( '\n' ) }
288312
289313Common File Types:
290- ${ Object . entries ( fileTypes ) . slice ( 0 , 10 ) . map ( ( [ ext , count ] ) => `- ${ ext } : ${ count } files` ) . join ( '\n' ) }
314+ ${ Object . entries ( fileTypes ) . slice ( 0 , 10 ) . map ( ( [ ext , count ] ) => `- . ${ ext } : ${ count } files changed ` ) . join ( '\n' ) }
291315
292- ${ snapshot . readme ? `README:\n${ snapshot . readme . slice ( 0 , 1000 ) } ...\n` : '' }
316+ Stable Areas (good for first PRs):
317+ ${ stableAreas . length > 0 ? stableAreas . map ( d => `- ${ d } /` ) . join ( '\n' ) : 'None identified' }
318+
319+ High-Churn Files (avoid for first PRs):
320+ ${ Object . entries ( fileChurn ) . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] ) . slice ( 0 , 5 ) . map ( ( [ file , count ] ) => `- ${ file } (${ count } changes)` ) . join ( '\n' ) }
293321
294- Create a Good First Issues list in this EXACT format:
322+ ${ snapshot . readme ? `README (for context):\n${ snapshot . readme . slice ( 0 , 1500 ) } ...\n` : '' }
323+ ${ snapshot . contributing ? `CONTRIBUTING (for context):\n${ snapshot . contributing . slice ( 0 , 800 ) } ...\n` : '' }
324+
325+ ===== GENERATE THIS EXACT FORMAT =====
295326
296327# Good First Issues
297328
298- ## Suggested Issues
329+ > **Based on recent commits and PRs, these are the safest and most impactful entry points for new contributors right now.**
330+
331+ ---
332+
333+ ## 📚 Documentation
334+ ${ tone === 'detailed' ? '[List 2-4 documentation issues]' : '[List 1-2 documentation issues]' }
335+
336+ For each:
337+ ### [Clear, actionable title]
338+ **Why this is safe:** [1 sentence - what makes it low-risk]
339+ **What to do:** [Specific action - which file to edit, what to add]
340+ **Files:** \`path/to/relevant/file.md\`
341+ **Confidence:** ⭐⭐⭐⭐⭐ (5/5) or similar
342+
343+ ---
344+
345+ ## 🧪 Testing
346+ ${ tone === 'detailed' ? '[List 2-3 testing issues]' : '[List 1-2 testing issues]' }
347+
348+ For each:
349+ ### [Clear, actionable title]
350+ **Why this is safe:** [1 sentence]
351+ **What to do:** [Specific action]
352+ **Files:** \`path/to/test/file.test.ts\`
353+ **Confidence:** ⭐⭐⭐⭐ (4/5) or similar
354+
355+ ---
356+
357+ ## 🔧 Code Improvements
358+ ${ tone === 'detailed' ? '[List 3-5 refactoring/improvement issues]' : '[List 2-3 issues]' }
359+
360+ For each:
361+ ### [Clear, actionable title]
362+ **Why this is safe:** [1 sentence - reference the stability data]
363+ **What to do:** [Specific action]
364+ **Files:** \`path/to/file.ts\`
365+ **Related:** ${ existingIssues . length > 0 ? '[Link to existing issue #X if related]' : '[Any related PRs]' }
366+ **Confidence:** ⭐⭐⭐ (3/5) or similar
367+
368+ ---
369+
370+ ## 🎨 UX/UI (if applicable)
371+ ${ tone === 'detailed' ? '[List 1-3 UX issues if this has a frontend]' : '[List 1 UX issue if applicable]' }
372+
373+ For each:
374+ ### [Clear, actionable title]
375+ **Why this is safe:** [1 sentence]
376+ **What to do:** [Specific action]
377+ **Files:** \`path/to/component.tsx\`
378+ **Confidence:** ⭐⭐⭐⭐ (4/5) or similar
379+
380+ ---
381+
382+ ## 📊 How We Generated These
383+
384+ <details>
385+ <summary>Analysis methodology (click to expand)</summary>
386+
387+ We analyzed:
388+ - ${ recentCommits . length } recent commits
389+ - ${ recentPRs . length } merged PRs
390+ - File churn patterns
391+ - Directory stability
299392
300- ${ tone === 'detailed' ? '[List 10-15 issues]' : '[List 5-8 issues] '}
393+ **Stable areas identified:** ${ stableAreas . join ( ', ' ) || 'None '}
301394
302- For each issue:
395+ **Avoided areas:** High-churn files that would require deep context
303396
304- ### [Issue Title]
305- **Why Good First Issue:** [Reasoning]
306- **Required Skills:** [e.g. JavaScript, documentation, testing]
307- **Confidence:** [0.0 to 1.0]
308- ${ existingIssues . length > 0 ? '**Related:** [Link to similar existing issue if applicable]' : '' }
397+ </details>
309398
310- ## Analysis Notes
311- [Overall assessment of good first issue opportunities]
399+ ---
312400
313- Be specific and realistic about difficulty.
314- Consider existing contributor patterns.
315- Suggest issues that actually need doing.` ;
401+ IMPORTANT RULES:
402+ 1. Every issue MUST have a specific file path - not "somewhere in the codebase"
403+ 2. Every issue MUST be actionable - a new contributor should know exactly what to do
404+ 3. Reference actual file paths from the commit data provided
405+ 4. If an existing issue is related, reference it by number: "See #123"
406+ 5. Confidence should reflect actual risk - documentation is 5/5, core logic is 2/5
407+ 6. Don't suggest issues that require understanding complex systems
408+ 7. Prefer stable areas over high-churn areas for safety` ;
316409}
317410
318411/**
0 commit comments