@m3hti/commit-genie 3.1.0 → 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.
Files changed (56) hide show
  1. package/dist/commands/generate.d.ts.map +1 -1
  2. package/dist/commands/generate.js +10 -0
  3. package/dist/commands/generate.js.map +1 -1
  4. package/dist/commands/generate.test.js +38 -0
  5. package/dist/commands/generate.test.js.map +1 -1
  6. package/dist/services/analyzerService.d.ts +0 -157
  7. package/dist/services/analyzerService.d.ts.map +1 -1
  8. package/dist/services/analyzerService.js +75 -2010
  9. package/dist/services/analyzerService.js.map +1 -1
  10. package/dist/services/analyzerService.test.js +66 -4
  11. package/dist/services/analyzerService.test.js.map +1 -1
  12. package/dist/services/breakingChangeDetector.d.ts +9 -0
  13. package/dist/services/breakingChangeDetector.d.ts.map +1 -0
  14. package/dist/services/breakingChangeDetector.js +76 -0
  15. package/dist/services/breakingChangeDetector.js.map +1 -0
  16. package/dist/services/commitTypeDetector.d.ts +39 -0
  17. package/dist/services/commitTypeDetector.d.ts.map +1 -0
  18. package/dist/services/commitTypeDetector.js +510 -0
  19. package/dist/services/commitTypeDetector.js.map +1 -0
  20. package/dist/services/descriptionGenerator.d.ts +58 -0
  21. package/dist/services/descriptionGenerator.d.ts.map +1 -0
  22. package/dist/services/descriptionGenerator.js +566 -0
  23. package/dist/services/descriptionGenerator.js.map +1 -0
  24. package/dist/services/gitService.test.js +242 -24
  25. package/dist/services/gitService.test.js.map +1 -1
  26. package/dist/services/hookService.test.d.ts +2 -0
  27. package/dist/services/hookService.test.d.ts.map +1 -0
  28. package/dist/services/hookService.test.js +182 -0
  29. package/dist/services/hookService.test.js.map +1 -0
  30. package/dist/services/lintService.test.d.ts +2 -0
  31. package/dist/services/lintService.test.d.ts.map +1 -0
  32. package/dist/services/lintService.test.js +288 -0
  33. package/dist/services/lintService.test.js.map +1 -0
  34. package/dist/services/messageBuilder.d.ts +16 -0
  35. package/dist/services/messageBuilder.d.ts.map +1 -0
  36. package/dist/services/messageBuilder.js +135 -0
  37. package/dist/services/messageBuilder.js.map +1 -0
  38. package/dist/services/scopeDetector.d.ts +6 -0
  39. package/dist/services/scopeDetector.d.ts.map +1 -0
  40. package/dist/services/scopeDetector.js +51 -0
  41. package/dist/services/scopeDetector.js.map +1 -0
  42. package/dist/services/semanticAnalyzer.d.ts +25 -0
  43. package/dist/services/semanticAnalyzer.d.ts.map +1 -0
  44. package/dist/services/semanticAnalyzer.js +713 -0
  45. package/dist/services/semanticAnalyzer.js.map +1 -0
  46. package/dist/services/splitService.test.d.ts +2 -0
  47. package/dist/services/splitService.test.d.ts.map +1 -0
  48. package/dist/services/splitService.test.js +190 -0
  49. package/dist/services/splitService.test.js.map +1 -0
  50. package/dist/services/statsService.test.d.ts +2 -0
  51. package/dist/services/statsService.test.d.ts.map +1 -0
  52. package/dist/services/statsService.test.js +211 -0
  53. package/dist/services/statsService.test.js.map +1 -0
  54. package/dist/types/index.d.ts +5 -0
  55. package/dist/types/index.d.ts.map +1 -1
  56. package/package.json +1 -1
