@untools/commitgen 0.0.5 → 0.1.1

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 ADDED
@@ -0,0 +1,333 @@
1
+ <!-- ./README.md -->
2
+
3
+ # @untools/commitgen
4
+
5
+ šŸš€ AI-powered commit message generator for Git with modular AI provider support.
6
+
7
+ ## Features
8
+
9
+ ✨ **AI-Powered Generation**: Leverages advanced AI models to analyze your git changes and generate meaningful commit messages
10
+
11
+ šŸŽÆ **Conventional Commits**: Follows the [Conventional Commits](https://www.conventionalcommits.org/) specification
12
+
13
+ šŸ”Œ **Modular Providers**: Support for multiple AI providers:
14
+
15
+ - āœ… Vercel AI SDK (Google Gemini)
16
+ - šŸ”œ Vercel AI SDK (OpenAI)
17
+ - šŸ”œ Groq
18
+ - šŸ”œ OpenAI Direct
19
+ - šŸ”œ Google Direct
20
+ - šŸ”œ Local LLMs (Ollama, LM Studio, etc.)
21
+
22
+ šŸŽØ **Beautiful CLI**: Colorized output with interactive prompts using Inquirer
23
+
24
+ šŸ“Š **Smart Analysis**: Analyzes file patterns, additions/deletions, and git diffs
25
+
26
+ ⚔ **Fast**: Efficient processing with fallback to rule-based suggestions
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ # Global installation (recommended)
32
+ npm install -g @untools/commitgen
33
+
34
+ # Or use with npx
35
+ npx @untools/commitgen
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ 1. **Stage your changes**:
41
+
42
+ ```bash
43
+ git add .
44
+ ```
45
+
46
+ 2. **Generate commit message**:
47
+
48
+ ```bash
49
+ commitgen
50
+ ```
51
+
52
+ That's it! If it's your first time, CommitGen will automatically prompt you to configure your API key. The tool will then analyze your changes and suggest commit messages.
53
+
54
+ ### First-Time Setup
55
+
56
+ When you run `commitgen` for the first time without an API key, you'll see:
57
+
58
+ ```
59
+ āš ļø API key not found for the selected provider.
60
+ ? Would you like to configure your API key now? (Y/n)
61
+ ```
62
+
63
+ Choose "Yes" to set up your configuration, or run `commitgen config` manually anytime.
64
+
65
+ ## Usage
66
+
67
+ ### Basic Commands
68
+
69
+ ```bash
70
+ # Generate commit message (interactive)
71
+ commitgen
72
+
73
+ # Commit and push in one command
74
+ commitgen --push
75
+
76
+ # Skip git hooks
77
+ commitgen --noverify
78
+
79
+ # Use rule-based suggestions (no AI)
80
+ commitgen --no-ai
81
+
82
+ # Configure AI provider
83
+ commitgen config
84
+
85
+ # Show help
86
+ commitgen --help
87
+
88
+ # Show version
89
+ commitgen --version
90
+ ```
91
+
92
+ ### Configuration
93
+
94
+ The configuration file is stored at `~/.commitgenrc.json`:
95
+
96
+ ```json
97
+ {
98
+ "provider": {
99
+ "provider": "vercel-google",
100
+ "model": "gemini-2.5-flash",
101
+ "apiKey": "optional-if-using-env-var"
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Environment Variables
107
+
108
+ You can use environment variables instead of storing API keys in the config:
109
+
110
+ ```bash
111
+ # For Google Gemini (via Vercel AI SDK)
112
+ export GOOGLE_GENERATIVE_AI_API_KEY="your-api-key"
113
+
114
+ # Then run without configuring
115
+ commitgen
116
+ ```
117
+
118
+ ## AI Providers
119
+
120
+ ### Vercel AI SDK - Google Gemini (Available Now)
121
+
122
+ Uses the [Vercel AI SDK](https://sdk.vercel.ai/) with Google's Gemini models.
123
+
124
+ **Setup:**
125
+
126
+ 1. Get a free API key from [Google AI Studio](https://aistudio.google.com/app/apikey)
127
+ 2. Run `commitgen config` and select "Vercel AI SDK - Google Gemini"
128
+ 3. Enter your API key or set `GOOGLE_GENERATIVE_AI_API_KEY` environment variable
129
+
130
+ **Available Models:**
131
+
132
+ - `gemini-2.5-flash` (Recommended - Fast and efficient)
133
+ - `gemini-2.5-pro` (More capable, higher quality)
134
+ - `gemini-1.5-flash`
135
+ - `gemini-1.5-pro`
136
+
137
+ ### Coming Soon
138
+
139
+ - **Vercel AI SDK - OpenAI**: GPT-4o, GPT-4o-mini
140
+ - **Groq**: Ultra-fast inference with Llama models
141
+ - **OpenAI Direct**: Direct OpenAI API integration
142
+ - **Google Direct**: Direct Google Generative AI integration
143
+ - **Local LLMs**: Ollama, LM Studio, LocalAI support
144
+
145
+ ## How It Works
146
+
147
+ 1. **Analysis**: Scans your staged git changes
148
+
149
+ - File patterns (tests, docs, configs, components)
150
+ - Addition/deletion statistics
151
+ - Git diff content
152
+
153
+ 2. **AI Generation**: Sends analysis to your configured AI provider
154
+
155
+ - Uses a specialized prompt for commit message generation
156
+ - Follows Conventional Commits specification
157
+ - Returns 3-5 contextual suggestions
158
+
159
+ 3. **Selection**: Interactive prompt to choose or customize
160
+
161
+ - Select from AI-generated suggestions
162
+ - Write a custom message
163
+ - Confirm before committing
164
+
165
+ 4. **Commit**: Executes git commit with your chosen message
166
+ - Optional: Push to remote with `--push` flag
167
+ - Optional: Skip hooks with `--noverify` flag
168
+
169
+ ## Examples
170
+
171
+ ### Typical Workflow
172
+
173
+ ```bash
174
+ # Make some changes
175
+ vim src/components/Button.tsx
176
+
177
+ # Stage changes
178
+ git add src/components/Button.tsx
179
+
180
+ # Generate and commit
181
+ commitgen
182
+ ```
183
+
184
+ Output:
185
+
186
+ ```
187
+ šŸš€ CommitGen - AI-Powered Commit Message Generator
188
+
189
+ šŸ“Š Analysis:
190
+ Files changed: 1
191
+ Additions: +45
192
+ Deletions: -12
193
+
194
+ šŸ“ Changed files:
195
+ āš›ļø src/components/Button.tsx
196
+
197
+ šŸ¤– Generating commit messages using vercel-google...
198
+
199
+ šŸ’” Suggested commit messages:
200
+
201
+ 1. feat(components): add variant prop to Button component
202
+ 2. feat(Button): implement new button styles and variants
203
+ 3. refactor(components): restructure Button component props
204
+ 4. style(Button): update button styling system
205
+ āœļø Write custom message
206
+
207
+ ? Choose a commit message: (Use arrow keys)
208
+ ```
209
+
210
+ ### Configuration Example
211
+
212
+ ```bash
213
+ $ commitgen config
214
+
215
+ āš™ļø Configure CommitGen
216
+
217
+ ? Select AI provider: Vercel AI SDK - Google Gemini
218
+ ? Enter your Google AI API key: **********************
219
+ ? Select model: Gemini 2.5 Flash (Fast, Recommended)
220
+
221
+ āœ… Configuration saved successfully!
222
+ Config file: /Users/you/.commitgenrc.json
223
+ ```
224
+
225
+ ## Commit Message Format
226
+
227
+ Generated messages follow the Conventional Commits specification:
228
+
229
+ ```
230
+ <type>(<scope>): <subject>
231
+
232
+ <body>
233
+
234
+ <footer>
235
+ ```
236
+
237
+ **Types:**
238
+
239
+ - `feat`: New feature
240
+ - `fix`: Bug fix
241
+ - `docs`: Documentation changes
242
+ - `style`: Code style changes
243
+ - `refactor`: Code refactoring
244
+ - `perf`: Performance improvements
245
+ - `test`: Test updates
246
+ - `build`: Build system changes
247
+ - `ci`: CI/CD changes
248
+ - `chore`: Maintenance tasks
249
+ - `revert`: Revert previous commit
250
+
251
+ **Example:**
252
+
253
+ ```
254
+ feat(auth): add OAuth2 authentication
255
+
256
+ Implemented OAuth2 flow with Google and GitHub providers.
257
+ Added JWT token management and refresh logic.
258
+
259
+ BREAKING CHANGE: Authentication API has changed
260
+ ```
261
+
262
+ ## Troubleshooting
263
+
264
+ ### "No staged changes found"
265
+
266
+ Make sure you've staged your changes:
267
+
268
+ ```bash
269
+ git add <files>
270
+ # or
271
+ git add .
272
+ ```
273
+
274
+ ### "API key is required"
275
+
276
+ Set your API key either:
277
+
278
+ 1. Run `commitgen config` to save it in config file
279
+ 2. Set environment variable: `export GOOGLE_GENERATIVE_AI_API_KEY="your-key"`
280
+
281
+ ### AI generation fails
282
+
283
+ The tool will automatically fall back to rule-based suggestions if AI generation fails. You can also force rule-based mode with `--no-ai`.
284
+
285
+ ## Development
286
+
287
+ ```bash
288
+ # Clone the repository
289
+ git clone https://github.com/aevrHQ/untools-commitgen.git
290
+ cd untools-commitgen
291
+
292
+ # Install dependencies
293
+ npm install
294
+
295
+ # Build
296
+ npm run build
297
+
298
+ # Link for local testing
299
+ npm link
300
+
301
+ # Run
302
+ commitgen
303
+ ```
304
+
305
+ ## Dependencies
306
+
307
+ ```json
308
+ {
309
+ "@ai-sdk/google": "^1.x.x",
310
+ "ai": "^4.x.x",
311
+ "chalk": "^4.1.2",
312
+ "commander": "^13.1.0",
313
+ "inquirer": "^12.5.2"
314
+ }
315
+ ```
316
+
317
+ ## Contributing
318
+
319
+ Contributions are welcome! Please feel free to submit a Pull Request.
320
+
321
+ ## License
322
+
323
+ MIT Ā© Miracle Onyenma
324
+
325
+ ## Links
326
+
327
+ - [GitHub Repository](https://github.com/aevrHQ/untools-commitgen)
328
+ - [npm Package](https://www.npmjs.com/package/@untools/commitgen)
329
+ - [Issue Tracker](https://github.com/aevrHQ/untools-commitgen/issues)
330
+
331
+ ---
332
+
333
+ Made with ā¤ļø by [Miracle Onyenma](https://github.com/miracleonyenma)
@@ -0,0 +1 @@
1
+ export declare function configureCommand(): Promise<void>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ // ./src/commands/configure.ts
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.configureCommand = configureCommand;
8
+ const inquirer_1 = __importDefault(require("inquirer"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const config_1 = require("../config");
11
+ async function configureCommand() {
12
+ console.log(chalk_1.default.cyan.bold("\nāš™ļø Configure CommitGen\n"));
13
+ const configManager = new config_1.ConfigManager();
14
+ const currentConfig = configManager.getProviderConfig();
15
+ // Show current configuration if it exists
16
+ if (currentConfig.provider) {
17
+ console.log(chalk_1.default.gray("Current configuration:"));
18
+ console.log(chalk_1.default.gray(` Provider: ${currentConfig.provider}`));
19
+ console.log(chalk_1.default.gray(` Model: ${currentConfig.model || "default"}`));
20
+ console.log(chalk_1.default.gray(` API Key: ${currentConfig.apiKey ? "***configured***" : "not set"}`));
21
+ console.log();
22
+ }
23
+ const { provider } = await inquirer_1.default.prompt([
24
+ {
25
+ type: "list",
26
+ name: "provider",
27
+ message: "Select AI provider:",
28
+ choices: [
29
+ { name: "Vercel AI SDK - Google Gemini", value: "vercel-google" },
30
+ {
31
+ name: "Vercel AI SDK - OpenAI (Coming Soon)",
32
+ value: "vercel-openai",
33
+ disabled: true,
34
+ },
35
+ { name: "Groq (Coming Soon)", value: "groq", disabled: true },
36
+ {
37
+ name: "OpenAI Direct (Coming Soon)",
38
+ value: "openai",
39
+ disabled: true,
40
+ },
41
+ {
42
+ name: "Google Direct (Coming Soon)",
43
+ value: "google",
44
+ disabled: true,
45
+ },
46
+ { name: "Local LLM (Coming Soon)", value: "local", disabled: true },
47
+ ],
48
+ default: currentConfig.provider || "vercel-google",
49
+ },
50
+ ]);
51
+ let config = { provider };
52
+ // Provider-specific configuration
53
+ if (provider === "vercel-google") {
54
+ const hasEnvKey = !!process.env.GOOGLE_GENERATIVE_AI_API_KEY;
55
+ const { apiKey, model } = await inquirer_1.default.prompt([
56
+ {
57
+ type: "password",
58
+ name: "apiKey",
59
+ message: hasEnvKey
60
+ ? "Enter your Google AI API key (or press Enter to use GOOGLE_GENERATIVE_AI_API_KEY env var):"
61
+ : "Enter your Google AI API key (get one at https://aistudio.google.com/app/apikey):",
62
+ mask: "*",
63
+ validate: (input) => {
64
+ if (!input.trim() && !hasEnvKey) {
65
+ return "API key is required. Get one at https://aistudio.google.com/app/apikey";
66
+ }
67
+ return true;
68
+ },
69
+ default: currentConfig.provider === provider
70
+ ? currentConfig.apiKey
71
+ : undefined,
72
+ },
73
+ {
74
+ type: "list",
75
+ name: "model",
76
+ message: "Select model:",
77
+ choices: [
78
+ {
79
+ name: "Gemini 2.5 Flash (Fast, Recommended)",
80
+ value: "gemini-2.5-flash",
81
+ },
82
+ { name: "Gemini 2.5 Pro (More Capable)", value: "gemini-2.5-pro" },
83
+ { name: "Gemini 1.5 Flash", value: "gemini-1.5-flash" },
84
+ { name: "Gemini 1.5 Pro", value: "gemini-1.5-pro" },
85
+ ],
86
+ default: currentConfig.model || "gemini-2.5-flash",
87
+ },
88
+ ]);
89
+ config.apiKey = apiKey || undefined;
90
+ config.model = model;
91
+ }
92
+ configManager.setProvider(config);
93
+ console.log(chalk_1.default.green("\nāœ… Configuration saved successfully!"));
94
+ console.log(chalk_1.default.gray(`Config file: ${require("os").homedir()}/.commitgenrc.json`));
95
+ }
96
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/commands/configure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { ProviderConfig } from "./types";
2
+ interface CommitGenConfig {
3
+ provider?: ProviderConfig;
4
+ defaultProvider?: "vercel-google" | "vercel-openai" | "groq" | "openai" | "google" | "local";
5
+ }
6
+ export declare class ConfigManager {
7
+ private configPath;
8
+ private config;
9
+ constructor();
10
+ private loadConfig;
11
+ saveConfig(config: CommitGenConfig): void;
12
+ getProviderConfig(): ProviderConfig;
13
+ setProvider(config: ProviderConfig): void;
14
+ }
15
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ // ./src/config.ts
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ConfigManager = void 0;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const os_1 = __importDefault(require("os"));
11
+ class ConfigManager {
12
+ constructor() {
13
+ this.configPath = path_1.default.join(os_1.default.homedir(), ".commitgenrc.json");
14
+ this.config = this.loadConfig();
15
+ }
16
+ loadConfig() {
17
+ try {
18
+ if (fs_1.default.existsSync(this.configPath)) {
19
+ const content = fs_1.default.readFileSync(this.configPath, "utf8");
20
+ return JSON.parse(content);
21
+ }
22
+ }
23
+ catch (error) {
24
+ console.warn("Failed to load config file:", error);
25
+ }
26
+ return {};
27
+ }
28
+ saveConfig(config) {
29
+ try {
30
+ fs_1.default.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf8");
31
+ this.config = config;
32
+ }
33
+ catch (error) {
34
+ console.error("Failed to save config:", error);
35
+ }
36
+ }
37
+ getProviderConfig() {
38
+ if (this.config.provider) {
39
+ return this.config.provider;
40
+ }
41
+ // Default to vercel-google
42
+ return {
43
+ provider: this.config.defaultProvider || "vercel-google",
44
+ apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY,
45
+ model: "gemini-2.5-flash",
46
+ };
47
+ }
48
+ setProvider(config) {
49
+ this.saveConfig({
50
+ ...this.config,
51
+ provider: config,
52
+ });
53
+ }
54
+ }
55
+ exports.ConfigManager = ConfigManager;
56
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA,kBAAkB;;;;;;AAElB,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAcpB,MAAa,aAAa;IAIxB;QACE,IAAI,CAAC,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IAClC,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC;YACH,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,UAAU,CAAC,MAAuB;QAChC,IAAI,CAAC;YACH,YAAE,CAAC,aAAa,CACd,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,iBAAiB;QACf,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC9B,CAAC;QAED,2BAA2B;QAC3B,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,eAAe;YACxD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;YAChD,KAAK,EAAE,kBAAkB;SAC1B,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,MAAsB;QAChC,IAAI,CAAC,UAAU,CAAC;YACd,GAAG,IAAI,CAAC,MAAM;YACd,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;IACL,CAAC;CACF;AArDD,sCAqDC"}