@gilbert_oliveira/commit-wizard 1.0.25 → 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.
package/README.md CHANGED
@@ -1,80 +1,253 @@
1
- # Commit Wizard
1
+ # 🧙‍♂️ Commit Wizard
2
+
3
+ [![npm version](https://badge.fury.io/js/%40gilbert_oliveira%2Fcommit-wizard.svg)](https://badge.fury.io/js/%40gilbert_oliveira%2Fcommit-wizard)
4
+ [![CI/CD](https://github.com/gilbert-oliveira/commit-wizard/actions/workflows/ci.yml/badge.svg)](https://github.com/gilbert-oliveira/commit-wizard/actions/workflows/ci.yml)
5
+ [![codecov](https://codecov.io/gh/gilbert-oliveira/commit-wizard/branch/main/graph/badge.svg)](https://codecov.io/gh/gilbert-oliveira/commit-wizard)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
2
7
 
3
8
  Gere mensagens de commit convencionais automaticamente com base nas alterações no código usando a API da OpenAI.
4
9
 
5
- ## ✨ Visão Geral
10
+ ## ✨ Funcionalidades
6
11
 
7
- Este projeto é uma ferramenta de linha de comando (CLI) chamada `commit-wizard`, que utiliza a API da OpenAI para gerar mensagens de commit com base no `diff` dos arquivos que estão em *staged* no Git.
12
+ - 🤖 **Geração inteligente de commits** usando GPT-4o/GPT-4o Mini
13
+ - 📝 **Convenção de Conventional Commits** automática
14
+ - 🌍 **Suporte multilíngue** (Português e Inglês)
15
+ - ⚙️ **Configuração flexível** (local e global)
16
+ - 📊 **Análise de complexidade** do diff
17
+ - 🚀 **Auto commit** opcional
18
+ - 😀 **Emojis** opcionais nas mensagens
19
+ - 🔄 **Regeneração** de mensagens
20
+ - 📋 **Cópia para clipboard**
21
+ - 🎯 **Detecção de breaking changes**
22
+ - 🧪 **Cobertura de testes** completa
8
23
 
9
24
  ## 🚀 Instalação
10
25
 
26
+ ### Global (Recomendado)
11
27
  ```bash
12
- npm install -g commit-wizard
28
+ npm install -g @gilbert_oliveira/commit-wizard
13
29
  ```
14
30
 
15
- Ou, se estiver usando localmente:
16
-
31
+ ### Local
17
32
  ```bash
18
- npm install
33
+ npm install @gilbert_oliveira/commit-wizard
19
34
  ```
20
35
 
21
36
  ## ⚙️ Configuração
22
37
 
23
- Antes de usar, você precisa definir a variável de ambiente com sua chave da OpenAI:
38
+ ### 1. API Key da OpenAI
39
+ Defina sua chave da OpenAI como variável de ambiente:
24
40
 
25
41
  ```bash
26
42
  export OPENAI_API_KEY=sk-...
27
43
  ```
28
44
 
29
- Você pode adicionar isso no seu `.bashrc`, `.zshrc` ou arquivo de ambiente equivalente.
45
+ Adicione isso no seu `.bashrc`, `.zshrc` ou arquivo de ambiente equivalente.
46
+
47
+ ### 2. Configuração do Wizard
48
+ Execute o comando de configuração para personalizar o comportamento:
49
+
50
+ ```bash
51
+ commit-wizard --config
52
+ ```
53
+
54
+ Ou crie um arquivo `.commit-wizard.json` no seu projeto ou diretório home:
55
+
56
+ ```json
57
+ {
58
+ "model": "gpt-4o",
59
+ "temperature": 0.2,
60
+ "maxTokens": 1000,
61
+ "language": "pt",
62
+ "autoCommit": false,
63
+ "excludePatterns": ["*.lock*", "*.log", "node_modules/**"],
64
+ "includeEmoji": true
65
+ }
66
+ ```
30
67
 
31
68
  ## 🧠 Como Funciona
32
69
 
33
- 1. O script os arquivos que estão em *staged* (`git diff --cached`).
34
- 2. Envia esse diff para a API da OpenAI.
35
- 3. Recebe uma sugestão de mensagem de commit no formato convencional (`feat:`, `fix:`, etc).
36
- 4. Exibe a mensagem para revisão.
70
+ 1. **Análise**: os arquivos staged (`git diff --cached`)
71
+ 2. **Processamento**: Divide diff grandes em chunks menores
72
+ 3. **IA**: Envia para OpenAI com prompts otimizados
73
+ 4. **Geração**: Cria mensagem seguindo Conventional Commits
74
+ 5. **Interação**: Permite edição, regeneração ou cópia
75
+ 6. **Commit**: Executa git commit com a mensagem final
76
+
77
+ ## 📝 Exemplos de Uso
78
+
79
+ ### Uso Básico
80
+ ```bash
81
+ # Adicione arquivos ao stage
82
+ git add .
83
+
84
+ # Execute o wizard
85
+ commit-wizard
86
+ ```
87
+
88
+ ### Comandos Disponíveis
89
+ ```bash
90
+ commit-wizard # Gerar commit normal
91
+ commit-wizard --config # Configurar o wizard
92
+ commit-wizard --info # Ver informações do sistema
93
+ commit-wizard --help # Mostrar ajuda
94
+ ```
95
+
96
+ ### Exemplo de Output
97
+ ```
98
+ 📈 Análise do Diff:
99
+ • Arquivos alterados: 3
100
+ • Linhas adicionadas: +45
101
+ • Linhas removidas: -12
102
+ • Tokens estimados: 850
103
+ • Complexidade: 🟡 Moderada
104
+
105
+ ✨ Mensagem de commit gerada:
106
+ feat(auth): adiciona autenticação OAuth2 com Google
107
+
108
+ 💰 Tokens utilizados: 1,234 (prompt: 987, resposta: 247)
109
+
110
+ O que deseja fazer com a mensagem de commit?
111
+ ❯ 📌 Confirmar e commitar
112
+ 📝 Editar a mensagem antes de commitar
113
+ 🔄 Regenerar mensagem
114
+ 📋 Copiar para clipboard
115
+ 🚫 Cancelar o commit
116
+ ```
117
+
118
+ ## 🛠 Modelos Suportados
119
+
120
+ - **GPT-4o** (padrão) - Mais recente e eficiente
121
+ - **GPT-4o Mini** - Mais rápido e econômico
122
+ - **GPT-4 Turbo** - Versão anterior robusta
123
+ - **GPT-3.5 Turbo** - Opção econômica
37
124
 
38
- ## 📝 Exemplo de Uso
125
+ ## 🧪 Scripts de Desenvolvimento
39
126
 
40
127
  ```bash
41
- npx commit-wizard
128
+ npm run build # Compilar TypeScript
129
+ npm run dev # Modo desenvolvimento
130
+ npm run test # Executar testes
131
+ npm run test:watch # Testes em modo watch
132
+ npm run test:coverage # Testes com cobertura
133
+ npm run lint # Verificar lint
134
+ npm run lint:fix # Corrigir lint automaticamente
135
+ npm run format # Formatar código
136
+ npm run format:check # Verificar formatação
137
+ npm run clean # Limpar arquivos build
42
138
  ```
43
139
 
44
- Resultado esperado:
140
+ ## 📊 Conventional Commits Suportados
141
+
142
+ O wizard gera mensagens seguindo a [especificação Conventional Commits](https://www.conventionalcommits.org/):
143
+
144
+ - `feat:` - Novas funcionalidades
145
+ - `fix:` - Correções de bugs
146
+ - `docs:` - Mudanças na documentação
147
+ - `style:` - Formatação, ponto e vírgula, etc.
148
+ - `refactor:` - Mudanças que não alteram funcionalidade
149
+ - `perf:` - Melhorias de performance
150
+ - `test:` - Adição ou correção de testes
151
+ - `chore:` - Mudanças em ferramentas, configs, etc.
152
+ - `ci:` - Mudanças no CI/CD
45
153
 
154
+ ### Breaking Changes
155
+ Para alterações que quebram compatibilidade:
46
156
  ```
47
- Sugestão de commit:
48
- feat: adiciona verificação automática para arquivos staged usando GPT-4
157
+ feat!(auth): reestruturar API de login
158
+
159
+ BREAKING CHANGE: A API de login foi alterada e não é compatível com versões anteriores.
49
160
  ```
50
161
 
51
- ## 🛠 Tecnologias Utilizadas
162
+ ## 🎯 Configurações Avançadas
163
+
164
+ ### Padrões de Exclusão
165
+ Customize quais arquivos ignorar:
166
+ ```json
167
+ {
168
+ "excludePatterns": [
169
+ "*.lock*",
170
+ "*.log",
171
+ "node_modules/**",
172
+ "dist/**",
173
+ "coverage/**"
174
+ ]
175
+ }
176
+ ```
52
177
 
53
- - Node.js
54
- - TypeScript
55
- - OpenAI API
56
- - Commander (CLI)
57
- - Dotenv
178
+ ### Auto Commit
179
+ Para fluxos automatizados:
180
+ ```json
181
+ {
182
+ "autoCommit": true
183
+ }
184
+ ```
185
+
186
+ ### Multilíngue
187
+ Suporte para português e inglês:
188
+ ```json
189
+ {
190
+ "language": "en"
191
+ }
192
+ ```
58
193
 
59
- ## 🧪 Scripts Disponíveis
194
+ ## 🚨 Tratamento de Erros
60
195
 
61
- - `npm run build`: compila o TypeScript para JavaScript.
62
- - `npm start`: executa o CLI direto pelo TypeScript (com ts-node).
63
- - `npm run dev`: roda em modo de desenvolvimento com `ts-node-dev`.
196
+ O wizard trata graciosamente:
197
+ - API key não configurada
198
+ - Não é repositório Git
199
+ - ❌ Sem arquivos staged
200
+ - ❌ Erros da API OpenAI
201
+ - ❌ Problemas de conectividade
202
+ - ❌ Arquivos de configuração inválidos
64
203
 
65
- ## Commit Convencional
204
+ ## 💡 Dicas de Uso
66
205
 
67
- Este projeto segue o padrão de commit convencional, como:
206
+ 1. **Stage seletivo**: Use `git add -p` para adicionar mudanças específicas
207
+ 2. **Configuração por projeto**: Crie `.commit-wizard.json` no projeto
208
+ 3. **Temperatura baixa**: Use 0.1-0.3 para mensagens mais consistentes
209
+ 4. **Exclude patterns**: Configure para ignorar arquivos irrelevantes
210
+ 5. **Auto commit**: Ative apenas em ambientes confiáveis
68
211
 
69
- - `feat:` para novas funcionalidades
70
- - `fix:` para correções de bugs
71
- - `docs:` para documentação
72
- - `refactor:` para mudanças internas no código
212
+ ## 🤝 Contribuindo
213
+
214
+ 1. Fork o projeto
215
+ 2. Crie uma branch para sua feature (`git checkout -b feature/AmazingFeature`)
216
+ 3. Commit suas mudanças (`git commit -m 'feat: add some AmazingFeature'`)
217
+ 4. Push para a branch (`git push origin feature/AmazingFeature`)
218
+ 5. Abra um Pull Request
219
+
220
+ ### Executando Localmente
221
+ ```bash
222
+ git clone https://github.com/gilbert-oliveira/commit-wizard.git
223
+ cd commit-wizard
224
+ npm install
225
+ npm run build
226
+ npm link
227
+ ```
228
+
229
+ ## 📈 Roadmap
230
+
231
+ - [ ] Suporte a outros provedores de IA (Claude, Gemini)
232
+ - [ ] Integração com GitHub Actions
233
+ - [ ] Plugin para VS Code
234
+ - [ ] Templates de commit customizáveis
235
+ - [ ] Integração com Conventional Changelog
236
+ - [ ] Suporte a monorepos
237
+ - [ ] Cache de respostas IA
73
238
 
74
239
  ## 📄 Licença
75
240
 
76
241
  Este projeto está licenciado sob a licença MIT. Veja o arquivo [LICENSE](LICENSE) para mais detalhes.
77
242
 
243
+ ## 🙏 Agradecimentos
244
+
245
+ - [OpenAI](https://openai.com/) pela API GPT
246
+ - [Conventional Commits](https://www.conventionalcommits.org/) pela especificação
247
+ - Comunidade open source pelas bibliotecas utilizadas
248
+
78
249
  ---
79
250
 
80
- Feito com 💜 por Gilbert de Oliveira Santos
251
+ <div align="center">
252
+ <sub>Feito com 💜 por <a href="https://github.com/gilbert-oliveira">Gilbert de Oliveira Santos</a></sub>
253
+ </div>
@@ -0,0 +1,36 @@
1
+ import { Config } from './config.js';
2
+ export interface AIResponse {
3
+ content: string;
4
+ usage?: {
5
+ promptTokens: number;
6
+ completionTokens: number;
7
+ totalTokens: number;
8
+ };
9
+ }
10
+ /**
11
+ * Serviço para interação com APIs de IA
12
+ */
13
+ export declare class AIService {
14
+ private config;
15
+ constructor(config: Config);
16
+ /**
17
+ * Gera prompt do sistema baseado no modo e linguagem
18
+ */
19
+ private getSystemPrompt;
20
+ /**
21
+ * Gera prompt para mensagem de commit
22
+ */
23
+ private getCommitPrompt;
24
+ /**
25
+ * Realiza chamada para a API da OpenAI
26
+ */
27
+ callOpenAI(prompt: string, mode?: 'commit' | 'summary'): Promise<AIResponse>;
28
+ /**
29
+ * Gera resumo de um chunk de diff
30
+ */
31
+ generateSummary(chunk: string): Promise<string>;
32
+ /**
33
+ * Gera mensagem de commit baseada no diff ou resumo
34
+ */
35
+ generateCommitMessage(diffOrSummary: string): Promise<AIResponse>;
36
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Serviço para interação com APIs de IA
3
+ */
4
+ export class AIService {
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ /**
9
+ * Gera prompt do sistema baseado no modo e linguagem
10
+ */
11
+ getSystemPrompt(mode) {
12
+ const isPortuguese = this.config.language === 'pt';
13
+ if (mode === 'commit') {
14
+ return isPortuguese
15
+ ? 'Você é um assistente que gera mensagens de commit seguindo a convenção do Conventional Commits. Use linguagem imperativa em português.'
16
+ : 'You are an assistant that generates commit messages following the Conventional Commits convention. Use imperative language in English.';
17
+ }
18
+ return isPortuguese
19
+ ? 'Você é um assistente que resume alterações de código de forma breve, usando linguagem imperativa em português.'
20
+ : 'You are an assistant that summarizes code changes briefly, using imperative language in English.';
21
+ }
22
+ /**
23
+ * Gera prompt para mensagem de commit
24
+ */
25
+ getCommitPrompt() {
26
+ const isPortuguese = this.config.language === 'pt';
27
+ if (isPortuguese) {
28
+ return `
29
+ Por favor, escreva a mensagem de commit para este diff usando a convenção de Conventional Commits.
30
+ A mensagem deve começar com um tipo de commit, como:
31
+ feat: para novas funcionalidades
32
+ fix: para correções de bugs
33
+ chore: para alterações que não afetam a funcionalidade
34
+ docs: para mudanças na documentação
35
+ style: para alterações no estilo do código (formatação)
36
+ refactor: para alterações no código que não alteram a funcionalidade
37
+ perf: para melhorias de desempenho
38
+ test: para alterações nos testes
39
+ ci: para mudanças no pipeline de integração contínua
40
+
41
+ ${this.config.includeEmoji ? 'Inclua emojis apropriados no início da mensagem.' : 'Não inclua emojis na mensagem.'}
42
+
43
+ Para breaking changes, use "!" após o tipo: feat!(auth): reestruturar fluxo de login
44
+
45
+ Use sempre linguagem imperativa, como:
46
+ - "adiciona recurso"
47
+ - "corrige bug"
48
+ - "remove arquivo"
49
+
50
+ Mantenha a mensagem concisa mas informativa.
51
+ `;
52
+ }
53
+ return `
54
+ Please write the commit message for this diff using the Conventional Commits convention.
55
+ The message should start with a commit type, such as:
56
+ feat: for new features
57
+ fix: for bug fixes
58
+ chore: for changes that don't affect functionality
59
+ docs: for documentation changes
60
+ style: for code style changes (formatting)
61
+ refactor: for code changes that don't alter functionality
62
+ perf: for performance improvements
63
+ test: for test changes
64
+ ci: for CI pipeline changes
65
+
66
+ ${this.config.includeEmoji ? 'Include appropriate emojis at the beginning of the message.' : 'Do not include emojis in the message.'}
67
+
68
+ For breaking changes, use "!" after the type: feat!(auth): restructure login flow
69
+
70
+ Always use imperative language, such as:
71
+ - "add feature"
72
+ - "fix bug"
73
+ - "remove file"
74
+
75
+ Keep the message concise but informative.
76
+ `;
77
+ }
78
+ /**
79
+ * Realiza chamada para a API da OpenAI
80
+ */
81
+ async callOpenAI(prompt, mode = 'commit') {
82
+ if (!this.config.apiKey) {
83
+ throw new Error('API key da OpenAI não configurada');
84
+ }
85
+ const url = 'https://api.openai.com/v1/chat/completions';
86
+ const systemPrompt = this.getSystemPrompt(mode);
87
+ const fullPrompt = mode === 'commit' ? `${this.getCommitPrompt()}\n\nDiff:\n\n${prompt}` : prompt;
88
+ const body = {
89
+ model: this.config.model,
90
+ messages: [
91
+ { role: 'system', content: systemPrompt },
92
+ { role: 'user', content: fullPrompt },
93
+ ],
94
+ temperature: this.config.temperature,
95
+ max_tokens: 500, // Limite para mensagens de commit
96
+ };
97
+ try {
98
+ // Timeout de 30 segundos para evitar travamentos
99
+ const controller = new AbortController();
100
+ const timeoutId = globalThis.setTimeout(() => controller.abort(), 30000);
101
+ const response = await globalThis.fetch(url, {
102
+ method: 'POST',
103
+ headers: {
104
+ 'Content-Type': 'application/json',
105
+ Authorization: `Bearer ${this.config.apiKey}`,
106
+ },
107
+ body: JSON.stringify(body),
108
+ signal: controller.signal,
109
+ });
110
+ globalThis.clearTimeout(timeoutId);
111
+ if (!response.ok) {
112
+ const errorData = await response.json().catch(() => ({}));
113
+ throw new Error(`Erro na API OpenAI (${response.status}): ${errorData.error?.message || response.statusText}`);
114
+ }
115
+ const data = await response.json();
116
+ return {
117
+ content: data.choices[0].message.content.trim().replace(/```/g, ''),
118
+ usage: data.usage
119
+ ? {
120
+ promptTokens: data.usage.prompt_tokens,
121
+ completionTokens: data.usage.completion_tokens,
122
+ totalTokens: data.usage.total_tokens,
123
+ }
124
+ : undefined,
125
+ };
126
+ }
127
+ catch (error) {
128
+ if (error instanceof Error) {
129
+ if (error.name === 'AbortError') {
130
+ throw new Error('Timeout: A requisição demorou mais de 30 segundos. Tente reduzir o tamanho do diff ou verificar sua conexão.');
131
+ }
132
+ throw error;
133
+ }
134
+ throw new Error(`Erro desconhecido ao chamar API: ${error}`);
135
+ }
136
+ }
137
+ /**
138
+ * Gera resumo de um chunk de diff
139
+ */
140
+ async generateSummary(chunk) {
141
+ const isPortuguese = this.config.language === 'pt';
142
+ const summaryPrefix = isPortuguese
143
+ ? 'A partir do diff abaixo, extraia um resumo breve das alterações (use linguagem imperativa):'
144
+ : 'From the diff below, extract a brief summary of the changes (use imperative language):';
145
+ const prompt = `${summaryPrefix}\n\n${chunk}`;
146
+ const response = await this.callOpenAI(prompt, 'summary');
147
+ return response.content;
148
+ }
149
+ /**
150
+ * Gera mensagem de commit baseada no diff ou resumo
151
+ */
152
+ async generateCommitMessage(diffOrSummary) {
153
+ return this.callOpenAI(diffOrSummary, 'commit');
154
+ }
155
+ }
156
+ //# sourceMappingURL=ai-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-service.js","sourceRoot":"","sources":["../src/ai-service.ts"],"names":[],"mappings":"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"}
@@ -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":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAapB,MAAM,cAAc,GAAW;IAC7B,KAAK,EAAE,QAAQ;IACf,WAAW,EAAE,GAAG;IAChB,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,KAAK;IACjB,eAAe,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,iBAAiB,CAAC;IACxD,YAAY,EAAE,IAAI;CACnB,CAAC;AAEF,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C;;GAEG;AACH,SAAS,cAAc;IACrB,uCAAuC;IACvC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,qCAAqC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,IAAI,UAAU,GAAoB,EAAE,CAAC;IAErC,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC1D,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,0CAA0C,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,MAAM,MAAM,GAAW;QACrB,GAAG,cAAc;QACjB,GAAG,UAAU;QACb,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;KACxD,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAuB,EAAE,MAAM,GAAG,KAAK;IAChE,MAAM,UAAU,GAAG,MAAM;QACvB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC;QAC3C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAEnD,yEAAyE;QACzE,OAAO,SAAS,CAAC,MAAM,CAAC;QAExB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,gBAAgB,UAAU,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG;QACpB,GAAG,cAAc;QACjB,MAAM,EAAE,6BAA6B;KACtC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;AAC7D,CAAC"}
@@ -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
+ }