gims 0.6.4 β 0.6.6
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 +29 -0
- package/README.md +1 -1
- package/bin/gims.js +83 -13
- package/bin/lib/ai/providers.js +10 -9
- package/package.json +1 -1
- package/QUICK_REFERENCE.md +0 -77
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.6] - 2025-10-26
|
|
4
|
+
|
|
5
|
+
### π§ Improvements
|
|
6
|
+
- **Removed commit message length restriction**: AI can now generate commit messages of any length (no more `...` truncation at 72 chars)
|
|
7
|
+
- **Added confirmation prompt for local heuristics**: When no AI provider is configured, the tool now asks for confirmation `[Y/n]` before committing
|
|
8
|
+
- Default is `Y` (just press Enter to accept)
|
|
9
|
+
- Warning message clearly indicates "local heuristics" instead of AI
|
|
10
|
+
- Can be bypassed with `--yes` flag for automation
|
|
11
|
+
- **Better user awareness**: Users are now informed when local heuristics are used instead of AI
|
|
12
|
+
|
|
13
|
+
### π User Experience
|
|
14
|
+
- More transparent about when AI is used vs. local pattern matching
|
|
15
|
+
- Safer commits when API keys are not configured
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [0.6.5] - 2025-10-20
|
|
20
|
+
|
|
21
|
+
### π§ Command Behavior Updated
|
|
22
|
+
- **`g a` (amend) default behavior changed**: Now keeps the original commit message by default (`--no-edit`)
|
|
23
|
+
- **New `--edit` flag**: Use `g a --edit` to generate a new AI commit message
|
|
24
|
+
- **Simpler workflow**: `g a` simply merges current changes into previous commit without editing the message
|
|
25
|
+
|
|
26
|
+
### π Documentation Updates
|
|
27
|
+
- Updated all documentation to reflect the new amend behavior
|
|
28
|
+
- Clarified that `g a` merges changes while keeping the original message
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
3
32
|
## [0.6.4] - 2025-10-19
|
|
4
33
|
|
|
5
34
|
### π§ Command Aliases Fixed
|
package/README.md
CHANGED
package/bin/gims.js
CHANGED
|
@@ -90,7 +90,31 @@ async function safeLog() {
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
async function generateCommitMessage(rawDiff, options = {}) {
|
|
93
|
-
|
|
93
|
+
const result = await aiProvider.generateCommitMessage(rawDiff, options);
|
|
94
|
+
// Return both message and whether local heuristics were used
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function confirmCommit(message, isLocalHeuristic) {
|
|
99
|
+
if (!isLocalHeuristic) return true; // No confirmation needed for AI-generated messages
|
|
100
|
+
|
|
101
|
+
const readline = require('readline');
|
|
102
|
+
const rl = readline.createInterface({
|
|
103
|
+
input: process.stdin,
|
|
104
|
+
output: process.stdout
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
console.log(color.yellow('\nβ οΈ No AI provider configured - using local heuristics'));
|
|
108
|
+
console.log(`Suggested commit: "${message}"`);
|
|
109
|
+
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
rl.question('Proceed with this commit? [Y/n]: ', (answer) => {
|
|
112
|
+
rl.close();
|
|
113
|
+
const trimmed = answer.trim().toLowerCase();
|
|
114
|
+
// Default to 'yes' if empty (just Enter pressed)
|
|
115
|
+
resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
94
118
|
}
|
|
95
119
|
|
|
96
120
|
async function resolveCommit(input) {
|
|
@@ -311,7 +335,7 @@ program.command('help-quick').alias('q')
|
|
|
311
335
|
console.log(` ${color.cyan('g ls')} List - Short commit history`);
|
|
312
336
|
console.log(` ${color.cyan('g ll')} Large List - Detailed commit history`);
|
|
313
337
|
console.log(` ${color.cyan('g h')} History - Alias for list`);
|
|
314
|
-
console.log(` ${color.cyan('g a')} Amend -
|
|
338
|
+
console.log(` ${color.cyan('g a')} Amend - Merge changes to previous commit (keeps message)`);
|
|
315
339
|
console.log(` ${color.cyan('g u')} Undo - Undo last commit\n`);
|
|
316
340
|
|
|
317
341
|
console.log(color.bold('Quick Setup:'));
|
|
@@ -392,11 +416,19 @@ program.command('suggest').alias('sg')
|
|
|
392
416
|
}
|
|
393
417
|
} else {
|
|
394
418
|
if (opts.progressIndicators) Progress.start('π€ Analyzing changes');
|
|
395
|
-
const
|
|
419
|
+
const result = await generateCommitMessage(rawDiff, opts);
|
|
396
420
|
if (opts.progressIndicators) Progress.stop('');
|
|
421
|
+
|
|
422
|
+
const msg = result.message || result; // Handle both old and new format
|
|
423
|
+
const usedLocal = result.usedLocal || false;
|
|
424
|
+
|
|
425
|
+
// Warn if using local heuristics
|
|
426
|
+
if (usedLocal) {
|
|
427
|
+
console.log(color.yellow('β οΈ No AI provider configured - using local heuristics'));
|
|
428
|
+
}
|
|
397
429
|
|
|
398
430
|
if (opts.json) {
|
|
399
|
-
const out = { message: msg };
|
|
431
|
+
const out = { message: msg, usedLocalHeuristics: usedLocal };
|
|
400
432
|
console.log(JSON.stringify(out));
|
|
401
433
|
return;
|
|
402
434
|
}
|
|
@@ -446,8 +478,11 @@ program.command('local').alias('l')
|
|
|
446
478
|
}
|
|
447
479
|
|
|
448
480
|
if (opts.progressIndicators) Progress.start('π€ Generating commit message');
|
|
449
|
-
const
|
|
481
|
+
const result = await generateCommitMessage(rawDiff, opts);
|
|
450
482
|
if (opts.progressIndicators) Progress.stop('');
|
|
483
|
+
|
|
484
|
+
const msg = result.message || result; // Handle both old and new format
|
|
485
|
+
const usedLocal = result.usedLocal || false;
|
|
451
486
|
|
|
452
487
|
if (opts.dryRun) {
|
|
453
488
|
console.log(color.yellow('[dry-run] Would commit with message:'));
|
|
@@ -455,6 +490,15 @@ program.command('local').alias('l')
|
|
|
455
490
|
return;
|
|
456
491
|
}
|
|
457
492
|
|
|
493
|
+
// Ask for confirmation if using local heuristics (unless --yes flag is set)
|
|
494
|
+
if (usedLocal && !opts.yes) {
|
|
495
|
+
const confirmed = await confirmCommit(msg, true);
|
|
496
|
+
if (!confirmed) {
|
|
497
|
+
Progress.info('Commit cancelled');
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
458
502
|
if (opts.amend) {
|
|
459
503
|
await git.raw(['commit', '--amend', '-m', msg]);
|
|
460
504
|
Progress.success(`Amended commit: "${msg}"`);
|
|
@@ -496,8 +540,11 @@ program.command('online').alias('o')
|
|
|
496
540
|
}
|
|
497
541
|
|
|
498
542
|
if (opts.progressIndicators) Progress.start('π€ Generating commit message');
|
|
499
|
-
const
|
|
543
|
+
const result = await generateCommitMessage(rawDiff, opts);
|
|
500
544
|
if (opts.progressIndicators) Progress.stop('');
|
|
545
|
+
|
|
546
|
+
const msg = result.message || result; // Handle both old and new format
|
|
547
|
+
const usedLocal = result.usedLocal || false;
|
|
501
548
|
|
|
502
549
|
if (opts.dryRun) {
|
|
503
550
|
console.log(color.yellow('[dry-run] Would commit & push with message:'));
|
|
@@ -505,6 +552,15 @@ program.command('online').alias('o')
|
|
|
505
552
|
return;
|
|
506
553
|
}
|
|
507
554
|
|
|
555
|
+
// Ask for confirmation if using local heuristics (unless --yes flag is set)
|
|
556
|
+
if (usedLocal && !opts.yes) {
|
|
557
|
+
const confirmed = await confirmCommit(msg, true);
|
|
558
|
+
if (!confirmed) {
|
|
559
|
+
Progress.info('Commit cancelled');
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
508
564
|
Progress.info('Committing changes...');
|
|
509
565
|
if (opts.amend) {
|
|
510
566
|
await git.raw(['commit', '--amend', '-m', msg]);
|
|
@@ -701,8 +757,8 @@ program.command('stash')
|
|
|
701
757
|
});
|
|
702
758
|
|
|
703
759
|
program.command('amend').alias('a')
|
|
704
|
-
.description('Stage all changes and amend last commit')
|
|
705
|
-
.option('--
|
|
760
|
+
.description('Stage all changes and amend last commit (keeps message)')
|
|
761
|
+
.option('--edit', 'Generate new AI commit message')
|
|
706
762
|
.action(async (cmdOptions) => {
|
|
707
763
|
await ensureRepo();
|
|
708
764
|
try {
|
|
@@ -721,17 +777,31 @@ program.command('amend').alias('a')
|
|
|
721
777
|
return;
|
|
722
778
|
}
|
|
723
779
|
|
|
724
|
-
if (cmdOptions.
|
|
725
|
-
await git.raw(['commit', '--amend', '--no-edit']);
|
|
726
|
-
Progress.success('Amended last commit with staged changes');
|
|
727
|
-
} else {
|
|
780
|
+
if (cmdOptions.edit) {
|
|
728
781
|
// Generate new message for amend
|
|
782
|
+
const opts = getOpts();
|
|
729
783
|
Progress.start('π€ Generating updated commit message');
|
|
730
|
-
const
|
|
784
|
+
const result = await generateCommitMessage(rawDiff, opts);
|
|
731
785
|
Progress.stop('');
|
|
732
786
|
|
|
787
|
+
const newMessage = result.message || result; // Handle both old and new format
|
|
788
|
+
const usedLocal = result.usedLocal || false;
|
|
789
|
+
|
|
790
|
+
// Ask for confirmation if using local heuristics (unless --yes flag is set)
|
|
791
|
+
if (usedLocal && !opts.yes) {
|
|
792
|
+
const confirmed = await confirmCommit(newMessage, true);
|
|
793
|
+
if (!confirmed) {
|
|
794
|
+
Progress.info('Amend cancelled');
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
733
799
|
await git.raw(['commit', '--amend', '-m', newMessage]);
|
|
734
800
|
Progress.success(`Amended commit: "${newMessage}"`);
|
|
801
|
+
} else {
|
|
802
|
+
// Default: Keep existing message (--no-edit)
|
|
803
|
+
await git.raw(['commit', '--amend', '--no-edit']);
|
|
804
|
+
Progress.success('Amended last commit with staged changes (kept original message)');
|
|
735
805
|
}
|
|
736
806
|
} catch (e) {
|
|
737
807
|
handleError('Amend error', e);
|
package/bin/lib/ai/providers.js
CHANGED
|
@@ -46,7 +46,7 @@ class AIProviderManager {
|
|
|
46
46
|
return this.cache.get(cacheKey);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
setCache(cacheKey, result) {
|
|
49
|
+
setCache(cacheKey, result, usedLocal = false) {
|
|
50
50
|
if (!this.config.cacheEnabled) return;
|
|
51
51
|
|
|
52
52
|
if (this.cache.size >= this.maxCacheSize) {
|
|
@@ -56,6 +56,7 @@ class AIProviderManager {
|
|
|
56
56
|
|
|
57
57
|
this.cache.set(cacheKey, {
|
|
58
58
|
result,
|
|
59
|
+
usedLocal,
|
|
59
60
|
timestamp: Date.now()
|
|
60
61
|
});
|
|
61
62
|
}
|
|
@@ -129,7 +130,7 @@ class AIProviderManager {
|
|
|
129
130
|
const cached = this.getFromCache(cacheKey);
|
|
130
131
|
if (cached && Date.now() - cached.timestamp < 3600000) { // 1 hour cache
|
|
131
132
|
if (verbose) Progress.info('Using cached result');
|
|
132
|
-
return cached.result;
|
|
133
|
+
return { message: cached.result, usedLocal: cached.usedLocal || false };
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
const providerChain = this.buildProviderChain(preferredProvider);
|
|
@@ -140,16 +141,16 @@ class AIProviderManager {
|
|
|
140
141
|
|
|
141
142
|
if (provider === 'local') {
|
|
142
143
|
const result = await this.generateLocalHeuristic(diff, options);
|
|
143
|
-
this.setCache(cacheKey, result);
|
|
144
|
-
return result;
|
|
144
|
+
this.setCache(cacheKey, result, true);
|
|
145
|
+
return { message: result, usedLocal: true };
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
const prompt = this.buildPrompt(diff, { conventional, body });
|
|
148
149
|
const result = await this.generateWithProvider(provider, prompt, options);
|
|
149
150
|
const cleaned = this.cleanCommitMessage(result, { body });
|
|
150
151
|
|
|
151
|
-
this.setCache(cacheKey, cleaned);
|
|
152
|
-
return cleaned;
|
|
152
|
+
this.setCache(cacheKey, cleaned, false);
|
|
153
|
+
return { message: cleaned, usedLocal: false };
|
|
153
154
|
|
|
154
155
|
} catch (error) {
|
|
155
156
|
if (verbose) Progress.warning(`${provider} failed: ${error.message}`);
|
|
@@ -159,8 +160,8 @@ class AIProviderManager {
|
|
|
159
160
|
|
|
160
161
|
// Final fallback
|
|
161
162
|
const fallback = 'Update project files';
|
|
162
|
-
this.setCache(cacheKey, fallback);
|
|
163
|
-
return fallback;
|
|
163
|
+
this.setCache(cacheKey, fallback, true);
|
|
164
|
+
return { message: fallback, usedLocal: true };
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
buildProviderChain(preferred) {
|
|
@@ -213,7 +214,7 @@ class AIProviderManager {
|
|
|
213
214
|
let subject = (lines[0] || '').replace(/\s{2,}/g, ' ').replace(/[\s:,.!;]+$/g, '').trim();
|
|
214
215
|
|
|
215
216
|
if (subject.length === 0) subject = 'Update project code';
|
|
216
|
-
|
|
217
|
+
// No length restriction - allow AI to generate full commit messages
|
|
217
218
|
|
|
218
219
|
if (!options.body) return subject;
|
|
219
220
|
|
package/package.json
CHANGED
package/QUICK_REFERENCE.md
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# π GIMS Quick Reference
|
|
2
|
-
|
|
3
|
-
## Single-Letter Workflow Commands
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
g s # Status - Enhanced git status with AI insights
|
|
7
|
-
g i # Init - Initialize a new Git repository
|
|
8
|
-
g p # Preview - See what will be committed
|
|
9
|
-
g l # Local - AI commit locally
|
|
10
|
-
g o # Online - AI commit + push
|
|
11
|
-
g ls # List - Short commit history
|
|
12
|
-
g ll # Large List - Detailed commit history
|
|
13
|
-
g h # History - Alias for list
|
|
14
|
-
g a # Amend - Smart amend with AI
|
|
15
|
-
g u # Undo - Undo last commit
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Quick Setup
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
# Choose your AI provider (one-time setup)
|
|
22
|
-
g setup --api-key gemini # π Recommended: Fast & free
|
|
23
|
-
g setup --api-key openai # π High quality
|
|
24
|
-
g setup --api-key groq # β‘ Ultra fast
|
|
25
|
-
|
|
26
|
-
# Or run full setup wizard
|
|
27
|
-
g setup
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Essential Workflow
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# 1. Check what's changed
|
|
34
|
-
g s
|
|
35
|
-
|
|
36
|
-
# 2. Commit with AI (choose one)
|
|
37
|
-
g int # Interactive mode (guided)
|
|
38
|
-
g o # One-command: commit + push
|
|
39
|
-
g l # Local commit only
|
|
40
|
-
|
|
41
|
-
# 3. View history
|
|
42
|
-
g ls # Recent commits (short)
|
|
43
|
-
g ll # Recent commits (detailed)
|
|
44
|
-
g h # Same as g ls
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Default AI Models
|
|
48
|
-
|
|
49
|
-
- **Gemini**: `gemini-2.5-flash` (Fast, free, recommended)
|
|
50
|
-
- **OpenAI**: `gpt-5` (Latest GPT model)
|
|
51
|
-
- **Groq**: `groq/compound` (Ultra-fast inference)
|
|
52
|
-
|
|
53
|
-
## Pro Tips
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
g sg --multiple # Get 3 AI suggestions
|
|
57
|
-
g p # Preview before committing
|
|
58
|
-
g a # Smart amend with new AI message
|
|
59
|
-
g sync --rebase # Smart sync with rebase
|
|
60
|
-
g stash # Stash with AI description
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Configuration
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
g config --list # View all settings
|
|
67
|
-
g config --set conventional=true # Enable conventional commits
|
|
68
|
-
g config --set autoStage=true # Auto-stage changes
|
|
69
|
-
g config --set provider=gemini # Set AI provider
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Help
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
g --help # All commands
|
|
76
|
-
g q # This quick reference
|
|
77
|
-
```
|