xoegit 1.1.1 → 1.1.3

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 CHANGED
@@ -6,6 +6,8 @@
6
6
  [![npm](https://img.shields.io/npm/v/xoegit?color=cb3837&logo=npm&logoColor=white)](https://www.npmjs.com/package/xoegit)
7
7
  [![License](https://img.shields.io/badge/License-MIT-green)](https://github.com/ujangdoubleday/xoegit/blob/main/LICENSE.md)
8
8
 
9
+ <img src="docs/xoegit-banner.png" alt="xoegit banner" width="100%">
10
+
9
11
  **xoegit** is an AI-powered CLI tool that generates concise, semantic, and atomic git commit messages and PR descriptions. It analyzes your `git diff`, `git status`, and `git log` to provide context-aware suggestions powered by Google's Gemini models.
10
12
 
11
13
  > **Philosophy:** "Craft, Don't Code" — `xoegit` suggests commands; YOU execute them. You stay in control.
@@ -18,11 +20,17 @@
18
20
  - **Semantic Commits** — Strictly follows [Conventional Commits](https://www.conventionalcommits.org/)
19
21
  - **PR Ready** — Generates ready-to-use PR title and description
20
22
 
23
+ ## How It Works
24
+
25
+ > **Important:** `xoegit` **never** stages your files, commits your changes, or modifies your repository in any way. It only analyzes your changes and provides recommendations that you can review and execute yourself.
26
+
27
+ You remain in full control of your git workflow.
28
+
21
29
  ## Installation
22
30
 
23
31
  ### Prerequisites
24
32
 
25
- - **Node.js**: Version 20.19.5 or higher
33
+ - **Node.js**: Minimum version 20.19.5 or higher
26
34
  - **Git**: Must be installed and available in your PATH
27
35
  - **API Key**: A Google Gemini API key ([get one here](https://aistudio.google.com/))
28
36
 
@@ -44,10 +52,12 @@ make
44
52
 
45
53
  Simply run `xoegit` for the first time. It will prompt you for your API Key securely and save it locally.
46
54
 
47
- > **Security Note:** Your API key is stored locally on your device only. We do not collect, store, or have access to your API key.
55
+ > **Security Note:** Your API key is stored locally on your device only. We do not collect, store, or have access to your API key. See [Security Policy](SECURITY.md) for details.
48
56
 
49
57
  ## Usage
50
58
 
59
+ Then, from whatever project you're working on, just run:
60
+
51
61
  ```bash
52
62
  xoegit
53
63
  ```
@@ -60,21 +70,40 @@ xoegit
60
70
  | ---------------------- | --------------------------------------------- |
61
71
  | `-k, --api-key <key>` | Use specific API key for this session |
62
72
  | `-c, --context <text>` | Provide context for more accurate suggestions |
73
+ | `-s, --set-key <key>` | Save API key to config
74
+ | `-d, --delete-key` | Delete saved API key from config |
63
75
  | `-V, --version` | Show version |
64
76
  | `-h, --help` | Show help |
65
77
 
66
78
  ### Examples
67
79
 
80
+ **Basic usage:**
81
+
68
82
  ```bash
69
- # Basic usage
70
83
  xoegit
84
+ ```
71
85
 
72
- # With context for better commit type detection
86
+ **With context for better commit type detection:**
87
+
88
+ ```bash
73
89
  xoegit --context "refactoring folder structure"
74
90
  xoegit -c "fixing authentication bug"
75
91
  xoegit -c "adding new payment feature"
76
92
  ```
77
93
 
94
+ **Use API key for this session only (not saved):**
95
+
96
+ ```bash
97
+ xoegit --api-key "YOUR_GEMINI_API_KEY"
98
+ ```
99
+
100
+ **Manage API key:**
101
+
102
+ ```bash
103
+ xoegit --set-key "YOUR_GEMINI_API_KEY"
104
+ xoegit --delete-key
105
+ ```
106
+
78
107
  ### Sample Output
79
108
 
80
109
  ```
@@ -96,18 +125,6 @@ pr description: feat(auth): implement secure login
96
125
  - refactor(utils): improve error logging
97
126
  ```
98
127
 
99
- ## Smart Model Fallback
100
-
101
- xoegit uses multiple Gemini models with automatic fallback:
102
-
103
- | Model | Priority |
104
- | ----------------------- | ------------- |
105
- | `gemini-2.5-flash-lite` | 1st (default) |
106
- | `gemini-2.5-flash` | 2nd |
107
- | `gemini-3-flash` | 3rd |
108
-
109
- When one model hits its rate limit, xoegit automatically tries the next one.
110
-
111
128
  ## Troubleshooting
112
129
 
113
130
  ### "Current directory is not a git repository"
@@ -129,9 +146,12 @@ npm run build
129
146
 
130
147
  # Run tests
131
148
  npm test
149
+ ```
132
150
 
133
- # Watch mode for tests
134
- npm run test:watch
151
+ **or** use `make`:
152
+
153
+ ```bash
154
+ make
135
155
  ```
136
156
 
137
157
  ## Project Structure
@@ -16,6 +16,22 @@ export async function analyzeAction() {
16
16
  const options = program.opts();
17
17
  let apiKey = options.apiKey;
18
18
  const configService = new ConfigService();
19
+ // Handle --set-key flag (save and exit)
20
+ if (options.setKey) {
21
+ if (!isValidApiKey(options.setKey)) {
22
+ showError('Invalid API Key', 'Please provide a valid API key.');
23
+ process.exit(1);
24
+ }
25
+ await configService.saveApiKey(options.setKey);
26
+ showSuccess('API Key saved successfully!');
27
+ return;
28
+ }
29
+ // Handle --delete-key flag (delete and exit)
30
+ if (options.deleteKey) {
31
+ await configService.deleteApiKey();
32
+ showSuccess('API Key deleted successfully!');
33
+ return;
34
+ }
19
35
  if (!apiKey) {
20
36
  apiKey = await configService.getApiKey();
21
37
  }
@@ -1,8 +1,11 @@
1
1
  import { Command } from 'commander';
2
+ import { VERSION } from '../config/version.js';
2
3
  export const program = new Command();
3
4
  program
4
5
  .name('xoegit')
5
6
  .description('AI-powered git commit generator')
6
- .version('0.1.0')
7
+ .version(VERSION)
7
8
  .option('-k, --api-key <key>', 'Gemini API Key')
8
- .option('-c, --context <context>', 'Context for the changes (e.g., "refactoring folder structure")');
9
+ .option('-c, --context <context>', 'Context for the changes (e.g., "refactoring folder structure")')
10
+ .option('-s, --set-key <key>', 'Save Gemini API Key to config (overwrites existing)')
11
+ .option('-d, --delete-key', 'Delete saved API Key from config');
@@ -44,4 +44,24 @@ export class ConfigService {
44
44
  throw new Error(`Failed to save configuration: ${error.message}`);
45
45
  }
46
46
  }
47
+ async deleteApiKey() {
48
+ try {
49
+ const configStr = await fs.readFile(this.configPath, 'utf-8');
50
+ const config = JSON.parse(configStr);
51
+ delete config.XOEGIT_GEMINI_API_KEY;
52
+ if (Object.keys(config).length === 0) {
53
+ // Delete the file if no other config remains
54
+ await fs.unlink(this.configPath);
55
+ }
56
+ else {
57
+ await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
58
+ }
59
+ }
60
+ catch (error) {
61
+ // Ignore if file doesn't exist
62
+ if (error.code !== 'ENOENT') {
63
+ throw new Error(`Failed to delete API key: ${error.message}`);
64
+ }
65
+ }
66
+ }
47
67
  }
@@ -0,0 +1,4 @@
1
+ import { createRequire } from 'module';
2
+ const require = createRequire(import.meta.url);
3
+ const pkg = require('../../package.json');
4
+ export const VERSION = pkg.version;
package/dist/utils/ui.js CHANGED
@@ -16,7 +16,16 @@ const brand = {
16
16
  * App banner
17
17
  */
18
18
  export function showBanner() {
19
- console.log(`\n${brand.primary('⚡')} ${brand.secondary.bold('xoegit')} ${brand.muted('— AI-powered commit generator')}\n`);
19
+ const banner = `
20
+ ██╗ ██╗ ██╗ ██████╗ ███████╗ ██████╗ ██╗████████╗
21
+ ╚██╗ ╚██╗██╔╝██╔═══██╗██╔════╝██╔════╝ ██║╚══██╔══╝
22
+ ╚██╗ ╚███╔╝ ██║ ██║█████╗ ██║ ███╗██║ ██║
23
+ ██╔╝ ██╔██╗ ██║ ██║██╔══╝ ██║ ██║██║ ██║
24
+ ██╔╝ ██╔╝ ██╗╚██████╔╝███████╗╚██████╔╝██║ ██║
25
+ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝
26
+ `;
27
+ console.log(banner);
28
+ console.log(brand.muted('by https://github.com/ujangdoubleday\n'));
20
29
  }
21
30
  /**
22
31
  * Display the AI suggestion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xoegit",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "AI-powered CLI tool for generating semantic git commit messages and PR descriptions",
5
5
  "license": "MIT",
6
6
  "author": "ujangdoubleday",