@entro314labs/ai-changelog-generator 3.7.1 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -285,6 +285,7 @@ class Colors {
285
285
  // Helper to get actual visible length of string (without ANSI codes)
286
286
  getVisibleLength(str) {
287
287
  // Remove ANSI escape sequences to get actual visible length
288
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: Needed for ANSI codes
288
289
  return str.replace(/\x1b\[[0-9;]*m/g, '').length
289
290
  }
290
291
 
@@ -616,7 +617,7 @@ class Colors {
616
617
  return ''
617
618
  }
618
619
 
619
- const { headers = Object.keys(data[0]), align = 'left', padding = 1 } = options
620
+ const { headers = Object.keys(data[0]), align = 'left' } = options
620
621
  const rows = data.map((row) => headers.map((header) => String(row[header] || '')))
621
622
 
622
623
  // Calculate column widths
@@ -29,7 +29,9 @@ export function handleCLIError(error, context = 'application', options = {}) {
29
29
  if (showTips) {
30
30
  const tips = getContextualTips(error, context)
31
31
  if (tips.length > 0) {
32
- tips.forEach((tip) => console.error(colors.infoMessage(`💡 Tip: ${tip}`)))
32
+ tips.forEach((tip) => {
33
+ console.error(colors.infoMessage(`💡 Tip: ${tip}`))
34
+ })
33
35
  }
34
36
  }
35
37
 
@@ -191,41 +191,44 @@ export class MultiProgress {
191
191
  }
192
192
  }
193
193
 
194
+ import { format } from 'node:util'
195
+
194
196
  /**
195
197
  * Enhanced console with better formatting
196
198
  */
197
199
  export class EnhancedConsole {
198
- static log(message, type = 'info') {
200
+ static log(type = 'info', ...args) {
201
+ const message = format(...args)
199
202
  console.log(colors.statusSymbol(type, message))
200
203
  }
201
204
 
202
- static success(message) {
203
- EnhancedConsole.log(message, 'success')
205
+ static success(...args) {
206
+ EnhancedConsole.log('success', ...args)
204
207
  }
205
208
 
206
- static error(message) {
207
- EnhancedConsole.log(message, 'error')
209
+ static error(...args) {
210
+ EnhancedConsole.log('error', ...args)
208
211
  }
209
212
 
210
- static warn(message) {
211
- EnhancedConsole.log(message, 'warning')
213
+ static warn(...args) {
214
+ EnhancedConsole.log('warning', ...args)
212
215
  }
213
216
 
214
- static info(message) {
215
- EnhancedConsole.log(message, 'info')
217
+ static info(...args) {
218
+ EnhancedConsole.log('info', ...args)
216
219
  }
217
220
 
218
- static processing(message) {
219
- EnhancedConsole.log(message, 'processing')
221
+ static processing(...args) {
222
+ EnhancedConsole.log('processing', ...args)
220
223
  }
221
224
 
222
- static ai(message) {
223
- EnhancedConsole.log(message, 'ai')
225
+ static ai(...args) {
226
+ EnhancedConsole.log('ai', ...args)
224
227
  }
225
228
 
226
229
  static metrics(data, title = 'Metrics') {
227
230
  if (typeof data === 'string') {
228
- EnhancedConsole.log(data, 'metrics')
231
+ EnhancedConsole.log('metrics', data)
229
232
  } else if (data && Object.keys(data).length > 0) {
230
233
  EnhancedConsole.section(title)
231
234
  console.log(colors.formatMetrics(data))
@@ -101,7 +101,7 @@ export class DiffProcessor {
101
101
  * Process a single file's diff with intelligent compression
102
102
  */
103
103
  processFileDiff(file, options = {}) {
104
- const { budget = 4000, patterns = {}, isHighPriority = false } = options // Increased from 1500
104
+ const { budget = 4000, _patterns = {}, isHighPriority = false } = options // Increased from 1500
105
105
 
106
106
  if (!file.diff || file.diff === 'No diff available') {
107
107
  return {
@@ -120,17 +120,7 @@ export class DiffProcessor {
120
120
  }
121
121
 
122
122
  // Temporarily disable bulk pattern matching to preserve more detail
123
- // TODO: Make this smarter - only apply to truly repetitive patterns
124
- // const patternMatch = this.matchesBulkPattern(file, patterns)
125
- // if (patternMatch) {
126
- // return {
127
- // ...file,
128
- // diff: `[Bulk ${patternMatch.type}]: ${patternMatch.description}`,
129
- // processed: true,
130
- // compressionApplied: true,
131
- // bulkPattern: patternMatch.type,
132
- // }
133
- // }
123
+ // Pattern matching logic removed for cleanup
134
124
 
135
125
  // Apply intelligent truncation if still too large
136
126
  if (processedDiff.length > budget) {
@@ -370,7 +360,7 @@ export class DiffProcessor {
370
360
  * Apply intelligent truncation that preserves structure
371
361
  */
372
362
  intelligentTruncation(diff, budget, options = {}) {
373
- const { preserveStructure = false, filePath = '' } = options
363
+ const { preserveStructure = false, _filePath = '' } = options
374
364
 
375
365
  if (diff.length <= budget) {
376
366
  return diff
@@ -288,9 +288,13 @@ export class JsonUtils {
288
288
  if (typeof obj === 'string') {
289
289
  strings.push(obj)
290
290
  } else if (Array.isArray(obj)) {
291
- obj.forEach((item) => JsonUtils.extractStrings(item, strings))
291
+ obj.forEach((item) => {
292
+ JsonUtils.extractStrings(item, strings)
293
+ })
292
294
  } else if (obj && typeof obj === 'object') {
293
- Object.values(obj).forEach((value) => JsonUtils.extractStrings(value, strings))
295
+ Object.values(obj).forEach((value) => {
296
+ JsonUtils.extractStrings(value, strings)
297
+ })
294
298
  }
295
299
  return strings
296
300
  }
@@ -720,7 +720,9 @@ export function throttle(func, limit) {
720
720
  if (!inThrottle) {
721
721
  func.apply(this, args)
722
722
  inThrottle = true
723
- setTimeout(() => (inThrottle = false), limit)
723
+ setTimeout(() => {
724
+ inThrottle = false
725
+ }, limit)
724
726
  }
725
727
  }
726
728
  }
@@ -814,7 +816,9 @@ export function analyzeSemanticChanges(diff, filePath) {
814
816
  const matches = [...diff.matchAll(regex)]
815
817
  if (matches.length > 0) {
816
818
  analysis.patterns.add(pattern)
817
- matches.forEach((match) => analysis.codeElements.add(match[1]))
819
+ matches.forEach((match) => {
820
+ analysis.codeElements.add(match[1])
821
+ })
818
822
  }
819
823
  })
820
824
 
@@ -1059,14 +1063,11 @@ export function buildEnhancedPrompt(commitAnalysis, analysisMode = 'standard') {
1059
1063
  const {
1060
1064
  subject,
1061
1065
  files = [],
1062
- semanticAnalysis = {},
1063
- diffStats = {},
1064
- complexity = {},
1065
- riskAssessment = {},
1066
+ // semanticAnalysis, diffStats, complexity, riskAssessment - unused
1066
1067
  } = commitAnalysis
1067
1068
 
1068
1069
  // Detect merge commits and upgrade analysis mode for better specificity
1069
- const isMergeCommit = subject && subject.toLowerCase().includes('merge')
1070
+ const isMergeCommit = subject?.toLowerCase().includes('merge')
1070
1071
  const effectiveAnalysisMode = isMergeCommit && files.length > 10 ? 'detailed' : analysisMode
1071
1072
 
1072
1073
  // Debug logging for merge commits (disabled)
@@ -1185,7 +1186,7 @@ Provide a JSON response with ONLY these fields (use definitive language - NO "li
1185
1186
  * Validate and correct AI categorization and impact assessment based on commit characteristics
1186
1187
  */
1187
1188
  export function validateCommitCategory(category, commitAnalysis) {
1188
- const { files = [], diffStats = {}, subject = '' } = commitAnalysis
1189
+ const { files = [] } = commitAnalysis
1189
1190
  const fileCount = files.length
1190
1191
  const addedFiles = files.filter((f) => f.status === 'A' || f.status === '??').length
1191
1192
  const { insertions = 0, deletions = 0 } = diffStats
@@ -1431,15 +1432,25 @@ function extractCategoryFromText(content) {
1431
1432
  *
1432
1433
  * @returns {Array} Array of change objects with status and filePath
1433
1434
  */
1434
- export function getWorkingDirectoryChanges() {
1435
+ export function getWorkingDirectoryChanges(cwd = undefined) {
1435
1436
  try {
1436
- const result = execSync('git status --porcelain', { encoding: 'utf8' })
1437
+ const execOptions = { encoding: 'utf8' }
1438
+ if (cwd) {
1439
+ execOptions.cwd = cwd
1440
+ console.log(`[getWorkingDirectoryChanges] Running in cwd: ${cwd}`)
1441
+ } else {
1442
+ console.log(`[getWorkingDirectoryChanges] Running in process.cwd(): ${process.cwd()}`)
1443
+ }
1444
+ const result = execSync('git status --porcelain', execOptions)
1445
+ console.log(`[getWorkingDirectoryChanges] Git status result length: ${result.length}`)
1437
1446
 
1438
1447
  if (!result.trim()) {
1448
+ console.log('[getWorkingDirectoryChanges] No changes detected (empty result)')
1439
1449
  return []
1440
1450
  }
1441
1451
 
1442
1452
  const lines = result.split('\n').filter((line) => line.trim())
1453
+ console.log(`[getWorkingDirectoryChanges] Found ${lines.length} changed files`)
1443
1454
 
1444
1455
  const changes = lines.map((line) => {
1445
1456
  const status = line.substring(0, 2).trim() || '??'
@@ -1621,6 +1632,7 @@ export function summarizeFileChanges(changes) {
1621
1632
  summary,
1622
1633
  categories,
1623
1634
  stats,
1635
+ totalFiles: changes.length,
1624
1636
  languages: Array.from(languages),
1625
1637
  }
1626
1638
  }