commic 1.0.0 → 1.0.2
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/CHANGELOG.md +83 -0
- package/README.md +3 -3
- package/dist/ai/AIService.d.ts +3 -3
- package/dist/ai/AIService.d.ts.map +1 -1
- package/dist/ai/AIService.js +12 -61
- package/dist/ai/AIService.js.map +1 -1
- package/dist/config/CommitPromptTemplate.d.ts +9 -0
- package/dist/config/CommitPromptTemplate.d.ts.map +1 -0
- package/dist/config/CommitPromptTemplate.js +89 -0
- package/dist/config/CommitPromptTemplate.js.map +1 -0
- package/dist/config/ConfigManager.js +1 -1
- package/dist/config/ConfigManager.js.map +1 -1
- package/dist/git/GitService.d.ts.map +1 -1
- package/dist/git/GitService.js +12 -4
- package/dist/git/GitService.js.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/MainOrchestrator.d.ts +3 -3
- package/dist/orchestrator/MainOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/MainOrchestrator.js +31 -23
- package/dist/orchestrator/MainOrchestrator.js.map +1 -1
- package/dist/ui/UIManager.d.ts +6 -2
- package/dist/ui/UIManager.d.ts.map +1 -1
- package/dist/ui/UIManager.js +31 -6
- package/dist/ui/UIManager.js.map +1 -1
- package/package.json +1 -1
- package/src/ai/AIService.ts +15 -65
- package/src/config/CommitPromptTemplate.ts +93 -0
- package/src/config/ConfigManager.ts +1 -1
- package/src/git/GitService.ts +15 -4
- package/src/index.ts +11 -1
- package/src/orchestrator/MainOrchestrator.ts +34 -23
- package/src/ui/UIManager.ts +34 -8
|
@@ -32,14 +32,31 @@ export class MainOrchestrator {
|
|
|
32
32
|
const repositoryPath = options.path || '.';
|
|
33
33
|
const repository = await this.findAndValidateRepository(repositoryPath);
|
|
34
34
|
|
|
35
|
+
// Step 2.5: Stage all changes
|
|
36
|
+
await this.stageAllChanges(repository.rootPath);
|
|
37
|
+
|
|
35
38
|
// Step 3: Get Git diff
|
|
36
39
|
const diff = await this.getGitDiff(repository.rootPath);
|
|
37
40
|
|
|
38
41
|
// Step 4: Generate commit suggestions
|
|
39
|
-
|
|
42
|
+
let suggestions = await this.generateSuggestions(config, diff);
|
|
43
|
+
let customInstruction: string | undefined;
|
|
44
|
+
|
|
45
|
+
// Step 5: Let user select a commit message (with regenerate option)
|
|
46
|
+
let selectedIndex = await this.uiManager.promptForCommitSelection(suggestions);
|
|
40
47
|
|
|
41
|
-
//
|
|
42
|
-
|
|
48
|
+
// Handle regenerate with prompt loop
|
|
49
|
+
while (selectedIndex === -2) {
|
|
50
|
+
// Get custom instruction from user
|
|
51
|
+
customInstruction = await this.uiManager.promptForCustomInstruction();
|
|
52
|
+
|
|
53
|
+
// Regenerate suggestions with custom instruction
|
|
54
|
+
this.uiManager.newLine();
|
|
55
|
+
suggestions = await this.generateSuggestions(config, diff, customInstruction);
|
|
56
|
+
|
|
57
|
+
// Prompt again with new suggestions
|
|
58
|
+
selectedIndex = await this.uiManager.promptForCommitSelection(suggestions);
|
|
59
|
+
}
|
|
43
60
|
|
|
44
61
|
// Handle cancellation
|
|
45
62
|
if (selectedIndex === -1) {
|
|
@@ -47,10 +64,7 @@ export class MainOrchestrator {
|
|
|
47
64
|
return;
|
|
48
65
|
}
|
|
49
66
|
|
|
50
|
-
// Step 6:
|
|
51
|
-
await this.stageChangesIfNeeded(repository.rootPath, diff);
|
|
52
|
-
|
|
53
|
-
// Step 7: Execute commit
|
|
67
|
+
// Step 6: Execute commit (changes already staged)
|
|
54
68
|
const commitHash = await this.executeCommit(
|
|
55
69
|
repository.rootPath,
|
|
56
70
|
suggestions[selectedIndex].message
|
|
@@ -181,18 +195,19 @@ export class MainOrchestrator {
|
|
|
181
195
|
* Generate commit message suggestions using AI
|
|
182
196
|
* @param config Configuration with API key
|
|
183
197
|
* @param diff Git diff
|
|
198
|
+
* @param customInstruction Optional custom instruction for regeneration
|
|
184
199
|
* @returns Array of suggestions
|
|
185
200
|
*/
|
|
186
|
-
private async generateSuggestions(config: Config, diff: any) {
|
|
201
|
+
private async generateSuggestions(config: Config, diff: any, customInstruction?: string) {
|
|
187
202
|
this.uiManager.newLine();
|
|
188
203
|
this.uiManager.showSectionHeader('🤖 AI Generation');
|
|
189
|
-
this.uiManager.showAIGenerationInfo(config.model
|
|
204
|
+
this.uiManager.showAIGenerationInfo(config.model);
|
|
190
205
|
|
|
191
206
|
const spinner = this.uiManager.showLoading(' Generating commit messages...');
|
|
192
207
|
|
|
193
208
|
try {
|
|
194
209
|
const aiService = new AIService(config.apiKey, config.model);
|
|
195
|
-
const suggestions = await aiService.generateCommitMessages(diff,
|
|
210
|
+
const suggestions = await aiService.generateCommitMessages(diff, customInstruction);
|
|
196
211
|
|
|
197
212
|
spinner.succeed(` Generated ${suggestions.length} suggestions`);
|
|
198
213
|
this.uiManager.newLine();
|
|
@@ -205,22 +220,18 @@ export class MainOrchestrator {
|
|
|
205
220
|
}
|
|
206
221
|
|
|
207
222
|
/**
|
|
208
|
-
* Stage changes
|
|
223
|
+
* Stage all changes in the repository
|
|
209
224
|
* @param repoPath Repository root path
|
|
210
|
-
* @param diff Git diff
|
|
211
225
|
*/
|
|
212
|
-
private async
|
|
213
|
-
|
|
226
|
+
private async stageAllChanges(repoPath: string): Promise<void> {
|
|
227
|
+
const spinner = this.uiManager.showLoading('Staging all changes...');
|
|
228
|
+
try {
|
|
229
|
+
await this.gitService.stageAll(repoPath);
|
|
230
|
+
spinner.succeed('All changes staged');
|
|
214
231
|
this.uiManager.newLine();
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
spinner.succeed('Changes staged');
|
|
219
|
-
this.uiManager.newLine();
|
|
220
|
-
} catch (error) {
|
|
221
|
-
spinner.fail('Failed to stage changes');
|
|
222
|
-
throw error;
|
|
223
|
-
}
|
|
232
|
+
} catch (error) {
|
|
233
|
+
spinner.fail('Failed to stage changes');
|
|
234
|
+
throw error;
|
|
224
235
|
}
|
|
225
236
|
}
|
|
226
237
|
|
package/src/ui/UIManager.ts
CHANGED
|
@@ -241,14 +241,11 @@ export class UIManager {
|
|
|
241
241
|
/**
|
|
242
242
|
* Display AI generation info
|
|
243
243
|
* @param model Model name being used
|
|
244
|
-
* @param suggestionCount Number of suggestions generated
|
|
245
244
|
*/
|
|
246
|
-
showAIGenerationInfo(model: string
|
|
245
|
+
showAIGenerationInfo(model: string): void {
|
|
247
246
|
console.log(this.colors.muted(` 🤖 Model: ${chalk.cyan.bold(model)}`));
|
|
248
247
|
console.log(
|
|
249
|
-
this.colors.muted(
|
|
250
|
-
` 📝 Generating ${chalk.cyan.bold(suggestionCount)} commit message suggestions...`
|
|
251
|
-
)
|
|
248
|
+
this.colors.muted(` 📝 Generating ${chalk.cyan.bold(5)} commit message suggestions...`)
|
|
252
249
|
);
|
|
253
250
|
console.log();
|
|
254
251
|
}
|
|
@@ -291,7 +288,7 @@ export class UIManager {
|
|
|
291
288
|
name: 'model',
|
|
292
289
|
message: 'Select Gemini model:',
|
|
293
290
|
choices: models.map((model) => {
|
|
294
|
-
if (model === 'gemini-
|
|
291
|
+
if (model === 'gemini-3-flash-preview') {
|
|
295
292
|
return {
|
|
296
293
|
name: `${model} ${chalk.gray('(stable)')}`,
|
|
297
294
|
value: model,
|
|
@@ -359,6 +356,13 @@ export class UIManager {
|
|
|
359
356
|
};
|
|
360
357
|
});
|
|
361
358
|
|
|
359
|
+
// Add regenerate with prompt option
|
|
360
|
+
choices.push({
|
|
361
|
+
name: chalk.cyan('🔄 Regenerate with prompt'),
|
|
362
|
+
value: -2,
|
|
363
|
+
short: 'Regenerate',
|
|
364
|
+
});
|
|
365
|
+
|
|
362
366
|
// Add cancel option
|
|
363
367
|
choices.push({
|
|
364
368
|
name: chalk.red("✖ Cancel (don't commit)"),
|
|
@@ -377,8 +381,8 @@ export class UIManager {
|
|
|
377
381
|
},
|
|
378
382
|
]);
|
|
379
383
|
|
|
380
|
-
// Show preview of selected message if not cancelled
|
|
381
|
-
if (answer.selection !== -1) {
|
|
384
|
+
// Show preview of selected message if not cancelled and not regenerate
|
|
385
|
+
if (answer.selection !== -1 && answer.selection !== -2) {
|
|
382
386
|
this.newLine();
|
|
383
387
|
this.showSectionHeader('✅ Selected commit message');
|
|
384
388
|
console.log();
|
|
@@ -417,4 +421,26 @@ export class UIManager {
|
|
|
417
421
|
|
|
418
422
|
return answer.confirmed;
|
|
419
423
|
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Prompt user for custom instruction to regenerate commit messages
|
|
427
|
+
* @returns Custom instruction string or empty string if cancelled
|
|
428
|
+
*/
|
|
429
|
+
async promptForCustomInstruction(): Promise<string> {
|
|
430
|
+
const answer = await inquirer.prompt([
|
|
431
|
+
{
|
|
432
|
+
type: 'input',
|
|
433
|
+
name: 'instruction',
|
|
434
|
+
message: 'Enter your instruction for regenerating commit messages:',
|
|
435
|
+
validate: (input: string) => {
|
|
436
|
+
if (!input || input.trim().length === 0) {
|
|
437
|
+
return 'Instruction cannot be empty';
|
|
438
|
+
}
|
|
439
|
+
return true;
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
]);
|
|
443
|
+
|
|
444
|
+
return answer.instruction.trim();
|
|
445
|
+
}
|
|
420
446
|
}
|