@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.
- package/bin/ai-changelog.js +5 -1
- package/package.json +12 -9
- package/src/application/orchestrators/changelog.orchestrator.js +16 -10
- package/src/application/services/application.service.js +36 -20
- package/src/domains/analysis/analysis.engine.js +26 -22
- package/src/domains/changelog/changelog.service.js +66 -8
- package/src/domains/git/git-manager.js +15 -7
- package/src/domains/git/git.service.js +36 -13
- package/src/infrastructure/cli/cli.controller.js +61 -42
- package/src/infrastructure/config/configuration.manager.js +6 -4
- package/src/infrastructure/interactive/interactive-workflow.service.js +119 -12
- package/src/infrastructure/mcp/mcp-server.service.js +13 -10
- package/src/infrastructure/providers/core/base-provider.js +2 -1
- package/src/infrastructure/providers/utils/model-config.js +3 -1
- package/src/infrastructure/validation/commit-message-validation.service.js +1 -1
- package/src/shared/constants/colors.js +2 -1
- package/src/shared/utils/cli-entry-utils.js +3 -1
- package/src/shared/utils/cli-ui.js +17 -14
- package/src/shared/utils/diff-processor.js +3 -13
- package/src/shared/utils/json-utils.js +6 -2
- package/src/shared/utils/utils.js +22 -10
|
@@ -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'
|
|
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) =>
|
|
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(
|
|
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(
|
|
203
|
-
EnhancedConsole.log(
|
|
205
|
+
static success(...args) {
|
|
206
|
+
EnhancedConsole.log('success', ...args)
|
|
204
207
|
}
|
|
205
208
|
|
|
206
|
-
static error(
|
|
207
|
-
EnhancedConsole.log(
|
|
209
|
+
static error(...args) {
|
|
210
|
+
EnhancedConsole.log('error', ...args)
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
static warn(
|
|
211
|
-
EnhancedConsole.log(
|
|
213
|
+
static warn(...args) {
|
|
214
|
+
EnhancedConsole.log('warning', ...args)
|
|
212
215
|
}
|
|
213
216
|
|
|
214
|
-
static info(
|
|
215
|
-
EnhancedConsole.log(
|
|
217
|
+
static info(...args) {
|
|
218
|
+
EnhancedConsole.log('info', ...args)
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
static processing(
|
|
219
|
-
EnhancedConsole.log(
|
|
221
|
+
static processing(...args) {
|
|
222
|
+
EnhancedConsole.log('processing', ...args)
|
|
220
223
|
}
|
|
221
224
|
|
|
222
|
-
static ai(
|
|
223
|
-
EnhancedConsole.log(
|
|
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(
|
|
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,
|
|
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
|
-
//
|
|
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,
|
|
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) =>
|
|
291
|
+
obj.forEach((item) => {
|
|
292
|
+
JsonUtils.extractStrings(item, strings)
|
|
293
|
+
})
|
|
292
294
|
} else if (obj && typeof obj === 'object') {
|
|
293
|
-
Object.values(obj).forEach((value) =>
|
|
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(() =>
|
|
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) =>
|
|
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
|
|
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 = []
|
|
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
|
|
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
|
}
|