@m3hti/commit-genie 1.0.0 → 1.1.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 (37) hide show
  1. package/README.md +164 -2
  2. package/dist/commands/generate.d.ts +2 -0
  3. package/dist/commands/generate.d.ts.map +1 -1
  4. package/dist/commands/generate.js +248 -11
  5. package/dist/commands/generate.js.map +1 -1
  6. package/dist/data/wordlist.d.ts +11 -0
  7. package/dist/data/wordlist.d.ts.map +1 -0
  8. package/dist/data/wordlist.js +170 -0
  9. package/dist/data/wordlist.js.map +1 -0
  10. package/dist/index.js +4 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/services/aiService.d.ts +4 -0
  13. package/dist/services/aiService.d.ts.map +1 -1
  14. package/dist/services/aiService.js +37 -0
  15. package/dist/services/aiService.js.map +1 -1
  16. package/dist/services/configService.d.ts.map +1 -1
  17. package/dist/services/configService.js +21 -0
  18. package/dist/services/configService.js.map +1 -1
  19. package/dist/services/gitService.d.ts +20 -0
  20. package/dist/services/gitService.d.ts.map +1 -1
  21. package/dist/services/gitService.js +86 -0
  22. package/dist/services/gitService.js.map +1 -1
  23. package/dist/services/lintService.d.ts +32 -0
  24. package/dist/services/lintService.d.ts.map +1 -0
  25. package/dist/services/lintService.js +191 -0
  26. package/dist/services/lintService.js.map +1 -0
  27. package/dist/services/spellService.d.ts +42 -0
  28. package/dist/services/spellService.d.ts.map +1 -0
  29. package/dist/services/spellService.js +175 -0
  30. package/dist/services/spellService.js.map +1 -0
  31. package/dist/services/splitService.d.ts +32 -0
  32. package/dist/services/splitService.d.ts.map +1 -0
  33. package/dist/services/splitService.js +184 -0
  34. package/dist/services/splitService.js.map +1 -0
  35. package/dist/types/index.d.ts +66 -1
  36. package/dist/types/index.d.ts.map +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LintService = void 0;
