@entro314labs/ai-changelog-generator 3.0.5 → 3.2.0
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/CHANGELOG.md +383 -785
- package/README.md +30 -3
- package/ai-changelog-mcp.sh +0 -0
- package/ai-changelog.sh +0 -0
- package/bin/ai-changelog-dxt.js +9 -9
- package/bin/ai-changelog-mcp.js +19 -17
- package/bin/ai-changelog.js +6 -6
- package/package.json +84 -52
- package/src/ai-changelog-generator.js +83 -81
- package/src/application/orchestrators/changelog.orchestrator.js +1040 -296
- package/src/application/services/application.service.js +145 -123
- package/src/cli.js +76 -57
- package/src/domains/ai/ai-analysis.service.js +289 -209
- package/src/domains/analysis/analysis.engine.js +253 -193
- package/src/domains/changelog/changelog.service.js +1062 -784
- package/src/domains/changelog/workspace-changelog.service.js +420 -249
- package/src/domains/git/git-repository.analyzer.js +348 -258
- package/src/domains/git/git.service.js +132 -112
- package/src/infrastructure/cli/cli.controller.js +415 -247
- package/src/infrastructure/config/configuration.manager.js +220 -190
- package/src/infrastructure/interactive/interactive-staging.service.js +332 -0
- package/src/infrastructure/interactive/interactive-workflow.service.js +200 -159
- package/src/infrastructure/mcp/mcp-server.service.js +208 -207
- package/src/infrastructure/metrics/metrics.collector.js +140 -123
- package/src/infrastructure/providers/core/base-provider.js +87 -40
- package/src/infrastructure/providers/implementations/anthropic.js +101 -99
- package/src/infrastructure/providers/implementations/azure.js +124 -101
- package/src/infrastructure/providers/implementations/bedrock.js +136 -126
- package/src/infrastructure/providers/implementations/dummy.js +23 -23
- package/src/infrastructure/providers/implementations/google.js +123 -114
- package/src/infrastructure/providers/implementations/huggingface.js +94 -87
- package/src/infrastructure/providers/implementations/lmstudio.js +75 -60
- package/src/infrastructure/providers/implementations/mock.js +69 -73
- package/src/infrastructure/providers/implementations/ollama.js +89 -66
- package/src/infrastructure/providers/implementations/openai.js +88 -89
- package/src/infrastructure/providers/implementations/vertex.js +227 -197
- package/src/infrastructure/providers/provider-management.service.js +245 -207
- package/src/infrastructure/providers/provider-manager.service.js +145 -125
- package/src/infrastructure/providers/utils/base-provider-helpers.js +308 -302
- package/src/infrastructure/providers/utils/model-config.js +220 -195
- package/src/infrastructure/providers/utils/provider-utils.js +105 -100
- package/src/infrastructure/validation/commit-message-validation.service.js +556 -0
- package/src/shared/constants/colors.js +467 -172
- package/src/shared/utils/cli-demo.js +285 -0
- package/src/shared/utils/cli-entry-utils.js +257 -249
- package/src/shared/utils/cli-ui.js +447 -0
- package/src/shared/utils/diff-processor.js +513 -0
- package/src/shared/utils/error-classes.js +125 -156
- package/src/shared/utils/json-utils.js +93 -89
- package/src/shared/utils/utils.js +1299 -775
- package/types/index.d.ts +353 -344
|
@@ -12,7 +12,7 @@ export class JsonUtils {
|
|
|
12
12
|
* @returns {string} JSON string
|
|
13
13
|
*/
|
|
14
14
|
static stringify(data, pretty = true) {
|
|
15
|
-
return JSON.stringify(data, null, pretty ? 2 : 0)
|
|
15
|
+
return JSON.stringify(data, null, pretty ? 2 : 0)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -23,10 +23,10 @@ export class JsonUtils {
|
|
|
23
23
|
*/
|
|
24
24
|
static safeParse(jsonString, fallback = null) {
|
|
25
25
|
try {
|
|
26
|
-
return JSON.parse(jsonString)
|
|
26
|
+
return JSON.parse(jsonString)
|
|
27
27
|
} catch (error) {
|
|
28
|
-
console.warn(`JSON parse error: ${error.message}`)
|
|
29
|
-
return fallback
|
|
28
|
+
console.warn(`JSON parse error: ${error.message}`)
|
|
29
|
+
return fallback
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -36,7 +36,7 @@ export class JsonUtils {
|
|
|
36
36
|
* @returns {string} Pretty-printed JSON string
|
|
37
37
|
*/
|
|
38
38
|
static stringifyForResponse(data) {
|
|
39
|
-
return JSON.stringify(data, null, 2)
|
|
39
|
+
return JSON.stringify(data, null, 2)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -45,7 +45,7 @@ export class JsonUtils {
|
|
|
45
45
|
* @returns {string} Compact JSON string
|
|
46
46
|
*/
|
|
47
47
|
static stringifyCompact(data) {
|
|
48
|
-
return JSON.stringify(data, null, 0)
|
|
48
|
+
return JSON.stringify(data, null, 0)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -55,20 +55,20 @@ export class JsonUtils {
|
|
|
55
55
|
* @returns {string} JSON string with circular references handled
|
|
56
56
|
*/
|
|
57
57
|
static safeStringify(data, pretty = true) {
|
|
58
|
-
const seen = new WeakSet()
|
|
58
|
+
const seen = new WeakSet()
|
|
59
59
|
return JSON.stringify(
|
|
60
60
|
data,
|
|
61
61
|
(_, value) => {
|
|
62
62
|
if (typeof value === 'object' && value !== null) {
|
|
63
63
|
if (seen.has(value)) {
|
|
64
|
-
return '[Circular]'
|
|
64
|
+
return '[Circular]'
|
|
65
65
|
}
|
|
66
|
-
seen.add(value)
|
|
66
|
+
seen.add(value)
|
|
67
67
|
}
|
|
68
|
-
return value
|
|
68
|
+
return value
|
|
69
69
|
},
|
|
70
70
|
pretty ? 2 : 0
|
|
71
|
-
)
|
|
71
|
+
)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/**
|
|
@@ -79,19 +79,19 @@ export class JsonUtils {
|
|
|
79
79
|
*/
|
|
80
80
|
static parseWithErrorDetails(jsonString, context = '') {
|
|
81
81
|
try {
|
|
82
|
-
const data = JSON.parse(jsonString)
|
|
83
|
-
return { success: true, data, error: null }
|
|
82
|
+
const data = JSON.parse(jsonString)
|
|
83
|
+
return { success: true, data, error: null }
|
|
84
84
|
} catch (error) {
|
|
85
|
-
const errorMsg = context
|
|
85
|
+
const errorMsg = context
|
|
86
86
|
? `JSON parse error in ${context}: ${error.message}`
|
|
87
|
-
: `JSON parse error: ${error.message}
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
success: false,
|
|
91
|
-
data: null,
|
|
87
|
+
: `JSON parse error: ${error.message}`
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
data: null,
|
|
92
92
|
error: errorMsg,
|
|
93
|
-
position:
|
|
94
|
-
}
|
|
93
|
+
position: JsonUtils.getErrorPosition(error, jsonString),
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -103,30 +103,34 @@ export class JsonUtils {
|
|
|
103
103
|
*/
|
|
104
104
|
static getErrorPosition(error, jsonString) {
|
|
105
105
|
// Try to extract position from error message
|
|
106
|
-
const positionMatch = error.message.match(/position (\d+)/)
|
|
107
|
-
const lineMatch = error.message.match(/line (\d+)/)
|
|
108
|
-
const columnMatch = error.message.match(/column (\d+)/)
|
|
109
|
-
|
|
106
|
+
const positionMatch = error.message.match(/position (\d+)/)
|
|
107
|
+
const lineMatch = error.message.match(/line (\d+)/)
|
|
108
|
+
const columnMatch = error.message.match(/column (\d+)/)
|
|
109
|
+
|
|
110
110
|
if (positionMatch) {
|
|
111
|
-
const position = parseInt(positionMatch[1])
|
|
112
|
-
const lines = jsonString.substring(0, position).split('\n')
|
|
111
|
+
const position = Number.parseInt(positionMatch[1], 10)
|
|
112
|
+
const lines = jsonString.substring(0, position).split('\n')
|
|
113
113
|
return {
|
|
114
114
|
position,
|
|
115
115
|
line: lines.length,
|
|
116
|
-
column: lines
|
|
117
|
-
context:
|
|
118
|
-
}
|
|
116
|
+
column: lines.at(-1).length + 1,
|
|
117
|
+
context: JsonUtils.getErrorContext(jsonString, position),
|
|
118
|
+
}
|
|
119
119
|
}
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
if (lineMatch && columnMatch) {
|
|
122
122
|
return {
|
|
123
|
-
line: parseInt(lineMatch[1]),
|
|
124
|
-
column: parseInt(columnMatch[1]),
|
|
125
|
-
context:
|
|
126
|
-
|
|
123
|
+
line: Number.parseInt(lineMatch[1], 10),
|
|
124
|
+
column: Number.parseInt(columnMatch[1], 10),
|
|
125
|
+
context: JsonUtils.getErrorContextByLine(
|
|
126
|
+
jsonString,
|
|
127
|
+
Number.parseInt(lineMatch[1], 10),
|
|
128
|
+
Number.parseInt(columnMatch[1], 10)
|
|
129
|
+
),
|
|
130
|
+
}
|
|
127
131
|
}
|
|
128
|
-
|
|
129
|
-
return null
|
|
132
|
+
|
|
133
|
+
return null
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/**
|
|
@@ -136,16 +140,16 @@ export class JsonUtils {
|
|
|
136
140
|
* @returns {Object} Context information
|
|
137
141
|
*/
|
|
138
142
|
static getErrorContext(jsonString, position) {
|
|
139
|
-
const start = Math.max(0, position - 50)
|
|
140
|
-
const end = Math.min(jsonString.length, position + 50)
|
|
141
|
-
const before = jsonString.substring(start, position)
|
|
142
|
-
const after = jsonString.substring(position, end)
|
|
143
|
-
|
|
143
|
+
const start = Math.max(0, position - 50)
|
|
144
|
+
const end = Math.min(jsonString.length, position + 50)
|
|
145
|
+
const before = jsonString.substring(start, position)
|
|
146
|
+
const after = jsonString.substring(position, end)
|
|
147
|
+
|
|
144
148
|
return {
|
|
145
149
|
before,
|
|
146
150
|
after,
|
|
147
|
-
marker: '>>> ERROR HERE <<<'
|
|
148
|
-
}
|
|
151
|
+
marker: '>>> ERROR HERE <<<',
|
|
152
|
+
}
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
/**
|
|
@@ -156,28 +160,28 @@ export class JsonUtils {
|
|
|
156
160
|
* @returns {Object} Context information
|
|
157
161
|
*/
|
|
158
162
|
static getErrorContextByLine(jsonString, line, column) {
|
|
159
|
-
const lines = jsonString.split('\n')
|
|
160
|
-
const errorLine = lines[line - 1] || ''
|
|
161
|
-
const contextLines = []
|
|
162
|
-
|
|
163
|
+
const lines = jsonString.split('\n')
|
|
164
|
+
const errorLine = lines[line - 1] || ''
|
|
165
|
+
const contextLines = []
|
|
166
|
+
|
|
163
167
|
// Add surrounding lines for context
|
|
164
168
|
for (let i = Math.max(0, line - 3); i < Math.min(lines.length, line + 2); i++) {
|
|
165
|
-
const lineNum = i + 1
|
|
166
|
-
const isErrorLine = lineNum === line
|
|
169
|
+
const lineNum = i + 1
|
|
170
|
+
const isErrorLine = lineNum === line
|
|
167
171
|
contextLines.push({
|
|
168
172
|
number: lineNum,
|
|
169
173
|
content: lines[i],
|
|
170
|
-
isError: isErrorLine
|
|
171
|
-
})
|
|
174
|
+
isError: isErrorLine,
|
|
175
|
+
})
|
|
172
176
|
}
|
|
173
|
-
|
|
177
|
+
|
|
174
178
|
return {
|
|
175
179
|
line,
|
|
176
180
|
column,
|
|
177
181
|
errorLine,
|
|
178
|
-
marker: ' '.repeat(column - 1)
|
|
179
|
-
contextLines
|
|
180
|
-
}
|
|
182
|
+
marker: `${' '.repeat(column - 1)}^`,
|
|
183
|
+
contextLines,
|
|
184
|
+
}
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
/**
|
|
@@ -187,10 +191,10 @@ export class JsonUtils {
|
|
|
187
191
|
*/
|
|
188
192
|
static isValidJson(jsonString) {
|
|
189
193
|
try {
|
|
190
|
-
JSON.parse(jsonString)
|
|
191
|
-
return true
|
|
194
|
+
JSON.parse(jsonString)
|
|
195
|
+
return true
|
|
192
196
|
} catch {
|
|
193
|
-
return false
|
|
197
|
+
return false
|
|
194
198
|
}
|
|
195
199
|
}
|
|
196
200
|
|
|
@@ -201,10 +205,10 @@ export class JsonUtils {
|
|
|
201
205
|
*/
|
|
202
206
|
static deepClone(obj) {
|
|
203
207
|
try {
|
|
204
|
-
return JSON.parse(JSON.stringify(obj))
|
|
208
|
+
return JSON.parse(JSON.stringify(obj))
|
|
205
209
|
} catch (error) {
|
|
206
|
-
console.warn('Deep clone failed, returning original object:', error.message)
|
|
207
|
-
return obj
|
|
210
|
+
console.warn('Deep clone failed, returning original object:', error.message)
|
|
211
|
+
return obj
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
214
|
|
|
@@ -215,19 +219,19 @@ export class JsonUtils {
|
|
|
215
219
|
* @returns {string} Formatted JSON string
|
|
216
220
|
*/
|
|
217
221
|
static formatForConsole(data, colorize = true) {
|
|
218
|
-
const jsonString =
|
|
219
|
-
|
|
222
|
+
const jsonString = JsonUtils.stringifyForResponse(data)
|
|
223
|
+
|
|
220
224
|
if (!colorize) {
|
|
221
|
-
return jsonString
|
|
225
|
+
return jsonString
|
|
222
226
|
}
|
|
223
|
-
|
|
227
|
+
|
|
224
228
|
// Simple syntax highlighting for console
|
|
225
229
|
return jsonString
|
|
226
|
-
.replace(/"([^"]+)":/g, '\x1b[36m"$1"\x1b[0m:')
|
|
230
|
+
.replace(/"([^"]+)":/g, '\x1b[36m"$1"\x1b[0m:') // Cyan for keys
|
|
227
231
|
.replace(/: "([^"]+)"/g, ': \x1b[32m"$1"\x1b[0m') // Green for string values
|
|
228
|
-
.replace(/: (\d+)/g, ': \x1b[33m$1\x1b[0m')
|
|
232
|
+
.replace(/: (\d+)/g, ': \x1b[33m$1\x1b[0m') // Yellow for numbers
|
|
229
233
|
.replace(/: (true|false)/g, ': \x1b[35m$1\x1b[0m') // Magenta for booleans
|
|
230
|
-
.replace(/: null/g, ': \x1b[90mnull\x1b[0m')
|
|
234
|
+
.replace(/: null/g, ': \x1b[90mnull\x1b[0m') // Gray for null
|
|
231
235
|
}
|
|
232
236
|
|
|
233
237
|
/**
|
|
@@ -237,10 +241,10 @@ export class JsonUtils {
|
|
|
237
241
|
*/
|
|
238
242
|
static minify(jsonString) {
|
|
239
243
|
try {
|
|
240
|
-
return JSON.stringify(JSON.parse(jsonString))
|
|
244
|
+
return JSON.stringify(JSON.parse(jsonString))
|
|
241
245
|
} catch (error) {
|
|
242
|
-
console.warn('JSON minification failed:', error.message)
|
|
243
|
-
return jsonString
|
|
246
|
+
console.warn('JSON minification failed:', error.message)
|
|
247
|
+
return jsonString
|
|
244
248
|
}
|
|
245
249
|
}
|
|
246
250
|
|
|
@@ -252,10 +256,10 @@ export class JsonUtils {
|
|
|
252
256
|
*/
|
|
253
257
|
static prettify(jsonString, indent = 2) {
|
|
254
258
|
try {
|
|
255
|
-
return JSON.stringify(JSON.parse(jsonString), null, indent)
|
|
259
|
+
return JSON.stringify(JSON.parse(jsonString), null, indent)
|
|
256
260
|
} catch (error) {
|
|
257
|
-
console.warn('JSON prettification failed:', error.message)
|
|
258
|
-
return jsonString
|
|
261
|
+
console.warn('JSON prettification failed:', error.message)
|
|
262
|
+
return jsonString
|
|
259
263
|
}
|
|
260
264
|
}
|
|
261
265
|
|
|
@@ -267,10 +271,10 @@ export class JsonUtils {
|
|
|
267
271
|
*/
|
|
268
272
|
static areEqual(obj1, obj2) {
|
|
269
273
|
try {
|
|
270
|
-
return JSON.stringify(obj1) === JSON.stringify(obj2)
|
|
274
|
+
return JSON.stringify(obj1) === JSON.stringify(obj2)
|
|
271
275
|
} catch (error) {
|
|
272
|
-
console.warn('JSON comparison failed:', error.message)
|
|
273
|
-
return false
|
|
276
|
+
console.warn('JSON comparison failed:', error.message)
|
|
277
|
+
return false
|
|
274
278
|
}
|
|
275
279
|
}
|
|
276
280
|
|
|
@@ -282,13 +286,13 @@ export class JsonUtils {
|
|
|
282
286
|
*/
|
|
283
287
|
static extractStrings(obj, strings = []) {
|
|
284
288
|
if (typeof obj === 'string') {
|
|
285
|
-
strings.push(obj)
|
|
289
|
+
strings.push(obj)
|
|
286
290
|
} else if (Array.isArray(obj)) {
|
|
287
|
-
obj.forEach(item =>
|
|
291
|
+
obj.forEach((item) => JsonUtils.extractStrings(item, strings))
|
|
288
292
|
} else if (obj && typeof obj === 'object') {
|
|
289
|
-
Object.values(obj).forEach(value =>
|
|
293
|
+
Object.values(obj).forEach((value) => JsonUtils.extractStrings(value, strings))
|
|
290
294
|
}
|
|
291
|
-
return strings
|
|
295
|
+
return strings
|
|
292
296
|
}
|
|
293
297
|
|
|
294
298
|
/**
|
|
@@ -297,22 +301,22 @@ export class JsonUtils {
|
|
|
297
301
|
* @returns {Object} Merged object
|
|
298
302
|
*/
|
|
299
303
|
static deepMerge(...objects) {
|
|
300
|
-
const result = {}
|
|
301
|
-
|
|
304
|
+
const result = {}
|
|
305
|
+
|
|
302
306
|
for (const obj of objects) {
|
|
303
307
|
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
304
308
|
for (const [key, value] of Object.entries(obj)) {
|
|
305
309
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
306
|
-
result[key] =
|
|
310
|
+
result[key] = JsonUtils.deepMerge(result[key] || {}, value)
|
|
307
311
|
} else {
|
|
308
|
-
result[key] = value
|
|
312
|
+
result[key] = value
|
|
309
313
|
}
|
|
310
314
|
}
|
|
311
315
|
}
|
|
312
316
|
}
|
|
313
|
-
|
|
314
|
-
return result
|
|
317
|
+
|
|
318
|
+
return result
|
|
315
319
|
}
|
|
316
320
|
}
|
|
317
321
|
|
|
318
|
-
export default JsonUtils
|
|
322
|
+
export default JsonUtils
|