@m3hti/commit-genie 1.0.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/LICENSE +21 -0
- package/README.md +430 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +31 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/generate.d.ts +10 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +313 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/generate.test.d.ts +2 -0
- package/dist/commands/generate.test.d.ts.map +1 -0
- package/dist/commands/generate.test.js +168 -0
- package/dist/commands/generate.test.js.map +1 -0
- package/dist/commands/hook.d.ts +4 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +62 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/stats.d.ts +6 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +39 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/services/aiService.d.ts +38 -0
- package/dist/services/aiService.d.ts.map +1 -0
- package/dist/services/aiService.js +187 -0
- package/dist/services/aiService.js.map +1 -0
- package/dist/services/analyzerService.d.ts +60 -0
- package/dist/services/analyzerService.d.ts.map +1 -0
- package/dist/services/analyzerService.js +832 -0
- package/dist/services/analyzerService.js.map +1 -0
- package/dist/services/analyzerService.test.d.ts +2 -0
- package/dist/services/analyzerService.test.d.ts.map +1 -0
- package/dist/services/analyzerService.test.js +323 -0
- package/dist/services/analyzerService.test.js.map +1 -0
- package/dist/services/configService.d.ts +25 -0
- package/dist/services/configService.d.ts.map +1 -0
- package/dist/services/configService.js +207 -0
- package/dist/services/configService.js.map +1 -0
- package/dist/services/configService.test.d.ts +2 -0
- package/dist/services/configService.test.d.ts.map +1 -0
- package/dist/services/configService.test.js +165 -0
- package/dist/services/configService.test.js.map +1 -0
- package/dist/services/gitService.d.ts +44 -0
- package/dist/services/gitService.d.ts.map +1 -0
- package/dist/services/gitService.js +217 -0
- package/dist/services/gitService.js.map +1 -0
- package/dist/services/gitService.test.d.ts +2 -0
- package/dist/services/gitService.test.d.ts.map +1 -0
- package/dist/services/gitService.test.js +140 -0
- package/dist/services/gitService.test.js.map +1 -0
- package/dist/services/historyService.d.ts +39 -0
- package/dist/services/historyService.d.ts.map +1 -0
- package/dist/services/historyService.js +195 -0
- package/dist/services/historyService.js.map +1 -0
- package/dist/services/historyService.test.d.ts +2 -0
- package/dist/services/historyService.test.d.ts.map +1 -0
- package/dist/services/historyService.test.js +157 -0
- package/dist/services/historyService.test.js.map +1 -0
- package/dist/services/hookService.d.ts +29 -0
- package/dist/services/hookService.d.ts.map +1 -0
- package/dist/services/hookService.js +164 -0
- package/dist/services/hookService.js.map +1 -0
- package/dist/services/statsService.d.ts +28 -0
- package/dist/services/statsService.d.ts.map +1 -0
- package/dist/services/statsService.js +204 -0
- package/dist/services/statsService.js.map +1 -0
- package/dist/types/index.d.ts +134 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/filePatterns.d.ts +5 -0
- package/dist/utils/filePatterns.d.ts.map +1 -0
- package/dist/utils/filePatterns.js +77 -0
- package/dist/utils/filePatterns.js.map +1 -0
- package/dist/utils/filePatterns.test.d.ts +2 -0
- package/dist/utils/filePatterns.test.d.ts.map +1 -0
- package/dist/utils/filePatterns.test.js +51 -0
- package/dist/utils/filePatterns.test.js.map +1 -0
- package/dist/utils/prompt.d.ts +4 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +60 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +47 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const generate_1 = require("./commands/generate");
|
|
6
|
+
const hook_1 = require("./commands/hook");
|
|
7
|
+
const config_1 = require("./commands/config");
|
|
8
|
+
const stats_1 = require("./commands/stats");
|
|
9
|
+
const program = new commander_1.Command();
|
|
10
|
+
program
|
|
11
|
+
.name('commit-genie')
|
|
12
|
+
.description('Generate intelligent Git commit messages based on your code changes')
|
|
13
|
+
.version('1.0.0');
|
|
14
|
+
program
|
|
15
|
+
.command('generate')
|
|
16
|
+
.alias('gen')
|
|
17
|
+
.description('Analyze staged changes and suggest a commit message')
|
|
18
|
+
.option('-c, --commit', 'Automatically commit with the generated message')
|
|
19
|
+
.option('-d, --dry-run', 'Preview commit without executing (shows what would be committed)')
|
|
20
|
+
.option('--ai', 'Use AI to generate enhanced commit descriptions (requires API key in config)')
|
|
21
|
+
.option('--no-interactive', 'Disable interactive mode (just show the message)')
|
|
22
|
+
.option('-m, --message-only', 'Output only the commit message (for scripts/hooks)')
|
|
23
|
+
.option('-s, --single', 'Show only one suggestion (skip multiple options)')
|
|
24
|
+
.action((options) => (0, generate_1.generateCommand)(options));
|
|
25
|
+
// Hook commands
|
|
26
|
+
const hookCommand = program
|
|
27
|
+
.command('hook')
|
|
28
|
+
.description('Manage git hooks');
|
|
29
|
+
hookCommand
|
|
30
|
+
.command('install')
|
|
31
|
+
.description('Install the prepare-commit-msg hook')
|
|
32
|
+
.action(hook_1.hookInstallCommand);
|
|
33
|
+
hookCommand
|
|
34
|
+
.command('uninstall')
|
|
35
|
+
.description('Uninstall the prepare-commit-msg hook')
|
|
36
|
+
.action(hook_1.hookUninstallCommand);
|
|
37
|
+
hookCommand
|
|
38
|
+
.command('status')
|
|
39
|
+
.description('Check if the hook is installed')
|
|
40
|
+
.action(hook_1.hookStatusCommand);
|
|
41
|
+
// Config commands
|
|
42
|
+
const configCommand = program
|
|
43
|
+
.command('config')
|
|
44
|
+
.description('Manage configuration');
|
|
45
|
+
configCommand
|
|
46
|
+
.command('init')
|
|
47
|
+
.description('Create a default config file')
|
|
48
|
+
.action(config_1.configInitCommand);
|
|
49
|
+
configCommand
|
|
50
|
+
.command('show')
|
|
51
|
+
.description('Show current configuration')
|
|
52
|
+
.action(config_1.configShowCommand);
|
|
53
|
+
// Stats command
|
|
54
|
+
program
|
|
55
|
+
.command('stats')
|
|
56
|
+
.description('Show commit statistics for the repository')
|
|
57
|
+
.option('-n, --count <number>', 'Number of commits to analyze', '100')
|
|
58
|
+
.option('--json', 'Output as JSON')
|
|
59
|
+
.action((options) => {
|
|
60
|
+
(0, stats_1.statsCommand)({
|
|
61
|
+
count: parseInt(options.count, 10),
|
|
62
|
+
json: options.json,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
// Default action (if no command specified, run generate)
|
|
66
|
+
program
|
|
67
|
+
.option('-c, --commit', 'Automatically commit with the generated message')
|
|
68
|
+
.option('-d, --dry-run', 'Preview commit without executing (shows what would be committed)')
|
|
69
|
+
.option('--ai', 'Use AI to generate enhanced commit descriptions (requires API key in config)')
|
|
70
|
+
.option('--no-interactive', 'Disable interactive mode (just show the message)')
|
|
71
|
+
.option('-m, --message-only', 'Output only the commit message (for scripts/hooks)')
|
|
72
|
+
.option('-s, --single', 'Show only one suggestion (skip multiple options)')
|
|
73
|
+
.action((options) => {
|
|
74
|
+
(0, generate_1.generateCommand)(options);
|
|
75
|
+
});
|
|
76
|
+
program.parse(process.argv);
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ChangeAnalysis, CommitType } from '../types';
|
|
2
|
+
interface AIResponse {
|
|
3
|
+
description: string;
|
|
4
|
+
type?: CommitType;
|
|
5
|
+
scope?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class AIService {
|
|
8
|
+
/**
|
|
9
|
+
* Check if AI is enabled and configured
|
|
10
|
+
*/
|
|
11
|
+
static isEnabled(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Generate an AI-enhanced description for the commit
|
|
14
|
+
*/
|
|
15
|
+
static generateDescription(analysis: ChangeAnalysis, diff: string): Promise<AIResponse | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Build the prompt for the AI
|
|
18
|
+
*/
|
|
19
|
+
private static buildPrompt;
|
|
20
|
+
/**
|
|
21
|
+
* Call OpenAI API
|
|
22
|
+
*/
|
|
23
|
+
private static callOpenAI;
|
|
24
|
+
/**
|
|
25
|
+
* Call Anthropic API
|
|
26
|
+
*/
|
|
27
|
+
private static callAnthropic;
|
|
28
|
+
/**
|
|
29
|
+
* Call Google AI Studio (Gemini) API
|
|
30
|
+
*/
|
|
31
|
+
private static callGoogle;
|
|
32
|
+
/**
|
|
33
|
+
* Get default model for provider
|
|
34
|
+
*/
|
|
35
|
+
private static getDefaultModel;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=aiService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiService.d.ts","sourceRoot":"","sources":["../../src/services/aiService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD,UAAU,UAAU;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB;;OAEG;IACH,MAAM,CAAC,SAAS,IAAI,OAAO;IAK3B;;OAEG;WACU,mBAAmB,CAC9B,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAiC7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAgC1B;;OAEG;mBACkB,UAAU;IAkC/B;;OAEG;mBACkB,aAAa;IAkClC;;OAEG;mBACkB,UAAU;IA2C/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAY/B"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AIService = void 0;
|
|
4
|
+
const configService_1 = require("./configService");
|
|
5
|
+
class AIService {
|
|
6
|
+
/**
|
|
7
|
+
* Check if AI is enabled and configured
|
|
8
|
+
*/
|
|
9
|
+
static isEnabled() {
|
|
10
|
+
const config = configService_1.ConfigService.getConfig();
|
|
11
|
+
return config.ai?.enabled === true && !!config.ai?.apiKey;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate an AI-enhanced description for the commit
|
|
15
|
+
*/
|
|
16
|
+
static async generateDescription(analysis, diff) {
|
|
17
|
+
const config = configService_1.ConfigService.getConfig();
|
|
18
|
+
const aiConfig = config.ai;
|
|
19
|
+
if (!aiConfig?.enabled || !aiConfig?.apiKey) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const provider = aiConfig.provider || 'openai';
|
|
23
|
+
const model = aiConfig.model || this.getDefaultModel(provider);
|
|
24
|
+
// Truncate diff to avoid token limits
|
|
25
|
+
const truncatedDiff = diff.length > 3000 ? diff.substring(0, 3000) + '\n...(truncated)' : diff;
|
|
26
|
+
const prompt = this.buildPrompt(analysis, truncatedDiff);
|
|
27
|
+
try {
|
|
28
|
+
if (provider === 'openai') {
|
|
29
|
+
return await this.callOpenAI(aiConfig.apiKey, model, prompt);
|
|
30
|
+
}
|
|
31
|
+
else if (provider === 'anthropic') {
|
|
32
|
+
return await this.callAnthropic(aiConfig.apiKey, model, prompt);
|
|
33
|
+
}
|
|
34
|
+
else if (provider === 'google') {
|
|
35
|
+
return await this.callGoogle(aiConfig.apiKey, model, prompt);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
40
|
+
console.error(`\n⚠ AI Error: ${errorMsg}`);
|
|
41
|
+
throw error; // Re-throw so caller can handle it
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build the prompt for the AI
|
|
47
|
+
*/
|
|
48
|
+
static buildPrompt(analysis, diff) {
|
|
49
|
+
const filesChanged = [
|
|
50
|
+
...analysis.fileChanges.added.map(f => `+ ${f} (added)`),
|
|
51
|
+
...analysis.fileChanges.modified.map(f => `~ ${f} (modified)`),
|
|
52
|
+
...analysis.fileChanges.deleted.map(f => `- ${f} (deleted)`),
|
|
53
|
+
...analysis.fileChanges.renamed.map(f => `→ ${f} (renamed)`),
|
|
54
|
+
].join('\n');
|
|
55
|
+
return `You are a helpful assistant that generates concise, professional git commit messages following the Conventional Commits specification.
|
|
56
|
+
|
|
57
|
+
Given the following git diff and file changes, generate a commit message description (NOT the full message, just the description after the type: prefix).
|
|
58
|
+
|
|
59
|
+
FILE CHANGES:
|
|
60
|
+
${filesChanged}
|
|
61
|
+
|
|
62
|
+
DETECTED COMMIT TYPE: ${analysis.commitType}
|
|
63
|
+
${analysis.scope ? `DETECTED SCOPE: ${analysis.scope}` : ''}
|
|
64
|
+
${analysis.isBreakingChange ? 'THIS IS A BREAKING CHANGE' : ''}
|
|
65
|
+
|
|
66
|
+
GIT DIFF:
|
|
67
|
+
${diff}
|
|
68
|
+
|
|
69
|
+
RULES:
|
|
70
|
+
1. Write a clear, concise description (max 50 characters ideal, 72 max)
|
|
71
|
+
2. Use lowercase and imperative mood (e.g., "add", "fix", "update", not "added", "fixes", "updated")
|
|
72
|
+
3. Don't end with a period
|
|
73
|
+
4. Focus on WHAT changed and WHY, not HOW
|
|
74
|
+
5. Be specific but brief
|
|
75
|
+
|
|
76
|
+
Respond with ONLY the description text, nothing else. No quotes, no type prefix, just the description.`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Call OpenAI API
|
|
80
|
+
*/
|
|
81
|
+
static async callOpenAI(apiKey, model, prompt) {
|
|
82
|
+
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
model,
|
|
90
|
+
messages: [
|
|
91
|
+
{ role: 'user', content: prompt }
|
|
92
|
+
],
|
|
93
|
+
max_tokens: 100,
|
|
94
|
+
temperature: 0.3,
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
const errorText = await response.text();
|
|
99
|
+
throw new Error(`OpenAI API error: ${response.status} - ${errorText}`);
|
|
100
|
+
}
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
const content = data.choices?.[0]?.message?.content?.trim();
|
|
103
|
+
if (content) {
|
|
104
|
+
return { description: content.toLowerCase() };
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Call Anthropic API
|
|
110
|
+
*/
|
|
111
|
+
static async callAnthropic(apiKey, model, prompt) {
|
|
112
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: {
|
|
115
|
+
'Content-Type': 'application/json',
|
|
116
|
+
'x-api-key': apiKey,
|
|
117
|
+
'anthropic-version': '2023-06-01',
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify({
|
|
120
|
+
model,
|
|
121
|
+
max_tokens: 100,
|
|
122
|
+
messages: [
|
|
123
|
+
{ role: 'user', content: prompt }
|
|
124
|
+
],
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const errorText = await response.text();
|
|
129
|
+
throw new Error(`Anthropic API error: ${response.status} - ${errorText}`);
|
|
130
|
+
}
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
const content = data.content?.find(c => c.type === 'text')?.text?.trim();
|
|
133
|
+
if (content) {
|
|
134
|
+
return { description: content.toLowerCase() };
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Call Google AI Studio (Gemini) API
|
|
140
|
+
*/
|
|
141
|
+
static async callGoogle(apiKey, model, prompt) {
|
|
142
|
+
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`, {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: {
|
|
145
|
+
'Content-Type': 'application/json',
|
|
146
|
+
},
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
contents: [
|
|
149
|
+
{
|
|
150
|
+
parts: [{ text: prompt }],
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
generationConfig: {
|
|
154
|
+
maxOutputTokens: 100,
|
|
155
|
+
temperature: 0.3,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
const errorText = await response.text();
|
|
161
|
+
throw new Error(`Google AI API error: ${response.status} - ${errorText}`);
|
|
162
|
+
}
|
|
163
|
+
const data = await response.json();
|
|
164
|
+
const content = data.candidates?.[0]?.content?.parts?.[0]?.text?.trim();
|
|
165
|
+
if (content) {
|
|
166
|
+
return { description: content.toLowerCase() };
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get default model for provider
|
|
172
|
+
*/
|
|
173
|
+
static getDefaultModel(provider) {
|
|
174
|
+
switch (provider) {
|
|
175
|
+
case 'openai':
|
|
176
|
+
return 'gpt-4o-mini';
|
|
177
|
+
case 'anthropic':
|
|
178
|
+
return 'claude-3-haiku-20240307';
|
|
179
|
+
case 'google':
|
|
180
|
+
return 'gemini-1.5-flash';
|
|
181
|
+
default:
|
|
182
|
+
return 'gpt-4o-mini';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.AIService = AIService;
|
|
187
|
+
//# sourceMappingURL=aiService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiService.js","sourceRoot":"","sources":["../../src/services/aiService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ChangeAnalysis, CommitMessage, MessageSuggestion } from '../types';
|
|
2
|
+
export declare class AnalyzerService {
|
|
3
|
+
/**
|
|
4
|
+
* Analyze staged changes and return structured analysis
|
|
5
|
+
*/
|
|
6
|
+
static analyzeChanges(): ChangeAnalysis;
|
|
7
|
+
/**
|
|
8
|
+
* Detect breaking changes from diff content and file changes
|
|
9
|
+
*/
|
|
10
|
+
private static detectBreakingChanges;
|
|
11
|
+
/**
|
|
12
|
+
* Determine the commit type based on analysis
|
|
13
|
+
*/
|
|
14
|
+
private static determineCommitType;
|
|
15
|
+
/**
|
|
16
|
+
* Check if diff contains actual logic changes (not just formatting)
|
|
17
|
+
*/
|
|
18
|
+
private static hasLogicChanges;
|
|
19
|
+
/**
|
|
20
|
+
* Generate a descriptive commit message
|
|
21
|
+
*/
|
|
22
|
+
private static generateDescription;
|
|
23
|
+
/**
|
|
24
|
+
* Determine scope from file paths
|
|
25
|
+
*/
|
|
26
|
+
private static determineScope;
|
|
27
|
+
/**
|
|
28
|
+
* Extract file name from path
|
|
29
|
+
*/
|
|
30
|
+
private static getFileName;
|
|
31
|
+
/**
|
|
32
|
+
* Generate commit body for larger changes
|
|
33
|
+
*/
|
|
34
|
+
private static generateBody;
|
|
35
|
+
/**
|
|
36
|
+
* Apply a template to build the commit message subject line
|
|
37
|
+
*/
|
|
38
|
+
private static applyTemplate;
|
|
39
|
+
/**
|
|
40
|
+
* Build full commit message string
|
|
41
|
+
*/
|
|
42
|
+
private static buildFullMessage;
|
|
43
|
+
/**
|
|
44
|
+
* Generate the final commit message
|
|
45
|
+
*/
|
|
46
|
+
static generateCommitMessage(): CommitMessage;
|
|
47
|
+
/**
|
|
48
|
+
* Generate multiple message suggestions
|
|
49
|
+
*/
|
|
50
|
+
static generateMultipleSuggestions(): MessageSuggestion[];
|
|
51
|
+
/**
|
|
52
|
+
* Generate suggestions with optional AI enhancement
|
|
53
|
+
*/
|
|
54
|
+
static generateSuggestionsWithAI(useAI?: boolean): Promise<MessageSuggestion[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Generate an alternative description style
|
|
57
|
+
*/
|
|
58
|
+
private static generateAlternativeDescription;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=analyzerService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzerService.d.ts","sourceRoot":"","sources":["../../src/services/analyzerService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,aAAa,EAA0B,iBAAiB,EAAc,MAAM,UAAU,CAAC;AAuChH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,cAAc;IAmFvC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAuEpC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA2OlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA4B9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA4DlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAiD7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAK1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IA8B3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IA8B5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAkE/B;;OAEG;IACH,MAAM,CAAC,qBAAqB,IAAI,aAAa;IAkC7C;;OAEG;IACH,MAAM,CAAC,2BAA2B,IAAI,iBAAiB,EAAE;IAqLzD;;OAEG;WACU,yBAAyB,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA0E5F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,8BAA8B;CAqC9C"}
|