4
+ const configService_1 = require("./configService");
5
+ const VALID_TYPES = [
6
+ 'feat',
7
+ 'fix',
8
+ 'docs',
9
+ 'style',
10
+ 'refactor',
11
+ 'test',
12
+ 'chore',
13
+ 'perf',
14
+ ];
15
+ const DEFAULT_FORBIDDEN_PREFIXES = [
16
+ 'added',
17
+ 'adding',
18
+ 'fixed',
19
+ 'fixing',
20
+ 'updated',
21
+ 'updating',
22
+ 'removed',
23
+ 'removing',
24
+ 'changed',
25
+ 'changing',
26
+ 'created',
27
+ 'creating',
28
+ 'deleted',
29
+ 'deleting',
30
+ 'implemented',
31
+ 'implementing',
32
+ ];
33
+ class LintService {
34
+ /**
35
+ * Validate a commit message against all enabled rules
36
+ */
37
+ static lint(message) {
38
+ const config = configService_1.ConfigService.getConfig();
39
+ const lintConfig = config.linting;
40
+ if (lintConfig?.enabled === false) {
41
+ return { valid: true, violations: [] };
42
+ }
43
+ const violations = [];
44
+ const rules = lintConfig?.rules;
45
+ // Check subject max length
46
+ if (rules?.subjectMaxLength?.enabled !== false) {
47
+ const maxLength = rules?.subjectMaxLength?.maxLength || 72;
48
+ const violation = this.checkSubjectLength(message.full.split('\n')[0], maxLength);
49
+ if (violation)
50
+ violations.push(violation);
51
+ }
52
+ // Check type required
53
+ if (rules?.typeRequired?.enabled !== false) {
54
+ const allowedTypes = rules?.typeRequired?.allowedTypes || VALID_TYPES;
55
+ const violation = this.checkTypeRequired(message.type, allowedTypes);
56
+ if (violation)
57
+ violations.push(violation);
58
+ }
59
+ // Check scope format
60
+ if (rules?.scopeFormat?.enabled !== false && message.scope) {
61
+ const pattern = rules?.scopeFormat?.pattern || '^[a-z][a-z0-9-]*$';
62
+ const violation = this.checkScopeFormat(message.scope, pattern);
63
+ if (violation)
64
+ violations.push(violation);
65
+ }
66
+ // Check imperative mood
67
+ if (rules?.imperativeMood?.enabled !== false) {
68
+ const forbiddenPrefixes = rules?.imperativeMood?.forbiddenPrefixes || DEFAULT_FORBIDDEN_PREFIXES;
69
+ const violation = this.checkImperativeMood(message.description, forbiddenPrefixes);
70
+ if (violation)
71
+ violations.push(violation);
72
+ }
73
+ return {
74
+ valid: violations.length === 0,
75
+ violations,
76
+ };
77
+ }
78
+ /**
79
+ * Check if the subject line exceeds max length
80
+ */
81
+ static checkSubjectLength(subject, maxLength) {
82
+ if (subject.length > maxLength) {
83
+ return {
84
+ ruleId: 'subject-max-length',
85
+ ruleName: 'Subject Max Length',
86
+ message: `Subject line is ${subject.length} characters, max allowed is ${maxLength}`,
87
+ severity: 'error',
88
+ suggestion: `Shorten to ${maxLength} characters or less`,
89
+ };
90
+ }
91
+ return null;
92
+ }
93
+ /**
94
+ * Check if the commit type is valid
95
+ */
96
+ static checkTypeRequired(type, allowedTypes) {
97
+ if (!type) {
98
+ return {
99
+ ruleId: 'type-required',
100
+ ruleName: 'Type Required',
101
+ message: 'Commit message must include a type prefix',
102
+ severity: 'error',
103
+ suggestion: `Use one of: ${allowedTypes.join(', ')}`,
104
+ };
105
+ }
106
+ if (!allowedTypes.includes(type)) {
107
+ return {
108
+ ruleId: 'type-invalid',
109
+ ruleName: 'Invalid Type',
110
+ message: `Type "${type}" is not in the allowed list`,
111
+ severity: 'error',
112
+ suggestion: `Use one of: ${allowedTypes.join(', ')}`,
113
+ };
114
+ }
115
+ return null;
116
+ }
117
+ /**
118
+ * Check if the scope format is valid
119
+ */
120
+ static checkScopeFormat(scope, pattern) {
121
+ try {
122
+ const regex = new RegExp(pattern);
123
+ if (!regex.test(scope)) {
124
+ return {
125
+ ruleId: 'scope-format',
126
+ ruleName: 'Scope Format',
127
+ message: `Scope "${scope}" does not match required format`,
128
+ severity: 'warning',
129
+ suggestion: 'Use lowercase alphanumeric characters and hyphens',
130
+ };
131
+ }
132
+ }
133
+ catch {
134
+ // Invalid regex pattern, skip check
135
+ }
136
+ return null;
137
+ }
138
+ /**
139
+ * Check if the description uses imperative mood
140
+ */
141
+ static checkImperativeMood(description, forbiddenPrefixes) {
142
+ const firstWord = description.split(/\s+/)[0]?.toLowerCase();
143
+ if (firstWord && forbiddenPrefixes.includes(firstWord)) {
144
+ const imperative = this.getImperativeForm(firstWord);
145
+ return {
146
+ ruleId: 'imperative-mood',
147
+ ruleName: 'Imperative Mood',
148
+ message: `Description should use imperative mood, not "${firstWord}"`,
149
+ severity: 'warning',
150
+ suggestion: imperative ? `Use "${imperative}" instead` : 'Start with a verb in imperative form',
151
+ };
152
+ }
153
+ return null;
154
+ }
155
+ /**
156
+ * Get the imperative form of a common past tense or gerund verb
157
+ */
158
+ static getImperativeForm(word) {
159
+ const conversions = {
160
+ added: 'add',
161
+ adding: 'add',
162
+ fixed: 'fix',
163
+ fixing: 'fix',
164
+ updated: 'update',
165
+ updating: 'update',
166
+ removed: 'remove',
167
+ removing: 'remove',
168
+ changed: 'change',
169
+ changing: 'change',
170
+ created: 'create',
171
+ creating: 'create',
172
+ deleted: 'delete',
173
+ deleting: 'delete',
174
+ implemented: 'implement',
175
+ implementing: 'implement',
176
+ };
177
+ return conversions[word] || null;
178
+ }
179
+ /**
180
+ * Check if linting should block the commit
181
+ */
182
+ static shouldBlockCommit(result) {
183
+ const config = configService_1.ConfigService.getConfig();
184
+ if (config.linting?.blockOnError === false) {
185
+ return false;
186
+ }
187
+ return result.violations.some(v => v.severity === 'error');
188
+ }
189
+ }
190
+ exports.LintService = LintService;
191
+ //# sourceMappingURL=lintService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lintService.js","sourceRoot":"","sources":["../../src/services/lintService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { SpellCheckResult } from '../types';
2
+ export declare class SpellService {
3
+ private static customWords;
4
+ private static initialized;
5
+ /**
6
+ * Initialize custom dictionary from config
7
+ */
8
+ private static init;
9
+ /**
10
+ * Check a commit message description for spelling errors
11
+ */
12
+ static check(description: string): SpellCheckResult;
13
+ /**
14
+ * Extract words from text, handling camelCase and code-like tokens
15
+ */
16
+ private static extractWords;
17
+ /**
18
+ * Check if a word should be ignored based on patterns
19
+ */
20
+ private static shouldIgnore;
21
+ /**
22
+ * Check if a word is valid (in dictionary or custom words)
23
+ */
24
+ private static isValidWord;
25
+ /**
26
+ * Get spelling suggestions using Levenshtein distance
27
+ */
28
+ private static getSuggestions;
29
+ /**
30
+ * Calculate Levenshtein distance between two strings
31
+ */
32
+ private static levenshteinDistance;
33
+ /**
34
+ * Add a word to the session dictionary (not persisted)
35
+ */
36
+ static addToSessionDictionary(word: string): void;
37
+ /**
38
+ * Clear the session dictionary
39
+ */
40
+ static clearSessionDictionary(): void;
41
+ }
42
+ //# sourceMappingURL=spellService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spellService.d.ts","sourceRoot":"","sources":["../../src/services/spellService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAC;AAI7D,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,WAAW,CAA0B;IACpD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IAEnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,IAAI;IAanB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAmCnD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAmC3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAc3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAK1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAuB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAkClC;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjD;;OAEG;IACH,MAAM,CAAC,sBAAsB,IAAI,IAAI;CAItC"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpellService = void 0;
4
+ const configService_1 = require("./configService");
5
+ const wordlist_1 = require("../data/wordlist");
6
+ class SpellService {
7
+ /**
8
+ * Initialize custom dictionary from config
9
+ */
10
+ static init() {
11
+ if (this.initialized)
12
+ return;
13
+ const config = configService_1.ConfigService.getConfig();
14
+ const customDictionary = config.spellCheck?.customDictionary || [];
15
+ for (const word of customDictionary) {
16
+ this.customWords.add(word.toLowerCase());
17
+ }
18
+ this.initialized = true;
19
+ }
20
+ /**
21
+ * Check a commit message description for spelling errors
22
+ */
23
+ static check(description) {
24
+ const config = configService_1.ConfigService.getConfig();
25
+ if (config.spellCheck?.enabled === false) {
26
+ return { valid: true, errors: [] };
27
+ }
28
+ this.init();
29
+ const words = this.extractWords(description);
30
+ const errors = [];
31
+ const ignorePatterns = config.spellCheck?.ignorePatterns || [];
32
+ for (const { word, position } of words) {
33
+ // Skip if matches ignore pattern
34
+ if (this.shouldIgnore(word, ignorePatterns)) {
35
+ continue;
36
+ }
37
+ if (!this.isValidWord(word)) {
38
+ const suggestions = this.getSuggestions(word);
39
+ errors.push({
40
+ word,
41
+ suggestions,
42
+ position,
43
+ });
44
+ }
45
+ }
46
+ return {
47
+ valid: errors.length === 0,
48
+ errors,
49
+ };
50
+ }
51
+ /**
52
+ * Extract words from text, handling camelCase and code-like tokens
53
+ */
54
+ static extractWords(text) {
55
+ const results = [];
56
+ const seen = new Set();
57
+ // Split camelCase and PascalCase
58
+ const expanded = text.replace(/([a-z])([A-Z])/g, '$1 $2');
59
+ // Replace separators with spaces
60
+ const cleaned = expanded
61
+ .replace(/[_\-./\\:;,!?'"()[\]{}]/g, ' ')
62
+ .replace(/\d+/g, ' ');
63
+ // Extract words
64
+ const regex = /[a-zA-Z]+/g;
65
+ let match;
66
+ while ((match = regex.exec(cleaned)) !== null) {
67
+ const word = match[0].toLowerCase();
68
+ // Skip very short words and already seen words
69
+ if (word.length <= 2 || seen.has(word)) {
70
+ continue;
71
+ }
72
+ seen.add(word);
73
+ // Find original position in the text
74
+ const position = text.toLowerCase().indexOf(word);
75
+ results.push({ word, position: position >= 0 ? position : 0 });
76
+ }
77
+ return results;
78
+ }
79
+ /**
80
+ * Check if a word should be ignored based on patterns
81
+ */
82
+ static shouldIgnore(word, patterns) {
83
+ for (const pattern of patterns) {
84
+ try {
85
+ const regex = new RegExp(pattern, 'i');
86
+ if (regex.test(word)) {
87
+ return true;
88
+ }
89
+ }
90
+ catch {
91
+ // Invalid regex, skip
92
+ }
93
+ }
94
+ return false;
95
+ }
96
+ /**
97
+ * Check if a word is valid (in dictionary or custom words)
98
+ */
99
+ static isValidWord(word) {
100
+ const lower = word.toLowerCase();
101
+ return wordlist_1.WORDLIST.has(lower) || this.customWords.has(lower);
102
+ }
103
+ /**
104
+ * Get spelling suggestions using Levenshtein distance
105
+ */
106
+ static getSuggestions(word, maxSuggestions = 3) {
107
+ const lower = word.toLowerCase();
108
+ const suggestions = [];
109
+ // Only check words of similar length for performance
110
+ const minLen = Math.max(1, word.length - 2);
111
+ const maxLen = word.length + 2;
112
+ for (const dictWord of wordlist_1.WORDLIST) {
113
+ if (dictWord.length >= minLen && dictWord.length <= maxLen) {
114
+ const distance = this.levenshteinDistance(lower, dictWord);
115
+ if (distance <= 2 && distance > 0) {
116
+ suggestions.push({ word: dictWord, distance });
117
+ }
118
+ }
119
+ }
120
+ return suggestions
121
+ .sort((a, b) => a.distance - b.distance)
122
+ .slice(0, maxSuggestions)
123
+ .map(s => s.word);
124
+ }
125
+ /**
126
+ * Calculate Levenshtein distance between two strings
127
+ */
128
+ static levenshteinDistance(a, b) {
129
+ if (a.length === 0)
130
+ return b.length;
131
+ if (b.length === 0)
132
+ return a.length;
133
+ const matrix = [];
134
+ // Initialize first column
135
+ for (let i = 0; i <= b.length; i++) {
136
+ matrix[i] = [i];
137
+ }
138
+ // Initialize first row
139
+ for (let j = 0; j <= a.length; j++) {
140
+ matrix[0][j] = j;
141
+ }
142
+ // Fill in the rest of the matrix
143
+ for (let i = 1; i <= b.length; i++) {
144
+ for (let j = 1; j <= a.length; j++) {
145
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
146
+ matrix[i][j] = matrix[i - 1][j - 1];
147
+ }
148
+ else {
149
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
150
+ matrix[i][j - 1] + 1, // insertion
151
+ matrix[i - 1][j] + 1 // deletion
152
+ );
153
+ }
154
+ }
155
+ }
156
+ return matrix[b.length][a.length];
157
+ }
158
+ /**
159
+ * Add a word to the session dictionary (not persisted)
160
+ */
161
+ static addToSessionDictionary(word) {
162
+ this.customWords.add(word.toLowerCase());
163
+ }
164
+ /**
165
+ * Clear the session dictionary
166
+ */
167
+ static clearSessionDictionary() {
168
+ this.customWords.clear();
169
+ this.initialized = false;
170
+ }
171
+ }
172
+ exports.SpellService = SpellService;
173
+ SpellService.customWords = new Set();
174
+ SpellService.initialized = false;
175
+ //# sourceMappingURL=spellService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spellService.js","sourceRoot":"","sources":["../../src/services/spellService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { FileChange, SplitSuggestion } from '../types';
2
+ export declare class SplitService {
3
+ /**
4
+ * Analyze staged files and detect if they should be split into multiple commits
5
+ */
6
+ static analyzeSplitOpportunity(files: FileChange[], _diff: string): SplitSuggestion | null;
7
+ /**
8
+ * Group files by their detected intent (commit type + scope)
9
+ */
10
+ private static groupFilesByIntent;
11
+ /**
12
+ * Detect scope from file path based on directory structure
13
+ */
14
+ private static detectScopeFromPath;
15
+ /**
16
+ * Generate a human-readable reason for why splitting is recommended
17
+ */
18
+ private static generateSplitReason;
19
+ /**
20
+ * Generate a suggested commit message for a group of files
21
+ */
22
+ private static generateGroupMessage;
23
+ /**
24
+ * Get appropriate action verb for commit type
25
+ */
26
+ private static getActionForType;
27
+ /**
28
+ * Get the file type category for display
29
+ */
30
+ static getFileTypeLabel(filePath: string): string;
31
+ }
32
+ //# sourceMappingURL=splitService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splitService.d.ts","sourceRoot":"","sources":["../../src/services/splitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,eAAe,EAAE,MAAM,UAAU,CAAC;AAI/E,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAC5B,KAAK,EAAE,UAAU,EAAE,EACnB,KAAK,EAAE,MAAM,GACZ,eAAe,GAAG,IAAI;IAmCzB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAgDjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAgDlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAelC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAiBnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAc/B;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAUlD"}
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SplitService = void 0;
4
+ const configService_1 = require("./configService");
5
+ const filePatterns_1 = require("../utils/filePatterns");
6
+ class SplitService {
7
+ /**
8
+ * Analyze staged files and detect if they should be split into multiple commits
9
+ */
10
+ static analyzeSplitOpportunity(files, _diff) {
11
+ const config = configService_1.ConfigService.getConfig();
12
+ const splitConfig = config.splitting;
13
+ if (splitConfig?.enabled === false) {
14
+ return null;
15
+ }
16
+ const minFiles = splitConfig?.minFilesForSuggestion || 2;
17
+ // Not enough files to suggest splitting
18
+ if (files.length < minFiles) {
19
+ return null;
20
+ }
21
+ const groups = this.groupFilesByIntent(files, splitConfig);
22
+ // If only one group, no split needed
23
+ if (groups.length <= 1) {
24
+ return null;
25
+ }
26
+ // Only suggest split if each group has meaningful changes
27
+ const meaningfulGroups = groups.filter(g => g.files.length > 0);
28
+ if (meaningfulGroups.length <= 1) {
29
+ return null;
30
+ }
31
+ return {
32
+ shouldSplit: true,
33
+ reason: this.generateSplitReason(meaningfulGroups),
34
+ groups: meaningfulGroups,
35
+ };
36
+ }
37
+ /**
38
+ * Group files by their detected intent (commit type + scope)
39
+ */
40
+ static groupFilesByIntent(files, splitConfig) {
41
+ const groupByScope = splitConfig?.groupByScope !== false;
42
+ const groupByType = splitConfig?.groupByType !== false;
43
+ const groups = new Map();
44
+ for (const file of files) {
45
+ const commitType = (0, filePatterns_1.getCommitTypeForFile)(file.path);
46
+ const scope = groupByScope ? this.detectScopeFromPath(file.path) : undefined;
47
+ // Create group key based on configuration
48
+ let key;
49
+ if (groupByType && groupByScope) {
50
+ key = `${commitType}:${scope || 'default'}`;
51
+ }
52
+ else if (groupByType) {
53
+ key = commitType;
54
+ }
55
+ else if (groupByScope) {
56
+ key = scope || 'default';
57
+ }
58
+ else {
59
+ key = 'all';
60
+ }
61
+ if (!groups.has(key)) {
62
+ groups.set(key, {
63
+ type: commitType,
64
+ scope,
65
+ files: [],
66
+ suggestedMessage: '',
67
+ });
68
+ }
69
+ groups.get(key).files.push(file);
70
+ }
71
+ // Generate suggested messages for each group
72
+ for (const group of groups.values()) {
73
+ group.suggestedMessage = this.generateGroupMessage(group);
74
+ }
75
+ return Array.from(groups.values());
76
+ }
77
+ /**
78
+ * Detect scope from file path based on directory structure
79
+ */
80
+ static detectScopeFromPath(filePath) {
81
+ const parts = filePath.split(/[/\\]/);
82
+ // Look for common scope-indicating directories
83
+ const scopeIndicators = ['src', 'lib', 'packages', 'apps', 'modules'];
84
+ for (let i = 0; i < parts.length - 1; i++) {
85
+ if (scopeIndicators.includes(parts[i]) && parts[i + 1]) {
86
+ const potentialScope = parts[i + 1];
87
+ // Validate it looks like a scope (not a file)
88
+ if (!potentialScope.includes('.') && potentialScope.length <= 20) {
89
+ return potentialScope;
90
+ }
91
+ }
92
+ }
93
+ // Fallback: use first directory if it looks like a scope
94
+ if (parts.length > 1) {
95
+ const firstDir = parts[0];
96
+ const validScopes = [
97
+ 'api',
98
+ 'ui',
99
+ 'web',
100
+ 'app',
101
+ 'core',
102
+ 'common',
103
+ 'shared',
104
+ 'utils',
105
+ 'helpers',
106
+ 'services',
107
+ 'components',
108
+ 'hooks',
109
+ 'models',
110
+ 'types',
111
+ 'config',
112
+ 'scripts',
113
+ 'tools',
114
+ 'tests',
115
+ 'docs',
116
+ ];
117
+ if (validScopes.includes(firstDir.toLowerCase())) {
118
+ return firstDir.toLowerCase();
119
+ }
120
+ }
121
+ return undefined;
122
+ }
123
+ /**
124
+ * Generate a human-readable reason for why splitting is recommended
125
+ */
126
+ static generateSplitReason(groups) {
127
+ const types = [...new Set(groups.map(g => g.type))];
128
+ const scopes = [...new Set(groups.map(g => g.scope).filter(Boolean))];
129
+ if (types.length > 1) {
130
+ return `Mixed commit types detected: ${types.join(', ')}`;
131
+ }
132
+ if (scopes.length > 1) {
133
+ return `Changes span multiple modules: ${scopes.join(', ')}`;
134
+ }
135
+ return 'Changes appear to address multiple concerns';
136
+ }
137
+ /**
138
+ * Generate a suggested commit message for a group of files
139
+ */
140
+ static generateGroupMessage(group) {
141
+ const fileNames = group.files
142
+ .slice(0, 3)
143
+ .map(f => {
144
+ const parts = f.path.split(/[/\\]/);
145
+ return parts[parts.length - 1];
146
+ })
147
+ .join(', ');
148
+ const moreFiles = group.files.length > 3 ? ` +${group.files.length - 3} more` : '';
149
+ const scopePart = group.scope ? `(${group.scope})` : '';
150
+ const action = this.getActionForType(group.type);
151
+ return `${group.type}${scopePart}: ${action} ${fileNames}${moreFiles}`;
152
+ }
153
+ /**
154
+ * Get appropriate action verb for commit type
155
+ */
156
+ static getActionForType(type) {
157
+ const actions = {
158
+ feat: 'add',
159
+ fix: 'fix',
160
+ docs: 'update',
161
+ style: 'format',
162
+ refactor: 'refactor',
163
+ test: 'add tests for',
164
+ chore: 'update',
165
+ perf: 'optimize',
166
+ };
167
+ return actions[type] || 'update';
168
+ }
169
+ /**
170
+ * Get the file type category for display
171
+ */
172
+ static getFileTypeLabel(filePath) {
173
+ const type = (0, filePatterns_1.detectFileType)(filePath);
174
+ const labels = {
175
+ test: 'Test',
176
+ docs: 'Docs',
177
+ config: 'Config',
178
+ source: 'Source',
179
+ };
180
+ return labels[type] || 'Source';
181
+ }
182
+ }
183
+ exports.SplitService = SplitService;
184
+ //# sourceMappingURL=splitService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splitService.js","sourceRoot":"","sources":["../../src/services/splitService.ts"],"names":[],"mappings":"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"}