Fix Gemini API, increase OpenAI temperature, and bug fixes
This commit is contained in:
+48
@@ -0,0 +1,48 @@
|
|||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Lock files
|
||||||
|
package-lock.json
|
||||||
|
bun.lock
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
GIMS (Git Made Simple) is an AI-powered Git CLI tool that automatically generates meaningful commit messages from code changes. It's a Node.js package published to npm that integrates with OpenAI GPT-4 and Google Gemini APIs.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- **Single-file CLI**: All functionality is contained in `bin/gims.js`
|
||||||
|
- **AI Integration**: Supports both OpenAI and Google Gemini APIs with intelligent fallback strategies
|
||||||
|
- **Git Wrapper**: Built on top of `simple-git` library for Git operations
|
||||||
|
- **Token Management**: Implements sophisticated content chunking to handle large diffs within AI token limits
|
||||||
|
|
||||||
|
## Key Components
|
||||||
|
|
||||||
|
- **Command System**: Uses `commander.js` for CLI argument parsing with aliases (e.g., `g o` for `gims online`)
|
||||||
|
- **AI Message Generation**: Multi-strategy approach that falls back from full diff → summary → status → truncated content
|
||||||
|
- **Commit Resolution**: Supports both commit hashes and numbered indices for referencing commits
|
||||||
|
- **Safe Operations**: Includes error handling for empty repositories and edge cases
|
||||||
|
|
||||||
|
## Environment Setup
|
||||||
|
|
||||||
|
Required environment variables (at least one):
|
||||||
|
- `OPENAI_API_KEY` - For OpenAI GPT-4o-mini integration
|
||||||
|
- `GEMINI_API_KEY` - For Google Gemini 2.0 Flash integration
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
- **Install globally**: `npm install -g .`
|
||||||
|
- **Test locally**: `node bin/gims.js --help`
|
||||||
|
- **Test specific command**: `node bin/gims.js suggest`
|
||||||
|
- **Run with alias**: `g o` (after global install)
|
||||||
|
|
||||||
|
## Development Notes
|
||||||
|
|
||||||
|
- No test framework is currently configured (package.json shows placeholder test script)
|
||||||
|
- Node.js version requirement: >=20.0.0
|
||||||
|
- Uses CommonJS modules (`require`/`module.exports`)
|
||||||
|
- Dependencies are minimal and focused on core functionality
|
||||||
|
- Token estimation uses 4 characters per token approximation
|
||||||
|
- Maximum context limit set conservatively at 100,000 tokens
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
[](https://npmjs.org/package/gims)
|
[](https://npmjs.org/package/gims)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://nodejs.org/)
|
[](https://nodejs.org/)
|
||||||
[](https://github.com/yourusername/gims)
|
[](https://github.com/s41r4j/gims)
|
||||||
|
|
||||||
**The AI-powered Git CLI that writes your commit messages for you**
|
**The AI-powered Git CLI that writes your commit messages for you**
|
||||||
|
|
||||||
@@ -34,10 +34,10 @@ g o # AI analyzes changes, commits with perfect message, and pushes!
|
|||||||
## 🌟 Features
|
## 🌟 Features
|
||||||
|
|
||||||
### 🤖 **AI-Powered Commit Messages**
|
### 🤖 **AI-Powered Commit Messages**
|
||||||
- **OpenAI GPT-4** integration for intelligent commit message generation
|
- **OpenAI GPT-4o-mini** integration for intelligent commit message generation
|
||||||
- **Google Gemini** support for lightning-fast analysis
|
- **Google Gemini 2.0 Flash** support for lightning-fast analysis
|
||||||
- Smart diff analysis that understands your code changes
|
- Smart diff analysis that understands your code changes
|
||||||
- Handles large codebases with intelligent summarization
|
- Handles large codebases with intelligent summarization and token management
|
||||||
|
|
||||||
### ⚡ **Lightning Fast Workflow**
|
### ⚡ **Lightning Fast Workflow**
|
||||||
- **One command commits**: `g o` - analyze, commit, and push in seconds
|
- **One command commits**: `g o` - analyze, commit, and push in seconds
|
||||||
@@ -95,6 +95,7 @@ g o
|
|||||||
| `gims init` | `g i` | Initialize new Git repo | `g i` |
|
| `gims init` | `g i` | Initialize new Git repo | `g i` |
|
||||||
| `gims clone <repo>` | `g c` | Clone repository | `g c https://github.com/user/repo` |
|
| `gims clone <repo>` | `g c` | Clone repository | `g c https://github.com/user/repo` |
|
||||||
| `gims suggest` | `g s` | Generate & copy commit message | `g s` |
|
| `gims suggest` | `g s` | Generate & copy commit message | `g s` |
|
||||||
|
| `gims commit` | `g cm` | Interactive commit message generation | `g cm` |
|
||||||
| `gims local` | `g l` | AI commit locally | `g l` |
|
| `gims local` | `g l` | AI commit locally | `g l` |
|
||||||
| `gims online` | `g o` | AI commit + push | `g o` |
|
| `gims online` | `g o` | AI commit + push | `g o` |
|
||||||
| `gims pull` | `g p` | Pull latest changes | `g p` |
|
| `gims pull` | `g p` | Pull latest changes | `g p` |
|
||||||
@@ -144,7 +145,7 @@ g p # Pull latest changes
|
|||||||
g s # Preview AI suggestion
|
g s # Preview AI suggestion
|
||||||
g l # Commit locally first
|
g l # Commit locally first
|
||||||
# ... test your changes ...
|
# ... test your changes ...
|
||||||
g push # Push when ready
|
g o # Push with AI commit message
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🧠 **Smart Branching**
|
### 🧠 **Smart Branching**
|
||||||
@@ -180,6 +181,7 @@ GIMS handles edge cases gracefully:
|
|||||||
- **📊 Massive changes**: Falls back to status-based analysis
|
- **📊 Massive changes**: Falls back to status-based analysis
|
||||||
- **🛜 No API key**: Uses sensible default messages
|
- **🛜 No API key**: Uses sensible default messages
|
||||||
- **⚠️ API failures**: Graceful degradation with helpful errors
|
- **⚠️ API failures**: Graceful degradation with helpful errors
|
||||||
|
- **🪙 Token limits**: Intelligent content chunking with 100K token limit
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
@@ -194,8 +196,8 @@ We love contributions! Here's how to get involved:
|
|||||||
|
|
||||||
### 🐛 Found a Bug?
|
### 🐛 Found a Bug?
|
||||||
|
|
||||||
1. Check [existing issues](https://github.com/yourusername/gims/issues)
|
1. Check [existing issues](https://github.com/s41r4j/gims/issues)
|
||||||
2. Create a [new issue](https://github.com/yourusername/gims/issues/new) with:
|
2. Create a [new issue](https://github.com/s41r4j/gims/issues/new) with:
|
||||||
- Clear description
|
- Clear description
|
||||||
- Steps to reproduce
|
- Steps to reproduce
|
||||||
- Expected vs actual behavior
|
- Expected vs actual behavior
|
||||||
@@ -248,7 +250,7 @@ MIT © [GIMS](https://github.com/s41r4j/gims)
|
|||||||
|
|
||||||
**⭐ Star this repo if GIMS makes your Git workflow awesome!**
|
**⭐ Star this repo if GIMS makes your Git workflow awesome!**
|
||||||
|
|
||||||
[Report Bug](https://github.com/yourusername/gims/issues) • [Request Feature](https://github.com/yourusername/gims/issues) • [Documentation](https://github.com/yourusername/gims/wiki)
|
[Report Bug](https://github.com/s41r4j/gims/issues) • [Request Feature](https://github.com/s41r4j/gims/issues) • [Documentation](https://github.com/s41r4j/gims#readme)
|
||||||
|
|
||||||
*Made with ❤️ by developers who hate writing commit messages*
|
*Made with ❤️ by developers who hate writing commit messages*
|
||||||
|
|
||||||
|
|||||||
+98
-15
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
const { Command } = require('commander');
|
const { Command } = require('commander');
|
||||||
const simpleGit = require('simple-git');
|
const simpleGit = require('simple-git');
|
||||||
const clipboard = require('clipboardy');
|
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
const { OpenAI } = require('openai');
|
const { OpenAI } = require('openai');
|
||||||
const { GoogleGenAI } = require('@google/genai');
|
const { GoogleGenAI } = require('@google/genai');
|
||||||
@@ -116,6 +115,11 @@ async function generateCommitMessage(rawDiff) {
|
|||||||
return 'Update multiple files';
|
return 'Update multiple files';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if API key is available
|
||||||
|
if (!process.env.GEMINI_API_KEY && !process.env.OPENAI_API_KEY) {
|
||||||
|
return null; // Signal that no API key is available
|
||||||
|
}
|
||||||
|
|
||||||
let message = 'Update project code'; // Default fallback
|
let message = 'Update project code'; // Default fallback
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -125,13 +129,13 @@ async function generateCommitMessage(rawDiff) {
|
|||||||
model: 'gemini-2.0-flash',
|
model: 'gemini-2.0-flash',
|
||||||
contents: prompt
|
contents: prompt
|
||||||
});
|
});
|
||||||
message = (await res.response.text()).trim();
|
message = res.text.trim();
|
||||||
} else if (process.env.OPENAI_API_KEY) {
|
} else if (process.env.OPENAI_API_KEY) {
|
||||||
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
||||||
const res = await openai.chat.completions.create({
|
const res = await openai.chat.completions.create({
|
||||||
model: 'gpt-4o-mini',
|
model: 'gpt-4o-mini',
|
||||||
messages: [{ role: 'user', content: prompt }],
|
messages: [{ role: 'user', content: prompt }],
|
||||||
temperature: 0.5,
|
temperature: 0.75,
|
||||||
max_tokens: 100 // Limit response length
|
max_tokens: 100 // Limit response length
|
||||||
});
|
});
|
||||||
message = res.choices[0].message.content.trim();
|
message = res.choices[0].message.content.trim();
|
||||||
@@ -176,7 +180,7 @@ program.command('clone <repo>').alias('c')
|
|||||||
});
|
});
|
||||||
|
|
||||||
program.command('suggest').alias('s')
|
program.command('suggest').alias('s')
|
||||||
.description('Suggest commit message and copy to clipboard')
|
.description('Suggest commit message')
|
||||||
.action(async () => {
|
.action(async () => {
|
||||||
if (!(await hasChanges())) {
|
if (!(await hasChanges())) {
|
||||||
return console.log('No changes to suggest.');
|
return console.log('No changes to suggest.');
|
||||||
@@ -185,23 +189,92 @@ program.command('suggest').alias('s')
|
|||||||
const { all } = await safeLog();
|
const { all } = await safeLog();
|
||||||
const isFirst = all.length === 0;
|
const isFirst = all.length === 0;
|
||||||
|
|
||||||
// Always add changes first
|
// Get diff of unstaged changes
|
||||||
await git.add('.');
|
let rawDiff = await git.diff();
|
||||||
|
|
||||||
// Get the appropriate diff
|
|
||||||
const rawDiff = await git.diff(['--cached']);
|
|
||||||
|
|
||||||
|
// If no diff from tracked files, check for untracked files
|
||||||
if (!rawDiff.trim()) {
|
if (!rawDiff.trim()) {
|
||||||
return console.log('No changes to suggest.');
|
const status = await git.status();
|
||||||
|
if (status.not_added.length > 0) {
|
||||||
|
// For untracked files, show file list since we can't diff them
|
||||||
|
rawDiff = `New files:\n${status.not_added.join('\n')}`;
|
||||||
|
} else {
|
||||||
|
return console.log('No changes to suggest.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = await generateCommitMessage(rawDiff);
|
const msg = await generateCommitMessage(rawDiff);
|
||||||
|
|
||||||
try {
|
if (msg === null) {
|
||||||
clipboard.writeSync(msg);
|
return console.log('Please set GEMINI_API_KEY or OPENAI_API_KEY environment variable');
|
||||||
console.log(`Suggested: "${msg}" (copied to clipboard)`);
|
}
|
||||||
} catch (error) {
|
|
||||||
console.log(`Suggested: "${msg}" (clipboard copy failed)`);
|
console.log(`git add . && git commit -m "${msg}"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
program.command('commit').alias('cm')
|
||||||
|
.description('Interactive commit message generation')
|
||||||
|
.action(async () => {
|
||||||
|
if (!(await hasChanges())) {
|
||||||
|
return console.log('No changes to commit.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get diff for message generation
|
||||||
|
let rawDiff = await git.diff();
|
||||||
|
|
||||||
|
// If no diff from tracked files, check for untracked files
|
||||||
|
if (!rawDiff.trim()) {
|
||||||
|
const status = await git.status();
|
||||||
|
if (status.not_added.length > 0) {
|
||||||
|
rawDiff = `New files:\n${status.not_added.join('\n')}`;
|
||||||
|
} else {
|
||||||
|
return console.log('No changes to commit.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!process.env.GEMINI_API_KEY && !process.env.OPENAI_API_KEY) {
|
||||||
|
return console.log('Please set GEMINI_API_KEY or OPENAI_API_KEY environment variable');
|
||||||
|
}
|
||||||
|
|
||||||
|
const readline = require('readline');
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
const askForInput = () => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
rl.question('> ', (answer) => {
|
||||||
|
resolve(answer.toLowerCase().trim());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentMessage = await generateCommitMessage(rawDiff);
|
||||||
|
console.log(`\n=== Interactive Commit ===`);
|
||||||
|
console.log(`┌──────────────────────────────────────────────────────────────────────┐`);
|
||||||
|
console.log(`│ Press "Enter" to generate new message, "c" to commit, or "q" to quit │`);
|
||||||
|
console.log(`└──────────────────────────────────────────────────────────────────────┘\n`);
|
||||||
|
console.log(`Suggested: "${currentMessage}"`);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const input = await askForInput();
|
||||||
|
|
||||||
|
if (input === 'q' || input === 'quit') {
|
||||||
|
console.log('Cancelled.');
|
||||||
|
rl.close();
|
||||||
|
return;
|
||||||
|
} else if (input === 'c' || input === 'commit') {
|
||||||
|
await git.add('.');
|
||||||
|
await git.commit(currentMessage);
|
||||||
|
console.log(`Committed: "${currentMessage}"`);
|
||||||
|
rl.close();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Generate new message
|
||||||
|
currentMessage = await generateCommitMessage(rawDiff);
|
||||||
|
console.log(`Suggested: "${currentMessage}"`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -226,6 +299,11 @@ program.command('local').alias('l')
|
|||||||
}
|
}
|
||||||
|
|
||||||
const msg = await generateCommitMessage(rawDiff);
|
const msg = await generateCommitMessage(rawDiff);
|
||||||
|
|
||||||
|
if (msg === null) {
|
||||||
|
return console.log('Please set GEMINI_API_KEY or OPENAI_API_KEY environment variable');
|
||||||
|
}
|
||||||
|
|
||||||
await git.commit(msg);
|
await git.commit(msg);
|
||||||
console.log(`Committed locally: "${msg}"`);
|
console.log(`Committed locally: "${msg}"`);
|
||||||
});
|
});
|
||||||
@@ -251,6 +329,11 @@ program.command('online').alias('o')
|
|||||||
}
|
}
|
||||||
|
|
||||||
const msg = await generateCommitMessage(rawDiff);
|
const msg = await generateCommitMessage(rawDiff);
|
||||||
|
|
||||||
|
if (msg === null) {
|
||||||
|
return console.log('Please set GEMINI_API_KEY or OPENAI_API_KEY environment variable');
|
||||||
|
}
|
||||||
|
|
||||||
await git.commit(msg);
|
await git.commit(msg);
|
||||||
await git.push();
|
await git.push();
|
||||||
console.log(`Committed & pushed: "${msg}"`);
|
console.log(`Committed & pushed: "${msg}"`);
|
||||||
|
|||||||
Reference in New Issue
Block a user