@@ -0,0 +1,39 @@
1
+ import { ChangeAnalysis, CommitType, ExportDiff } from '../types';
2
+ /**
3
+ * Determine the commit type based on analysis
4
+ */
5
+ export declare function determineCommitType(filesAffected: ChangeAnalysis['filesAffected'], diff: string, stagedFiles: any[], exportDiff: ExportDiff): CommitType;
6
+ /**
7
+ * Determine commit type based ONLY on file type distribution.
8
+ * Returns null if file types are mixed or include source files.
9
+ * Used when AST handles source files and we need to check if
10
+ * non-parseable files alone would determine the type.
11
+ */
12
+ export declare function determineCommitTypeFileOnly(filesAffected: ChangeAnalysis['filesAffected']): CommitType | null;
13
+ /**
14
+ * Check if diff contains actual logic changes (not just formatting)
15
+ */
16
+ export declare function hasLogicChanges(diff: string): boolean;
17
+ /**
18
+ * Check if the diff contains ONLY formatting changes (no logic impact).
19
+ * Formatting changes include: semicolons, blank lines, indentation, trailing commas, braces.
20
+ * Per Conventional Commits, these should be classified as "style".
21
+ */
22
+ export declare function isFormattingOnlyChange(diff: string): boolean;
23
+ /**
24
+ * Check if the changes are ONLY non-style JavaScript changes
25
+ * (console.log, debug statements, test prints, comments, etc.)
26
+ * Returns true if JS files have changes but NO actual styling changes
27
+ */
28
+ export declare function hasOnlyNonStyleJsChanges(diff: string, filePaths: string[]): boolean;
29
+ /**
30
+ * Extract non-comment changed lines from a diff for keyword analysis.
31
+ * Filters out comment lines to prevent false positives from descriptive text.
32
+ */
33
+ export declare function extractNonCommentChanges(diff: string): string;
34
+ /**
35
+ * Check if the diff contains only comment changes (documentation)
36
+ * Returns true if ALL changes are comments (no code changes)
37
+ */
38
+ export declare function isCommentOnlyChange(diff: string): boolean;
39
+ //# sourceMappingURL=commitTypeDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitTypeDetector.d.ts","sourceRoot":"","sources":["../../src/services/commitTypeDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGlE;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,cAAc,CAAC,eAAe,CAAC,EAC9C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,GAAG,EAAE,EAClB,UAAU,EAAE,UAAU,GACrB,UAAU,CAwTZ;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,cAAc,CAAC,eAAe,CAAC,GAC7C,UAAU,GAAG,IAAI,CAYnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA0BrD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA4D5D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAgEnF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoC7D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA6CzD"}
@@ -0,0 +1,510 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.determineCommitType = determineCommitType;
4
+ exports.determineCommitTypeFileOnly = determineCommitTypeFileOnly;
5
+ exports.hasLogicChanges = hasLogicChanges;
6
+ exports.isFormattingOnlyChange = isFormattingOnlyChange;
7
+ exports.hasOnlyNonStyleJsChanges = hasOnlyNonStyleJsChanges;
8
+ exports.extractNonCommentChanges = extractNonCommentChanges;
9
+ exports.isCommentOnlyChange = isCommentOnlyChange;
10
+ /**
11
+ * Determine the commit type based on analysis
12
+ */
13
+ function determineCommitType(filesAffected, diff, stagedFiles, exportDiff) {
14
+ const diffLower = diff.toLowerCase();
15
+ const cleanedDiff = extractNonCommentChanges(diff);
16
+ const cleanedDiffLower = cleanedDiff.toLowerCase();
17
+ const filePaths = stagedFiles.map((f) => f.path.toLowerCase());
18
+ // === FILE TYPE BASED DETECTION (highest priority) ===
19
+ // If only test files changed
20
+ if (filesAffected.test > 0 &&
21
+ filesAffected.source === 0 &&
22
+ filesAffected.docs === 0) {
23
+ return 'test';
24
+ }
25
+ // If only docs changed
26
+ if (filesAffected.docs > 0 &&
27
+ filesAffected.source === 0 &&
28
+ filesAffected.test === 0) {
29
+ return 'docs';
30
+ }
31
+ // If only config files changed
32
+ if (filesAffected.config > 0 &&
33
+ filesAffected.source === 0 &&
34
+ filesAffected.test === 0 &&
35
+ filesAffected.docs === 0) {
36
+ return 'chore';
37
+ }
38
+ // === DOCS DETECTION (comment-only changes) ===
39
+ // Check if the changes are only adding/modifying comments (documentation)
40
+ if (isCommentOnlyChange(diff)) {
41
+ return 'docs';
42
+ }
43
+ // === FORMATTING-ONLY DETECTION (code style, not CSS) ===
44
+ // Per Conventional Commits: "style" = changes that do not affect the meaning of the code
45
+ // (white-space, formatting, missing semi-colons, etc.)
46
+ if (isFormattingOnlyChange(diff)) {
47
+ return 'style';
48
+ }
49
+ // === STYLE DETECTION (CSS/UI) ===
50
+ // CSS/UI styling changes also classify as "style"
51
+ // Check for CSS/styling file extensions
52
+ const isStyleFile = filePaths.some(p => p.endsWith('.css') ||
53
+ p.endsWith('.scss') ||
54
+ p.endsWith('.sass') ||
55
+ p.endsWith('.less') ||
56
+ p.endsWith('.styl') ||
57
+ p.endsWith('.stylus') ||
58
+ p.includes('.styles.') ||
59
+ p.includes('.style.') ||
60
+ p.includes('styles/') ||
61
+ p.includes('/theme') ||
62
+ p.includes('theme.') ||
63
+ p.includes('.theme.'));
64
+ // Check for styled-components, Tailwind, or inline style changes in diff content
65
+ const hasStyledComponentChanges = /^\+.*\bstyled\s*[.(]/m.test(diff) ||
66
+ /^\+.*\bcss\s*`/m.test(diff) ||
67
+ /^\+.*\@emotion\/styled/m.test(diff);
68
+ const hasTailwindChanges = /^\+.*\bclassName\s*=.*\b(flex|grid|bg-|text-|p-|m-|w-|h-|rounded|border|shadow|hover:|focus:|sm:|md:|lg:|xl:)/m.test(diff);
69
+ const hasInlineStyleChanges = /^\+.*\bstyle\s*=\s*\{\{/m.test(diff);
70
+ const hasThemeChanges = /^\+.*(theme\s*[:=]|colors\s*[:=]|palette\s*[:=]|spacing\s*[:=]|typography\s*[:=])/m.test(diff);
71
+ const hasSxPropChanges = /^\+.*\bsx\s*=\s*\{/m.test(diff);
72
+ // Only classify as "style" if it's a CSS file OR contains actual CSS/styling code
73
+ const hasActualStyleChanges = isStyleFile || hasStyledComponentChanges ||
74
+ hasTailwindChanges || hasInlineStyleChanges ||
75
+ hasThemeChanges || hasSxPropChanges;
76
+ // NEVER classify as style if it's just JS without CSS
77
+ // This prevents console.log, debug statements, comments, test prints from being labeled as style
78
+ if (hasActualStyleChanges && !hasOnlyNonStyleJsChanges(diff, filePaths)) {
79
+ return 'style';
80
+ }
81
+ // === PERFORMANCE DETECTION ===
82
+ const perfPatterns = [
83
+ /\bperformance\b/i,
84
+ /\boptimiz(e|ation|ing)\b/i,
85
+ /\bfaster\b/i,
86
+ /\bspeed\s*(up|improvement)\b/i,
87
+ /\bcach(e|ing)\b/i,
88
+ /\bmemoiz(e|ation)\b/i,
89
+ /\blazy\s*load/i,
90
+ /\basync\b.*\bawait\b/i,
91
+ /\bparallel\b/i,
92
+ /\bbatch(ing)?\b/i,
93
+ ];
94
+ if (perfPatterns.some(p => p.test(cleanedDiffLower))) {
95
+ return 'perf';
96
+ }
97
+ // === DETECT NEW FUNCTIONALITY FIRST ===
98
+ // This must come BEFORE fix detection to avoid false positives when new functions contain validation
99
+ const hasNewFiles = stagedFiles.some((f) => f.status === 'A');
100
+ // Comprehensive new code detection
101
+ const hasNewExports = /^\+\s*export\s+(function|class|const|let|var|interface|type|default)/m.test(diff);
102
+ const hasNewFunctions = /^\+\s*(async\s+)?function\s+\w+/m.test(diff);
103
+ const hasNewArrowFunctions = /^\+\s*(export\s+)?(const|let|var)\s+\w+\s*=\s*(async\s+)?\([^)]*\)\s*=>/m.test(diff);
104
+ const hasNewClasses = /^\+\s*(export\s+)?(class|abstract\s+class)\s+\w+/m.test(diff);
105
+ // Detect new class/object methods - exclude control flow keywords (if, for, while, etc.)
106
+ // which share the `keyword(...) {` shape but are NOT method declarations
107
+ const hasNewMethods = /^\+\s+(async\s+)?(?!if|else|for|while|do|switch|catch|return|throw|new|typeof|instanceof|delete|void|yield|await\b)\w+\s*\([^)]*\)\s*{/m.test(diff);
108
+ const hasNewInterfaces = /^\+\s*(export\s+)?(interface|type)\s+\w+/m.test(diff);
109
+ const hasNewComponents = /^\+\s*(export\s+)?(const|function)\s+[A-Z]\w+/m.test(diff); // React components start with capital
110
+ const hasNewImports = /^\+\s*import\s+/m.test(diff);
111
+ // Count significant additions vs removals
112
+ const addedLines = (diff.match(/^\+[^+]/gm) || []).length;
113
+ const removedLines = (diff.match(/^-[^-]/gm) || []).length;
114
+ const netNewLines = addedLines - removedLines;
115
+ // Detect if we're adding new functionality
116
+ const hasNewFunctionality = hasNewExports || hasNewFunctions || hasNewArrowFunctions ||
117
+ hasNewClasses || hasNewMethods || hasNewInterfaces || hasNewComponents;
118
+ // === FEAT DETECTION (export-aware, AST-based) - CHECK BEFORE FIX ===
119
+ // Only treat as feat when the PUBLIC export surface grows
120
+ const removedExportNames = new Set(exportDiff.removed.map(e => e.name));
121
+ const hasNewExportedSymbols = exportDiff.added.some(e => !removedExportNames.has(e.name));
122
+ const hasAnyExportChanges = exportDiff.added.length > 0 || exportDiff.removed.length > 0;
123
+ if (hasNewFiles) {
124
+ return 'feat';
125
+ }
126
+ // New EXPORTED symbols = feat (public API surface grows)
127
+ if (hasNewExportedSymbols) {
128
+ return 'feat';
129
+ }
130
+ // New functions/classes that are NOT exported: internal refactoring
131
+ if (hasNewFunctionality && !hasNewExportedSymbols && !hasAnyExportChanges) {
132
+ // Balanced add/remove ratio indicates extraction/reorganization → refactor
133
+ if (addedLines > 0 && removedLines > 0) {
134
+ const ratio = Math.min(addedLines, removedLines) / Math.max(addedLines, removedLines);
135
+ if (ratio > 0.3) {
136
+ return 'refactor';
137
+ }
138
+ }
139
+ // Heavily additive internal code falls through to feat patterns / fallback below
140
+ }
141
+ // Significant net additions with new imports often means new feature
142
+ if (hasNewImports && netNewLines > 5) {
143
+ return 'feat';
144
+ }
145
+ // Check for new feature indicators in comments/strings
146
+ const featPatterns = [
147
+ /\badd(s|ed|ing)?\s+(new\s+)?(feature|support|ability|option|functionality)/i,
148
+ /\bimplement(s|ed|ing)?\s+\w+/i,
149
+ /\bintroduc(e|es|ed|ing)\s+(new\s+)?\w+/i,
150
+ /\benable(s|d|ing)?\s+(new\s+)?\w+/i,
151
+ /\bnew\s+(feature|function|method|api|endpoint)/i,
152
+ ];
153
+ if (featPatterns.some(p => p.test(cleanedDiff))) {
154
+ return 'feat';
155
+ }
156
+ // === FIX DETECTION ===
157
+ // Only check for validation patterns AFTER confirming no new functions/classes were added
158
+ // Check if this is adding validation/guards to existing code (defensive coding = fix)
159
+ const hasOnlyModifications = stagedFiles.every((f) => f.status === 'M');
160
+ const validationPatterns = [
161
+ /^\+.*\btypeof\s+\w+\s*===?\s*['"`]\w+['"`]/m, // typeof checks
162
+ /^\+.*\binstanceof\s+\w+/m, // instanceof checks
163
+ /^\+.*\bArray\.isArray\s*\(/m, // Array.isArray checks
164
+ /^\+.*\b(Number|String|Boolean)\.is\w+\s*\(/m, // Number.isNaN, etc.
165
+ /^\+.*\bif\s*\(\s*typeof\b/m, // if (typeof ...
166
+ /^\+.*\bif\s*\(\s*!\w+\s*\)/m, // if (!var) guards
167
+ /^\+.*\bif\s*\(\s*\w+\s*(===?|!==?)\s*(null|undefined)\s*\)/m, // null/undefined checks
168
+ /^\+.*\bif\s*\(\s*(null|undefined)\s*(===?|!==?)\s*\w+\s*\)/m, // null/undefined checks (reversed)
169
+ /^\+.*\bif\s*\(\s*[\w.\[\]]+\s*[<>]=?\s*-?\d/m, // numeric boundary checks: if (n < 0), if (arr[i] <= 0)
170
+ /^\+.*\bif\s*\(\s*-?\d+\s*[<>]=?\s*[\w.\[\]]+/m, // numeric boundary checks (reversed): if (0 > n)
171
+ /^\+.*\?\?/m, // Nullish coalescing
172
+ /^\+.*\?\./m, // Optional chaining
173
+ /^\+.*\|\|/m, // Default value patterns (when combined with guards)
174
+ ];
175
+ // Check if this is a simplification refactor (using modern syntax to replace verbose code)
176
+ // When deletions > additions significantly, it's likely simplifying existing code, not adding new checks
177
+ const isSimplificationRefactor = removedLines > addedLines &&
178
+ (removedLines - addedLines) >= 3 && // At least 3 net lines removed (significant simplification)
179
+ (/^\+.*\?\./m.test(diff) || // Using optional chaining
180
+ /^\+.*\?\?/m.test(diff) // Using nullish coalescing
181
+ ) &&
182
+ (/^-.*\bif\s*\(/m.test(diff) // Removing if statements
183
+ );
184
+ // If it's a simplification (replacing verbose ifs with optional chaining), it's refactor
185
+ if (isSimplificationRefactor) {
186
+ return 'refactor';
187
+ }
188
+ // If only modifying files (no new functions detected) and adding validation patterns, it's likely a fix
189
+ if (hasOnlyModifications && validationPatterns.some(p => p.test(diff))) {
190
+ return 'fix';
191
+ }
192
+ const fixPatterns = [
193
+ /\bfix(es|ed|ing)?\s*(the\s*)?(bug|issue|error|problem|crash)/i,
194
+ /\bfix(es|ed|ing)?\b/i, // Simple "fix" or "fixed" alone
195
+ /\bbug\s*fix/i,
196
+ /\bBUG:/i, // Bug comment markers
197
+ /\bhotfix\b/i,
198
+ /\bpatch(es|ed|ing)?\b/i,
199
+ /\bresolv(e|es|ed|ing)\s*(the\s*)?(issue|bug|error)/i,
200
+ /\bcorrect(s|ed|ing)?\s*(the\s*)?(bug|issue|error|problem)/i,
201
+ /\brepair(s|ed|ing)?\b/i,
202
+ /\bhandle\s*(error|exception|null|undefined)/i,
203
+ /\bnull\s*check/i,
204
+ /\bundefined\s*check/i,
205
+ /\btry\s*{\s*.*\s*}\s*catch/i,
206
+ /\bif\s*\(\s*!\s*\w+\s*\)/, // Null/undefined guards
207
+ /\bwas\s*broken\b/i, // "was broken" indicates fixing
208
+ /\bbroken\b.*\bfix/i, // broken...fix pattern
209
+ ];
210
+ if (fixPatterns.some(p => p.test(cleanedDiff))) {
211
+ return 'fix';
212
+ }
213
+ // === REFACTOR DETECTION ===
214
+ const refactorPatterns = [
215
+ /\brefactor(s|ed|ing)?\b/i,
216
+ /\brestructur(e|es|ed|ing)\b/i,
217
+ /\bclean\s*up\b/i,
218
+ /\bsimplif(y|ies|ied|ying)\b/i,
219
+ /\brenam(e|es|ed|ing)\b/i,
220
+ /\bmov(e|es|ed|ing)\s*(to|from|into)\b/i,
221
+ /\bextract(s|ed|ing)?\s*(function|method|class|component)/i,
222
+ /\binline(s|d|ing)?\b/i,
223
+ /\bdedup(licate)?\b/i,
224
+ /\bDRY\b/,
225
+ /\breorganiz(e|es|ed|ing)\b/i,
226
+ ];
227
+ if (refactorPatterns.some(p => p.test(cleanedDiff))) {
228
+ return 'refactor';
229
+ }
230
+ // If modifications with balanced adds/removes and no new functionality, likely refactor
231
+ // UNLESS the change modifies conditional logic (if/while/for/switch conditions),
232
+ // which typically alters behavior and should be treated as a fix, not a refactor
233
+ if (hasOnlyModifications && !hasNewFunctionality) {
234
+ // Check if the diff modifies conditions inside control flow statements.
235
+ // When both the removed and added lines contain the SAME control flow keyword
236
+ // but with different conditions, it's a behavioral change (fix), not a refactor.
237
+ const removedCondition = /^-\s*(if|while|for|switch)\s*\(/m.test(diff);
238
+ const addedCondition = /^\+\s*(if|while|for|switch)\s*\(/m.test(diff);
239
+ const isConditionChange = removedCondition && addedCondition;
240
+ if (isConditionChange) {
241
+ return 'fix';
242
+ }
243
+ // If roughly equal adds and removes, it's likely refactoring
244
+ if (addedLines > 0 && removedLines > 0) {
245
+ const ratio = Math.min(addedLines, removedLines) / Math.max(addedLines, removedLines);
246
+ if (ratio > 0.5) { // More strict ratio - must be very balanced
247
+ return 'refactor';
248
+ }
249
+ }
250
+ }
251
+ // === CHORE DETECTION ===
252
+ const chorePatterns = [
253
+ /\bdependenc(y|ies)\b/i,
254
+ /\bupgrade\b/i,
255
+ /\bupdate\s*(version|dep)/i,
256
+ /\bbump\b/i,
257
+ /\bpackage\.json\b/i,
258
+ /\bpackage-lock\.json\b/i,
259
+ /\byarn\.lock\b/i,
260
+ /\b\.gitignore\b/i,
261
+ /\bci\b.*\b(config|setup)\b/i,
262
+ /\blint(er|ing)?\b/i,
263
+ ];
264
+ if (chorePatterns.some(p => p.test(cleanedDiff)) || chorePatterns.some(p => filePaths.some(f => p.test(f)))) {
265
+ return 'chore';
266
+ }
267
+ // === FALLBACK ===
268
+ // If we have more additions than removals, lean towards feat
269
+ if (filesAffected.source > 0) {
270
+ if (netNewLines > 10) {
271
+ return 'feat'; // Significant new code added
272
+ }
273
+ if (hasOnlyModifications) {
274
+ return 'refactor'; // Modifications without clear new functionality
275
+ }
276
+ return 'feat'; // Default for source changes with new files
277
+ }
278
+ return 'chore';
279
+ }
280
+ /**
281
+ * Determine commit type based ONLY on file type distribution.
282
+ * Returns null if file types are mixed or include source files.
283
+ * Used when AST handles source files and we need to check if
284
+ * non-parseable files alone would determine the type.
285
+ */
286
+ function determineCommitTypeFileOnly(filesAffected) {
287
+ if (filesAffected.test > 0 && filesAffected.source === 0 && filesAffected.docs === 0) {
288
+ return 'test';
289
+ }
290
+ if (filesAffected.docs > 0 && filesAffected.source === 0 && filesAffected.test === 0) {
291
+ return 'docs';
292
+ }
293
+ if (filesAffected.config > 0 && filesAffected.source === 0 &&
294
+ filesAffected.test === 0 && filesAffected.docs === 0) {
295
+ return 'chore';
296
+ }
297
+ return null;
298
+ }
299
+ /**
300
+ * Check if diff contains actual logic changes (not just formatting)
301
+ */
302
+ function hasLogicChanges(diff) {
303
+ // Remove formatting-only changes and check if there's real code
304
+ const lines = diff.split('\n').filter(line => (line.startsWith('+') || line.startsWith('-')) &&
305
+ !line.startsWith('+++') &&
306
+ !line.startsWith('---'));
307
+ for (const line of lines) {
308
+ const content = line.substring(1).trim();
309
+ // Skip empty lines, comments, and whitespace-only
310
+ if (content.length === 0 ||
311
+ content.startsWith('//') ||
312
+ content.startsWith('/*') ||
313
+ content.startsWith('*') ||
314
+ content === '{' ||
315
+ content === '}' ||
316
+ content === ';') {
317
+ continue;
318
+ }
319
+ // Has actual code change
320
+ return true;
321
+ }
322
+ return false;
323
+ }
324
+ /**
325
+ * Check if the diff contains ONLY formatting changes (no logic impact).
326
+ * Formatting changes include: semicolons, blank lines, indentation, trailing commas, braces.
327
+ * Per Conventional Commits, these should be classified as "style".
328
+ */
329
+ function isFormattingOnlyChange(diff) {
330
+ const lines = diff.split('\n').filter(line => (line.startsWith('+') || line.startsWith('-')) &&
331
+ !line.startsWith('+++') &&
332
+ !line.startsWith('---'));
333
+ if (lines.length === 0) {
334
+ return false;
335
+ }
336
+ // Pair up removed and added lines to detect indentation-only changes
337
+ const removed = [];
338
+ const added = [];
339
+ for (const line of lines) {
340
+ const content = line.substring(1);
341
+ const trimmed = content.trim();
342
+ // Empty / whitespace-only lines are always formatting
343
+ if (trimmed.length === 0) {
344
+ continue;
345
+ }
346
+ // Standalone semicolons, braces, trailing commas are formatting
347
+ if (trimmed === ';' || trimmed === '{' || trimmed === '}' || trimmed === ',') {
348
+ continue;
349
+ }
350
+ // Collect lines for indentation-only and semicolon-only comparison
351
+ if (line.startsWith('-')) {
352
+ removed.push(trimmed);
353
+ }
354
+ else {
355
+ added.push(trimmed);
356
+ }
357
+ }
358
+ // If no added/removed content lines remain, it's purely blank line changes
359
+ if (removed.length === 0 && added.length === 0) {
360
+ return true;
361
+ }
362
+ // Check if each added line corresponds to a removed line that differs only by
363
+ // formatting (trailing semicolons, trailing commas, whitespace)
364
+ if (removed.length !== added.length) {
365
+ return false;
366
+ }
367
+ for (let i = 0; i < removed.length; i++) {
368
+ // Normalize: strip trailing semicolons, commas, and whitespace
369
+ const normalizeFormatting = (s) => s.replace(/[;\s,]+$/g, '').replace(/^\s+/, '');
370
+ const normRemoved = normalizeFormatting(removed[i]);
371
+ const normAdded = normalizeFormatting(added[i]);
372
+ if (normRemoved !== normAdded) {
373
+ return false;
374
+ }
375
+ }
376
+ return true;
377
+ }
378
+ /**
379
+ * Check if the changes are ONLY non-style JavaScript changes
380
+ * (console.log, debug statements, test prints, comments, etc.)
381
+ * Returns true if JS files have changes but NO actual styling changes
382
+ */
383
+ function hasOnlyNonStyleJsChanges(diff, filePaths) {
384
+ // Check if all files are JavaScript/TypeScript (not CSS)
385
+ const hasOnlyJsFiles = filePaths.every(p => p.endsWith('.js') ||
386
+ p.endsWith('.jsx') ||
387
+ p.endsWith('.ts') ||
388
+ p.endsWith('.tsx') ||
389
+ p.endsWith('.mjs') ||
390
+ p.endsWith('.cjs'));
391
+ if (!hasOnlyJsFiles) {
392
+ return false;
393
+ }
394
+ // Patterns that indicate NON-style changes (debug, logging, test output)
395
+ const nonStylePatterns = [
396
+ /console\.(log|debug|info|warn|error|trace|dir|table)/,
397
+ /debugger\b/,
398
+ /logger\.\w+/i,
399
+ /debug\s*\(/,
400
+ /print\s*\(/,
401
+ /console\.assert/,
402
+ /console\.time/,
403
+ /console\.count/,
404
+ /console\.group/,
405
+ /process\.stdout/,
406
+ /process\.stderr/,
407
+ /\.toLog\(/,
408
+ /\.log\(/,
409
+ /winston\./,
410
+ /pino\./,
411
+ /bunyan\./,
412
+ /log4js\./,
413
+ ];
414
+ // Get all added/changed lines
415
+ const changedLines = diff.split('\n').filter(line => line.startsWith('+') && !line.startsWith('+++'));
416
+ // If the changes match non-style patterns, return true
417
+ const hasNonStyleChanges = changedLines.some(line => nonStylePatterns.some(pattern => pattern.test(line)));
418
+ // Check if there are NO style-related patterns in the JS files
419
+ const stylePatterns = [
420
+ /styled\s*[.(]/,
421
+ /css\s*`/,
422
+ /\bstyle\s*=\s*\{\{/,
423
+ /className\s*=/,
424
+ /\bsx\s*=/,
425
+ /theme\./,
426
+ /colors\./,
427
+ /palette\./,
428
+ ];
429
+ const hasStylePatterns = changedLines.some(line => stylePatterns.some(pattern => pattern.test(line)));
430
+ // Return true only if we have non-style changes AND no style patterns
431
+ return hasNonStyleChanges && !hasStylePatterns;
432
+ }
433
+ /**
434
+ * Extract non-comment changed lines from a diff for keyword analysis.
435
+ * Filters out comment lines to prevent false positives from descriptive text.
436
+ */
437
+ function extractNonCommentChanges(diff) {
438
+ return diff.split('\n')
439
+ .filter(line => (line.startsWith('+') || line.startsWith('-')) &&
440
+ !line.startsWith('+++') &&
441
+ !line.startsWith('---'))
442
+ .map(line => line.substring(1))
443
+ .filter(line => {
444
+ const trimmed = line.trim();
445
+ if (trimmed.length === 0)
446
+ return false;
447
+ // Filter out comment lines
448
+ if (trimmed.startsWith('//') ||
449
+ trimmed.startsWith('/*') ||
450
+ trimmed.startsWith('*') ||
451
+ trimmed.startsWith('*/') ||
452
+ trimmed.startsWith('#') ||
453
+ trimmed.startsWith('<!--') ||
454
+ trimmed.startsWith('-->') ||
455
+ trimmed.startsWith('"""') ||
456
+ trimmed.startsWith("'''") ||
457
+ /^\/\*\*/.test(trimmed) ||
458
+ /^\*\s*@\w+/.test(trimmed)) {
459
+ return false;
460
+ }
461
+ // Filter out lines that are purely string literals
462
+ if (/^(?:return\s+)?(['"`]).*\1[;,]?\s*$/.test(trimmed)) {
463
+ return false;
464
+ }
465
+ return true;
466
+ })
467
+ .join('\n');
468
+ }
469
+ /**
470
+ * Check if the diff contains only comment changes (documentation)
471
+ * Returns true if ALL changes are comments (no code changes)
472
+ */
473
+ function isCommentOnlyChange(diff) {
474
+ // Get all changed lines (additions and deletions)
475
+ const lines = diff.split('\n').filter(line => (line.startsWith('+') || line.startsWith('-')) &&
476
+ !line.startsWith('+++') &&
477
+ !line.startsWith('---'));
478
+ if (lines.length === 0) {
479
+ return false;
480
+ }
481
+ let hasCommentChanges = false;
482
+ for (const line of lines) {
483
+ const content = line.substring(1).trim();
484
+ // Skip empty lines
485
+ if (content.length === 0) {
486
+ continue;
487
+ }
488
+ // Check if line is a comment
489
+ const isComment = content.startsWith('//') || // Single-line comment
490
+ content.startsWith('/*') || // Multi-line comment start
491
+ content.startsWith('*') || // Multi-line comment body
492
+ content.startsWith('*/') || // Multi-line comment end
493
+ content.startsWith('#') || // Shell/Python/Ruby comments
494
+ content.startsWith('<!--') || // HTML comments
495
+ content.startsWith('-->') || // HTML comment end
496
+ content.startsWith('"""') || // Python docstring
497
+ content.startsWith("'''") || // Python docstring
498
+ /^\/\*\*/.test(content) || // JSDoc start
499
+ /^\*\s*@\w+/.test(content); // JSDoc tag
500
+ if (isComment) {
501
+ hasCommentChanges = true;
502
+ }
503
+ else {
504
+ // Found a non-comment change - not a comment-only diff
505
+ return false;
506
+ }
507
+ }
508
+ return hasCommentChanges;
509
+ }
510
+ //# sourceMappingURL=commitTypeDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitTypeDetector.js","sourceRoot":"","sources":["../../src/services/commitTypeDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { ASTClassifierResult, ChangeAnalysis, CommitType, FileChange, SemanticAnalysis } from '../types';
2
+ /**
3
+ * Generate a description for formatting-only changes
4
+ */
5
+ export declare function generateFormattingDescription(diff: string, stagedFiles: FileChange[]): string;
6
+ /**
7
+ * Generate a description from AST analysis results.
8
+ * Produces specific, human-readable descriptions based on structural signals.
9
+ * Returns empty string if AST data is insufficient for a good description.
10
+ */
11
+ export declare function generateASTDescription(astResult: ASTClassifierResult, commitType: CommitType): string;
12
+ /**
13
+ * Detect test+implementation file pairs.
14
+ * Returns the pair info if files match naming conventions, null otherwise.
15
+ */
16
+ export declare function detectTestImplPair(stagedFiles: {
17
+ status: string;
18
+ path: string;
19
+ }[]): {
20
+ implFile: string;
21
+ testFile: string;
22
+ implStatus: string;
23
+ testStatus: string;
24
+ } | null;
25
+ /**
26
+ * Generate description using lightweight file content analysis (JSON, CSS, YAML, MD).
27
+ * Returns null if no structural info is available.
28
+ */
29
+ export declare function generateFileContentDescription(stagedFiles: {
30
+ status: string;
31
+ path: string;
32
+ }[], diff: string): string | null;
33
+ /**
34
+ * Generate description using hunk header context (function/class names).
35
+ * Works for any language that git can identify scope for.
36
+ * Returns null if no hunk context is available.
37
+ */
38
+ export declare function generateHunkDescription(stagedFiles: {
39
+ status: string;
40
+ path: string;
41
+ }[], diff: string, commitType: CommitType): string | null;
42
+ /**
43
+ * Generate a descriptive commit message
44
+ * Uses AST analysis for specific descriptions when available,
45
+ * falls back to semantic analysis and regex-based descriptions.
46
+ */
47
+ export declare function generateDescription(filesAffected: ChangeAnalysis['filesAffected'], fileStatuses: any, stagedFiles: any[], diff: string, semanticAnalysis?: SemanticAnalysis, astResult?: ASTClassifierResult, commitType?: CommitType): string;
48
+ /**
49
+ * Generate description based on semantic analysis
50
+ * Creates intent-based messages like "update UserProfile validation logic"
51
+ */
52
+ export declare function generateSemanticDescription(semantic: SemanticAnalysis, stagedFiles: FileChange[]): string;
53
+ /**
54
+ * Generate an alternative description style
55
+ * Uses AST data when available, otherwise falls back to regex extraction.
56
+ */
57
+ export declare function generateAlternativeDescription(analysis: ChangeAnalysis, diff: string): string;
58
+ //# sourceMappingURL=descriptionGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptionGenerator.d.ts","sourceRoot":"","sources":["../../src/services/descriptionGenerator.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,UAAU,EACV,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAuF7F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,UAAU,GACrB,MAAM,CAuHR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAC9C;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqCvF;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC/C,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAkBf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC/C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAmBf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,cAAc,CAAC,eAAe,CAAC,EAC9C,YAAY,EAAE,GAAG,EACjB,WAAW,EAAE,GAAG,EAAE,EAClB,IAAI,EAAE,MAAM,EACZ,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,SAAS,CAAC,EAAE,mBAAmB,EAC/B,UAAU,CAAC,EAAE,UAAU,GACtB,MAAM,CAwHR;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,gBAAgB,EAC1B,WAAW,EAAE,UAAU,EAAE,GACxB,MAAM,CAoER;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAgG7F"}