@gilbert_oliveira/commit-wizard 1.0.26 → 1.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/README.md +265 -35
- package/dist/ai-service.d.ts +36 -0
- package/dist/ai-service.js +156 -0
- package/dist/ai-service.js.map +1 -0
- package/dist/commit-splitter.d.ts +48 -0
- package/dist/commit-splitter.js +227 -0
- package/dist/commit-splitter.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +84 -0
- package/dist/config.js.map +1 -0
- package/dist/diff-processor.d.ts +39 -0
- package/dist/diff-processor.js +156 -0
- package/dist/diff-processor.js.map +1 -0
- package/dist/git-utils.d.ts +64 -0
- package/dist/git-utils.js +185 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/index.d.ts +2 -16
- package/dist/index.js +435 -204
- package/dist/index.js.map +1 -1
- package/package.json +40 -4
- package/src/index.ts +0 -279
- package/tsconfig.json +0 -24
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* Serviço para dividir commits grandes em commits menores e organizados
|
|
4
|
+
*/
|
|
5
|
+
export class CommitSplitter {
|
|
6
|
+
constructor(gitUtils, config) {
|
|
7
|
+
this.gitUtils = gitUtils;
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Analisa um arquivo e determina seu contexto/tipo
|
|
12
|
+
*/
|
|
13
|
+
analyzeFileContext(filePath, diff) {
|
|
14
|
+
const fileName = filePath.toLowerCase();
|
|
15
|
+
const diffContent = diff.toLowerCase();
|
|
16
|
+
// Testes
|
|
17
|
+
if (fileName.includes('test') || fileName.includes('spec') || fileName.includes('__tests__')) {
|
|
18
|
+
return 'test';
|
|
19
|
+
}
|
|
20
|
+
// Documentação
|
|
21
|
+
if (fileName.includes('readme') ||
|
|
22
|
+
fileName.includes('.md') ||
|
|
23
|
+
fileName.includes('docs/') ||
|
|
24
|
+
fileName.includes('changelog')) {
|
|
25
|
+
return 'docs';
|
|
26
|
+
}
|
|
27
|
+
// CI/CD
|
|
28
|
+
if (fileName.includes('.github/') ||
|
|
29
|
+
fileName.includes('ci.yml') ||
|
|
30
|
+
fileName.includes('workflow') ||
|
|
31
|
+
fileName.includes('pipeline')) {
|
|
32
|
+
return 'ci';
|
|
33
|
+
}
|
|
34
|
+
// Configuração/Build
|
|
35
|
+
if (fileName.includes('package.json') ||
|
|
36
|
+
fileName.includes('tsconfig') ||
|
|
37
|
+
fileName.includes('eslint') ||
|
|
38
|
+
fileName.includes('.config') ||
|
|
39
|
+
fileName.includes('jest.config') ||
|
|
40
|
+
fileName.includes('.gitignore')) {
|
|
41
|
+
return 'chore';
|
|
42
|
+
}
|
|
43
|
+
// Estilos (CSS, formatação)
|
|
44
|
+
if (fileName.includes('.css') ||
|
|
45
|
+
fileName.includes('.scss') ||
|
|
46
|
+
fileName.includes('style') ||
|
|
47
|
+
diffContent.includes('prettier') ||
|
|
48
|
+
diffContent.includes('format')) {
|
|
49
|
+
return 'style';
|
|
50
|
+
}
|
|
51
|
+
// Análise do conteúdo do diff
|
|
52
|
+
if (diffContent.includes('fix') ||
|
|
53
|
+
diffContent.includes('bug') ||
|
|
54
|
+
diffContent.includes('error') ||
|
|
55
|
+
diffContent.includes('throw') ||
|
|
56
|
+
diffContent.includes('catch')) {
|
|
57
|
+
return 'fix';
|
|
58
|
+
}
|
|
59
|
+
if (diffContent.includes('refactor') ||
|
|
60
|
+
diffContent.includes('rename') ||
|
|
61
|
+
diffContent.includes('move') ||
|
|
62
|
+
diffContent.includes('extract') ||
|
|
63
|
+
diffContent.includes('reorganiz')) {
|
|
64
|
+
return 'refactor';
|
|
65
|
+
}
|
|
66
|
+
// Por padrão, considera como nova funcionalidade
|
|
67
|
+
return 'feat';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Obtém emoji e prioridade para cada tipo de commit
|
|
71
|
+
*/
|
|
72
|
+
getCommitTypeInfo(type) {
|
|
73
|
+
const typeMap = {
|
|
74
|
+
fix: { emoji: '🐛', priority: 1 },
|
|
75
|
+
test: { emoji: '🧪', priority: 2 },
|
|
76
|
+
docs: { emoji: '📚', priority: 3 },
|
|
77
|
+
chore: { emoji: '🔧', priority: 4 },
|
|
78
|
+
style: { emoji: '💄', priority: 5 },
|
|
79
|
+
refactor: { emoji: '♻️', priority: 6 },
|
|
80
|
+
feat: { emoji: '✨', priority: 7 },
|
|
81
|
+
ci: { emoji: '🔄', priority: 8 },
|
|
82
|
+
};
|
|
83
|
+
return typeMap[type];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Agrupa arquivos relacionados por similaridade de caminho
|
|
87
|
+
*/
|
|
88
|
+
groupRelatedFiles(files) {
|
|
89
|
+
const groups = [];
|
|
90
|
+
const processed = new Set();
|
|
91
|
+
for (const file of files) {
|
|
92
|
+
if (processed.has(file))
|
|
93
|
+
continue;
|
|
94
|
+
const group = [file];
|
|
95
|
+
processed.add(file);
|
|
96
|
+
const fileDir = file.split('/').slice(0, -1).join('/');
|
|
97
|
+
const fileName = file.split('/').pop()?.split('.')[0] || '';
|
|
98
|
+
// Procura arquivos relacionados
|
|
99
|
+
for (const otherFile of files) {
|
|
100
|
+
if (processed.has(otherFile) || otherFile === file)
|
|
101
|
+
continue;
|
|
102
|
+
const otherDir = otherFile.split('/').slice(0, -1).join('/');
|
|
103
|
+
const otherName = otherFile.split('/').pop()?.split('.')[0] || '';
|
|
104
|
+
// Mesmo diretório ou nomes similares
|
|
105
|
+
if (fileDir === otherDir ||
|
|
106
|
+
fileName === otherName ||
|
|
107
|
+
otherName.includes(fileName) ||
|
|
108
|
+
fileName.includes(otherName)) {
|
|
109
|
+
group.push(otherFile);
|
|
110
|
+
processed.add(otherFile);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
groups.push(group);
|
|
114
|
+
}
|
|
115
|
+
return groups;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Divide o diff atual em grupos de commits organizados
|
|
119
|
+
*/
|
|
120
|
+
async analyzeAndSplit() {
|
|
121
|
+
console.log(chalk.blue('\n🔍 Analisando mudanças para dividir em commits...'));
|
|
122
|
+
const changedFiles = this.gitUtils.getChangedFiles();
|
|
123
|
+
if (changedFiles.length === 0) {
|
|
124
|
+
throw new Error('Nenhuma mudança detectada para commit');
|
|
125
|
+
}
|
|
126
|
+
console.log(chalk.gray(`📁 Arquivos alterados: ${changedFiles.length}`));
|
|
127
|
+
// Agrupa arquivos por contexto
|
|
128
|
+
const contextGroups = new Map();
|
|
129
|
+
for (const file of changedFiles) {
|
|
130
|
+
const fileDiff = this.gitUtils.getFileDiff(file);
|
|
131
|
+
const context = this.analyzeFileContext(file, fileDiff);
|
|
132
|
+
const key = context;
|
|
133
|
+
if (!contextGroups.has(key)) {
|
|
134
|
+
contextGroups.set(key, { files: [], type: context });
|
|
135
|
+
}
|
|
136
|
+
contextGroups.get(key).files.push(file);
|
|
137
|
+
}
|
|
138
|
+
// Cria grupos de commit
|
|
139
|
+
const commitGroups = [];
|
|
140
|
+
let groupId = 1;
|
|
141
|
+
for (const [, group] of contextGroups) {
|
|
142
|
+
const { emoji, priority } = this.getCommitTypeInfo(group.type);
|
|
143
|
+
// Subdivide grupos grandes por arquivos relacionados
|
|
144
|
+
const relatedGroups = this.groupRelatedFiles(group.files);
|
|
145
|
+
for (const relatedFiles of relatedGroups) {
|
|
146
|
+
const groupDiff = relatedFiles.map(file => this.gitUtils.getFileDiff(file)).join('\n\n');
|
|
147
|
+
commitGroups.push({
|
|
148
|
+
id: `group-${groupId++}`,
|
|
149
|
+
type: group.type,
|
|
150
|
+
emoji,
|
|
151
|
+
description: await this.generateGroupDescription(relatedFiles, group.type),
|
|
152
|
+
files: relatedFiles,
|
|
153
|
+
diff: groupDiff,
|
|
154
|
+
priority,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Ordena por prioridade e complexidade
|
|
159
|
+
commitGroups.sort((a, b) => {
|
|
160
|
+
if (a.priority !== b.priority)
|
|
161
|
+
return a.priority - b.priority;
|
|
162
|
+
return a.files.length - b.files.length;
|
|
163
|
+
});
|
|
164
|
+
const suggestedOrder = commitGroups.map(g => g.id);
|
|
165
|
+
return {
|
|
166
|
+
groups: commitGroups,
|
|
167
|
+
totalFiles: changedFiles.length,
|
|
168
|
+
suggestedOrder,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Gera descrição inteligente para um grupo de arquivos
|
|
173
|
+
*/
|
|
174
|
+
async generateGroupDescription(files, type) {
|
|
175
|
+
const isPortuguese = this.config.language === 'pt';
|
|
176
|
+
// Descrições padrão por tipo
|
|
177
|
+
const defaultDescriptions = {
|
|
178
|
+
feat: isPortuguese ? 'adiciona nova funcionalidade' : 'add new feature',
|
|
179
|
+
fix: isPortuguese ? 'corrige bug' : 'fix bug',
|
|
180
|
+
docs: isPortuguese ? 'atualiza documentação' : 'update documentation',
|
|
181
|
+
style: isPortuguese ? 'melhora formatação do código' : 'improve code formatting',
|
|
182
|
+
refactor: isPortuguese ? 'refatora código' : 'refactor code',
|
|
183
|
+
test: isPortuguese ? 'adiciona/atualiza testes' : 'add/update tests',
|
|
184
|
+
chore: isPortuguese ? 'atualiza configurações' : 'update configuration',
|
|
185
|
+
ci: isPortuguese ? 'atualiza CI/CD' : 'update CI/CD',
|
|
186
|
+
};
|
|
187
|
+
// Se apenas um arquivo, usa nome específico
|
|
188
|
+
if (files.length === 1) {
|
|
189
|
+
const fileName = files[0].split('/').pop() || '';
|
|
190
|
+
return isPortuguese
|
|
191
|
+
? `${defaultDescriptions[type]} em ${fileName}`
|
|
192
|
+
: `${defaultDescriptions[type]} in ${fileName}`;
|
|
193
|
+
}
|
|
194
|
+
// Se múltiplos arquivos do mesmo diretório
|
|
195
|
+
const commonDir = this.findCommonDirectory(files);
|
|
196
|
+
if (commonDir) {
|
|
197
|
+
return isPortuguese
|
|
198
|
+
? `${defaultDescriptions[type]} em ${commonDir}`
|
|
199
|
+
: `${defaultDescriptions[type]} in ${commonDir}`;
|
|
200
|
+
}
|
|
201
|
+
// Descrição genérica
|
|
202
|
+
return defaultDescriptions[type];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Encontra diretório comum de uma lista de arquivos
|
|
206
|
+
*/
|
|
207
|
+
findCommonDirectory(files) {
|
|
208
|
+
if (files.length === 0)
|
|
209
|
+
return null;
|
|
210
|
+
const dirs = files.map(f => f.split('/').slice(0, -1));
|
|
211
|
+
if (dirs.length === 1)
|
|
212
|
+
return dirs[0].join('/');
|
|
213
|
+
const commonParts = [];
|
|
214
|
+
const minLength = Math.min(...dirs.map(d => d.length));
|
|
215
|
+
for (let i = 0; i < minLength; i++) {
|
|
216
|
+
const part = dirs[0][i];
|
|
217
|
+
if (dirs.every(d => d[i] === part)) {
|
|
218
|
+
commonParts.push(part);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return commonParts.length > 0 ? commonParts.join('/') : null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=commit-splitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-splitter.js","sourceRoot":"","sources":["../src/commit-splitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAoB1B;;GAEG;AACH,MAAM,OAAO,cAAc;IAIzB,YAAY,QAAkB,EAAE,MAAc;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,QAAgB,EAAE,IAAY;QACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAEvC,SAAS;QACT,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7F,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,eAAe;QACf,IACE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3B,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;YACxB,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1B,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC9B,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,QAAQ;QACR,IACE,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC7B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3B,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC7B,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAC7B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qBAAqB;QACrB,IACE,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC;YACjC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC7B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5B,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;YAChC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAC/B,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,4BAA4B;QAC5B,IACE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzB,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1B,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1B,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;YAChC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC9B,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,8BAA8B;QAC9B,IACE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC3B,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC3B,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC7B,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC7B,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAC7B,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IACE,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;YAChC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC9B,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC5B,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC/B,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EACjC,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,iDAAiD;QACjD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,IAAyB;QACjD,MAAM,OAAO,GAAG;YACd,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YACjC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YAClC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YAClC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YACnC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YACnC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;YACtC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE;YACjC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE;SACjC,CAAC;QAEF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,KAAe;QACvC,MAAM,MAAM,GAAe,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAElC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;YACrB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAE5D,gCAAgC;YAChC,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC9B,IAAI,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,IAAI;oBAAE,SAAS;gBAE7D,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC7D,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAElE,qCAAqC;gBACrC,IACE,OAAO,KAAK,QAAQ;oBACpB,QAAQ,KAAK,SAAS;oBACtB,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAC5B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAC5B,CAAC;oBACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACtB,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,CAAC;QAE/E,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;QAErD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEzE,+BAA+B;QAC/B,MAAM,aAAa,GAAG,IAAI,GAAG,EAA0D,CAAC;QAExF,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAExD,MAAM,GAAG,GAAG,OAAO,CAAC;YACpB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,wBAAwB;QACxB,MAAM,YAAY,GAAkB,EAAE,CAAC;QACvC,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,aAAa,EAAE,CAAC;YACtC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE/D,qDAAqD;YACrD,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE1D,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAEzF,YAAY,CAAC,IAAI,CAAC;oBAChB,EAAE,EAAE,SAAS,OAAO,EAAE,EAAE;oBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,KAAK;oBACL,WAAW,EAAE,MAAM,IAAI,CAAC,wBAAwB,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC;oBAC1E,KAAK,EAAE,YAAY;oBACnB,IAAI,EAAE,SAAS;oBACf,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;gBAAE,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC9D,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAEnD,OAAO;YACL,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,YAAY,CAAC,MAAM;YAC/B,cAAc;SACf,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB,CACpC,KAAe,EACf,IAAyB;QAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC;QAEnD,6BAA6B;QAC7B,MAAM,mBAAmB,GAAG;YAC1B,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,iBAAiB;YACvE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;YAC7C,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB;YACrE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,yBAAyB;YAChF,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe;YAC5D,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,kBAAkB;YACpE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,sBAAsB;YACvE,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,cAAc;SACrD,CAAC;QAEF,4CAA4C;QAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YACjD,OAAO,YAAY;gBACjB,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE;gBAC/C,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC;QACpD,CAAC;QAED,2CAA2C;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,YAAY;gBACjB,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,SAAS,EAAE;gBAChD,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,SAAS,EAAE,CAAC;QACrD,CAAC;QAED,qBAAqB;QACrB,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,KAAe;QACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhD,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAEvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;gBACnC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,CAAC;CACF"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
model: string;
|
|
4
|
+
temperature: number;
|
|
5
|
+
maxTokens: number;
|
|
6
|
+
language: 'pt' | 'en';
|
|
7
|
+
autoCommit: boolean;
|
|
8
|
+
excludePatterns: string[];
|
|
9
|
+
includeEmoji: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Carrega a configuração mesclando defaults com arquivo de config
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfig(): Config;
|
|
15
|
+
/**
|
|
16
|
+
* Salva a configuração no arquivo local ou global
|
|
17
|
+
*/
|
|
18
|
+
export declare function saveConfig(config: Partial<Config>, global?: boolean): void;
|
|
19
|
+
/**
|
|
20
|
+
* Cria um arquivo de configuração exemplo
|
|
21
|
+
*/
|
|
22
|
+
export declare function createConfigExample(): void;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
model: 'gpt-4o',
|
|
6
|
+
temperature: 0.2,
|
|
7
|
+
maxTokens: 1000,
|
|
8
|
+
language: 'pt',
|
|
9
|
+
autoCommit: false,
|
|
10
|
+
excludePatterns: ['*.lock*', '*.log', 'node_modules/**'],
|
|
11
|
+
includeEmoji: true,
|
|
12
|
+
};
|
|
13
|
+
const CONFIG_FILE_NAME = '.commit-wizard.json';
|
|
14
|
+
/**
|
|
15
|
+
* Busca o arquivo de configuração no diretório atual ou no home do usuário
|
|
16
|
+
*/
|
|
17
|
+
function findConfigFile() {
|
|
18
|
+
// Primeiro verifica no diretório atual
|
|
19
|
+
const localConfig = path.join(process.cwd(), CONFIG_FILE_NAME);
|
|
20
|
+
if (fs.existsSync(localConfig)) {
|
|
21
|
+
return localConfig;
|
|
22
|
+
}
|
|
23
|
+
// Depois verifica no home do usuário
|
|
24
|
+
const globalConfig = path.join(os.homedir(), CONFIG_FILE_NAME);
|
|
25
|
+
if (fs.existsSync(globalConfig)) {
|
|
26
|
+
return globalConfig;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Carrega a configuração mesclando defaults com arquivo de config
|
|
32
|
+
*/
|
|
33
|
+
export function loadConfig() {
|
|
34
|
+
const configFile = findConfigFile();
|
|
35
|
+
let userConfig = {};
|
|
36
|
+
if (configFile) {
|
|
37
|
+
try {
|
|
38
|
+
const configContent = fs.readFileSync(configFile, 'utf8');
|
|
39
|
+
userConfig = JSON.parse(configContent);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.warn(`⚠️ Erro ao ler arquivo de configuração ${configFile}:`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Mescla configuração padrão com configuração do usuário
|
|
46
|
+
const config = {
|
|
47
|
+
...DEFAULT_CONFIG,
|
|
48
|
+
...userConfig,
|
|
49
|
+
apiKey: userConfig.apiKey || process.env.OPENAI_API_KEY,
|
|
50
|
+
};
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Salva a configuração no arquivo local ou global
|
|
55
|
+
*/
|
|
56
|
+
export function saveConfig(config, global = false) {
|
|
57
|
+
const configPath = global
|
|
58
|
+
? path.join(os.homedir(), CONFIG_FILE_NAME)
|
|
59
|
+
: path.join(process.cwd(), CONFIG_FILE_NAME);
|
|
60
|
+
try {
|
|
61
|
+
const existingConfig = global ? {} : loadConfig();
|
|
62
|
+
const newConfig = { ...existingConfig, ...config };
|
|
63
|
+
// Remove a apiKey do arquivo (deve ficar apenas em variável de ambiente)
|
|
64
|
+
delete newConfig.apiKey;
|
|
65
|
+
fs.writeFileSync(configPath, JSON.stringify(newConfig, null, 2));
|
|
66
|
+
console.log(`✅ Configuração salva em ${configPath}`);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('❌ Erro ao salvar configuração:', error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Cria um arquivo de configuração exemplo
|
|
74
|
+
*/
|
|
75
|
+
export function createConfigExample() {
|
|
76
|
+
const configPath = path.join(process.cwd(), `${CONFIG_FILE_NAME}.example`);
|
|
77
|
+
const exampleConfig = {
|
|
78
|
+
...DEFAULT_CONFIG,
|
|
79
|
+
apiKey: 'sk-your-openai-api-key-here',
|
|
80
|
+
};
|
|
81
|
+
fs.writeFileSync(configPath, JSON.stringify(exampleConfig, null, 2));
|
|
82
|
+
console.log(`📄 Arquivo de exemplo criado: ${configPath}`);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AIService } from './ai-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* Processador de diff para chunks e resumos
|
|
4
|
+
*/
|
|
5
|
+
export declare class DiffProcessor {
|
|
6
|
+
private aiService;
|
|
7
|
+
private maxTokens;
|
|
8
|
+
constructor(aiService: AIService, maxTokens?: number);
|
|
9
|
+
/**
|
|
10
|
+
* Divide o diff em chunks menores baseado na contagem de tokens
|
|
11
|
+
*/
|
|
12
|
+
chunkDiff(diff: string): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Processa diff grande gerando resumos dos chunks
|
|
15
|
+
*/
|
|
16
|
+
processLargeDiff(diff: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Analisa a complexidade do diff
|
|
19
|
+
*/
|
|
20
|
+
analyzeDiffComplexity(diff: string): {
|
|
21
|
+
tokenCount: number;
|
|
22
|
+
lineCount: number;
|
|
23
|
+
fileCount: number;
|
|
24
|
+
complexity: 'simple' | 'moderate' | 'complex';
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Extrai estatísticas do diff
|
|
28
|
+
*/
|
|
29
|
+
extractDiffStats(diff: string): {
|
|
30
|
+
additions: number;
|
|
31
|
+
deletions: number;
|
|
32
|
+
files: string[];
|
|
33
|
+
types: string[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Verifica se o diff contém breaking changes
|
|
37
|
+
*/
|
|
38
|
+
detectBreakingChanges(diff: string): boolean;
|
|
39
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { encode, decode } from 'gpt-tokenizer';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import cliProgress from 'cli-progress';
|
|
4
|
+
/**
|
|
5
|
+
* Processador de diff para chunks e resumos
|
|
6
|
+
*/
|
|
7
|
+
export class DiffProcessor {
|
|
8
|
+
constructor(aiService, maxTokens = 1000) {
|
|
9
|
+
this.aiService = aiService;
|
|
10
|
+
this.maxTokens = maxTokens;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Divide o diff em chunks menores baseado na contagem de tokens
|
|
14
|
+
*/
|
|
15
|
+
chunkDiff(diff) {
|
|
16
|
+
const tokens = encode(diff);
|
|
17
|
+
if (tokens.length <= this.maxTokens) {
|
|
18
|
+
return [diff];
|
|
19
|
+
}
|
|
20
|
+
const chunks = [];
|
|
21
|
+
for (let i = 0; i < tokens.length; i += this.maxTokens) {
|
|
22
|
+
const chunkTokens = tokens.slice(i, i + this.maxTokens);
|
|
23
|
+
const chunkText = decode(chunkTokens);
|
|
24
|
+
chunks.push(chunkText);
|
|
25
|
+
}
|
|
26
|
+
return chunks;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Processa diff grande gerando resumos dos chunks
|
|
30
|
+
*/
|
|
31
|
+
async processLargeDiff(diff) {
|
|
32
|
+
const chunks = this.chunkDiff(diff);
|
|
33
|
+
if (chunks.length === 1) {
|
|
34
|
+
return chunks[0];
|
|
35
|
+
}
|
|
36
|
+
const partialSummaries = [];
|
|
37
|
+
// Se há muitos chunks, usa progress bar
|
|
38
|
+
if (chunks.length > 3) {
|
|
39
|
+
console.log(`\n📊 Processando ${chunks.length} chunks do diff...\n`);
|
|
40
|
+
const progressBar = new cliProgress.SingleBar({
|
|
41
|
+
format: '🔄 Progresso |' + '{bar}' + '| {percentage}% | {value}/{total} chunks | ETA: {eta}s',
|
|
42
|
+
barCompleteChar: '█',
|
|
43
|
+
barIncompleteChar: '░',
|
|
44
|
+
hideCursor: true,
|
|
45
|
+
});
|
|
46
|
+
progressBar.start(chunks.length, 0);
|
|
47
|
+
try {
|
|
48
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
49
|
+
const summary = await this.aiService.generateSummary(chunks[i]);
|
|
50
|
+
partialSummaries.push(summary);
|
|
51
|
+
progressBar.update(i + 1);
|
|
52
|
+
}
|
|
53
|
+
progressBar.stop();
|
|
54
|
+
console.log(`✅ ${chunks.length} chunks processados com sucesso.\n`);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
progressBar.stop();
|
|
58
|
+
console.log('❌ Erro ao processar chunks do diff.\n');
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Para poucos chunks, usa spinner simples
|
|
64
|
+
const spinner = ora(`Processando ${chunks.length} chunks...`).start();
|
|
65
|
+
try {
|
|
66
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
67
|
+
spinner.text = `Processando chunk ${i + 1}/${chunks.length}...`;
|
|
68
|
+
const summary = await this.aiService.generateSummary(chunks[i]);
|
|
69
|
+
partialSummaries.push(summary);
|
|
70
|
+
}
|
|
71
|
+
spinner.succeed(`${chunks.length} chunks processados.`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
spinner.fail('Erro ao processar chunks.');
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return partialSummaries.join('\n\n');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Analisa a complexidade do diff
|
|
82
|
+
*/
|
|
83
|
+
analyzeDiffComplexity(diff) {
|
|
84
|
+
const tokens = encode(diff);
|
|
85
|
+
const lines = diff.split('\n');
|
|
86
|
+
const fileChanges = (diff.match(/^diff --git/gm) || []).length;
|
|
87
|
+
let complexity = 'simple';
|
|
88
|
+
if (tokens.length > 2000 || fileChanges > 10) {
|
|
89
|
+
complexity = 'complex';
|
|
90
|
+
}
|
|
91
|
+
else if (tokens.length > 500 || fileChanges > 3) {
|
|
92
|
+
complexity = 'moderate';
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
tokenCount: tokens.length,
|
|
96
|
+
lineCount: lines.length,
|
|
97
|
+
fileCount: fileChanges,
|
|
98
|
+
complexity,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Extrai estatísticas do diff
|
|
103
|
+
*/
|
|
104
|
+
extractDiffStats(diff) {
|
|
105
|
+
const lines = diff.split('\n');
|
|
106
|
+
let additions = 0;
|
|
107
|
+
let deletions = 0;
|
|
108
|
+
const files = [];
|
|
109
|
+
const types = new Set();
|
|
110
|
+
for (const line of lines) {
|
|
111
|
+
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
112
|
+
additions++;
|
|
113
|
+
}
|
|
114
|
+
else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
115
|
+
deletions++;
|
|
116
|
+
}
|
|
117
|
+
else if (line.startsWith('diff --git')) {
|
|
118
|
+
const match = line.match(/b\/(.+)$/);
|
|
119
|
+
if (match) {
|
|
120
|
+
const file = match[1];
|
|
121
|
+
files.push(file);
|
|
122
|
+
const ext = file.split('.').pop()?.toLowerCase();
|
|
123
|
+
if (ext) {
|
|
124
|
+
types.add(ext);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
additions,
|
|
131
|
+
deletions,
|
|
132
|
+
files,
|
|
133
|
+
types: Array.from(types),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Verifica se o diff contém breaking changes
|
|
138
|
+
*/
|
|
139
|
+
detectBreakingChanges(diff) {
|
|
140
|
+
const breakingPatterns = [
|
|
141
|
+
/class.*\{[\s\S]*?constructor.*\(/,
|
|
142
|
+
/interface.*\{[\s\S]*?\}/,
|
|
143
|
+
/export.*function.*\(/,
|
|
144
|
+
/export.*class/,
|
|
145
|
+
/export.*interface/,
|
|
146
|
+
/export.*type/,
|
|
147
|
+
/API/i,
|
|
148
|
+
/BREAKING/i,
|
|
149
|
+
/deprecated/i,
|
|
150
|
+
/remove.*function/i,
|
|
151
|
+
/delete.*method/i,
|
|
152
|
+
];
|
|
153
|
+
return breakingPatterns.some(pattern => pattern.test(diff));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=diff-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-processor.js","sourceRoot":"","sources":["../src/diff-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface GitStatus {
|
|
2
|
+
hasStagedFiles: boolean;
|
|
3
|
+
stagedFiles: string[];
|
|
4
|
+
diff: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Utilitários para operações Git
|
|
8
|
+
*/
|
|
9
|
+
export declare class GitUtils {
|
|
10
|
+
private excludePatterns;
|
|
11
|
+
constructor(excludePatterns?: string[]);
|
|
12
|
+
/**
|
|
13
|
+
* Verifica se o diretório atual é um repositório Git
|
|
14
|
+
*/
|
|
15
|
+
isGitRepository(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Constrói argumentos de exclusão para comandos git
|
|
18
|
+
*/
|
|
19
|
+
private buildExcludeArgs;
|
|
20
|
+
/**
|
|
21
|
+
* Obtém status dos arquivos staged
|
|
22
|
+
*/
|
|
23
|
+
getStagedStatus(): GitStatus;
|
|
24
|
+
/**
|
|
25
|
+
* Realiza commit com mensagem
|
|
26
|
+
*/
|
|
27
|
+
commit(message: string, additionalArgs?: string[]): void;
|
|
28
|
+
/**
|
|
29
|
+
* Realiza commit usando arquivo temporário para a mensagem
|
|
30
|
+
*/
|
|
31
|
+
commitWithFile(messageFile: string, additionalArgs?: string[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* Obtém informações sobre o último commit
|
|
34
|
+
*/
|
|
35
|
+
getLastCommitInfo(): {
|
|
36
|
+
hash: string;
|
|
37
|
+
message: string;
|
|
38
|
+
author: string;
|
|
39
|
+
date: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Verifica se há arquivos não commitados
|
|
43
|
+
*/
|
|
44
|
+
hasUncommittedChanges(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Lista branches disponíveis
|
|
47
|
+
*/
|
|
48
|
+
getBranches(): {
|
|
49
|
+
current: string;
|
|
50
|
+
all: string[];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Obtém lista de arquivos alterados (staged)
|
|
54
|
+
*/
|
|
55
|
+
getChangedFiles(): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Obtém diff de um arquivo específico
|
|
58
|
+
*/
|
|
59
|
+
getFileDiff(filePath: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Obtém diff completo dos arquivos staged
|
|
62
|
+
*/
|
|
63
|
+
getStagedDiff(): string;
|
|
64
|
+
}
|