git-aic 1.0.0 → 1.1.0

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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Spectra
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,269 @@
1
+ # Git Aic
2
+
3
+ **git-aic** is a command-line interface (CLI) tool built in TypeScript that upgrades your Git workflow by automatically generating high-quality, conventional commit messages.
4
+
5
+ Powered by Google Gemini, it analyzes your staged code changes and produces concise, descriptive, and standard-compliant commit messages, helping you maintain a clean and consistent Git history.
6
+
7
+ You define the rules.
8
+ You customize the system prompt.
9
+ You decide when it runs.
10
+
11
+ Your workflow. Your control.
12
+
13
+ ## Features
14
+
15
+ - **AI-Powered Message Generation**
16
+ Uses Google Gemini API to generate commit messages from your Git diff.
17
+
18
+ - **Self-Hosted & On-Demand**
19
+ Runs locally in your terminal. No background processes. No editor lock-in.
20
+
21
+ - **Full Control Over Rules**
22
+ Modify the system prompt to enforce your own commit conventions and formatting style.
23
+
24
+ - **Conventional Commits Compliance**
25
+ Strictly follows formats like `feat:`, `fix:`, `refactor:`, `chore:`.
26
+
27
+ - **Commit Confirmation & Editing**
28
+ Before committing, you can:
29
+ - Accept the suggested commit message
30
+ - Edit the message
31
+ - Reject it
32
+ - Retry generation
33
+
34
+ - **Issue Linking**
35
+ Attach commits to GitHub issues with `--issue <number>`.
36
+
37
+ - **Optional Push After Commit**
38
+ Use `-p` or `--push` to push after committing.
39
+
40
+ - **Config Management**
41
+ Set your Gemini API key or view your config:
42
+ - `git aic config --key <key>`
43
+ - `git aic config`
44
+
45
+ - **TypeScript & Type Safety**
46
+ Built with TypeScript for maintainability and reliability.
47
+
48
+ - **Seamless Git Integration**
49
+ Directly integrates with Git using a CLI.
50
+
51
+ ## Why Not Just Use Copilot?
52
+
53
+ Many AI commit tools:
54
+
55
+ - Depend on editor integrations
56
+ - Limit customization
57
+ - Enforce their defaults
58
+ - Restrict usage
59
+ - Run continuously in the background
60
+
61
+ This tool is different.
62
+
63
+ It runs only when you call it.
64
+ It follows your prompt rules.
65
+ It generates commits exactly how you define them.
66
+ It stays out of your way.
67
+
68
+ There are no forced conventions.
69
+ No hidden behavior.
70
+ No unnecessary background processes.
71
+
72
+ If needed, you can rotate API keys later. You stay in control.
73
+
74
+ This is controlled automation — not passive AI assistance.
75
+
76
+ ## User Installation
77
+
78
+ To install `git-aic` globally via npm:
79
+
80
+ ```bash
81
+ npm i -g git-aic
82
+ ```
83
+
84
+ ```bash
85
+ git aic --help
86
+ ```
87
+
88
+ ## Developer Installation (For Contributors)
89
+
90
+ ### 1. Clone the Repository
91
+
92
+ ```bash
93
+ git clone https://github.com/Spectra010s/git-aic.git
94
+ cd git-aic
95
+ ```
96
+
97
+ ### 2. Install Dependencies
98
+
99
+ ```bash
100
+ npm install
101
+ ```
102
+
103
+ ### 3. Build the Project
104
+
105
+ ```bash
106
+ npm run build
107
+ ```
108
+
109
+ ## Configuration
110
+
111
+ ### Set API Key (Primary)
112
+
113
+ Use the CLI config command to save your Google Gemini API key:
114
+
115
+ ```bash
116
+ git aic config --key <your_api_key>
117
+ ```
118
+
119
+ To view your current config:
120
+
121
+ ```bash
122
+ git aic config
123
+ ```
124
+
125
+ > "\*Note:\*\* it's masked by default for security reasons
126
+
127
+ To view the whole current config api key
128
+
129
+ ```bash
130
+ git aic config --show
131
+ ```
132
+
133
+ ### Environment Variable (Fallback)
134
+
135
+ If you prefer not to use the config system, you can set it manually in your environment:
136
+
137
+ - **macOS / Linux:**
138
+
139
+ ```bash
140
+ export GEMINI_COMMIT_MESSAGE_API_KEY=your_api_key_here
141
+ ```
142
+
143
+ - **Windows (PowerShell):**
144
+
145
+ ```powershell
146
+ setx GEMINI_COMMIT_MESSAGE_API_KEY "your_api_key_here"
147
+ ```
148
+
149
+ After setting the variable, restart your terminal.
150
+
151
+ > **Note:** This method works, but using the CLI config is safer and easier for long-term usage.
152
+
153
+ ## Usage
154
+
155
+ ### Commit With AI Assistance
156
+
157
+ ```bash
158
+ git aic
159
+ ```
160
+
161
+ - Prompts you with a generated commit message.
162
+ - You can **accept, edit, reject, or retry** the message.
163
+
164
+ ### Commit and Link to Issue
165
+
166
+ ```bash
167
+ git aic --issue 123
168
+ ```
169
+
170
+ - Attaches the commit to GitHub issue #123.
171
+
172
+ ### Commit and Push
173
+
174
+ ```bash
175
+ git aic -p
176
+ ```
177
+
178
+ - Pushes automatically after committing.
179
+
180
+ ### Configure API Key
181
+
182
+ ```bash
183
+ git aic config --key <key>
184
+ ```
185
+
186
+ - Saves your Google Gemini API key.
187
+
188
+ ```bash
189
+ git aic config
190
+ ```
191
+
192
+ - Displays your saved config.
193
+
194
+ That’s it.
195
+
196
+ No need to manually write commit messages anymore.
197
+
198
+ ## How It Works
199
+
200
+ 1. Captures your staged Git diff
201
+ 2. Builds a strict system prompt
202
+ 3. Sends the diff to Gemini
203
+ 4. Enforces Conventional Commit formatting
204
+ 5. Prompts for commit confirmation (accept, edit, retry, reject)
205
+ 6. Executes `git commit` automatically
206
+ 7. Optionally pushes if `-p` flag is used
207
+
208
+ You can modify commit behavior by editing:
209
+
210
+ ```
211
+ src/prompt.ts
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Technologies Used
217
+
218
+ | Technology | Purpose |
219
+ | ----------------- | ---------------------- |
220
+ | TypeScript | Core language |
221
+ | Node.js | Runtime |
222
+ | Axios | HTTP client |
223
+ | Chalk | Styled terminal output |
224
+ | Commander.js | CLI framework |
225
+ | Simple-Git | Git integration |
226
+ | Google Gemini API | LLM text generation |
227
+
228
+ ## Final Takeaway
229
+
230
+ Automating repetitive tasks like **commit messages** saves time — but the real win here is ownership.
231
+
232
+ git-aic:
233
+
234
+ - **Self-hosted** — runs entirely on your machine
235
+ - **On-demand** — only runs when you call it
236
+ - **Fully customizable** — prompts, commit format, workflow
237
+ - **Under your control** — you decide every step
238
+
239
+ It runs when you need it, follows your rules, and generates commits the way **you** want.
240
+
241
+ _Choose your model. Define your prompt. Control the format. Extend or optimize anytime._
242
+
243
+ Instead of adapting to someone else's defaults, _you built a system tailored to your workflow._
244
+
245
+ You are not just using AI tools.
246
+ You are **building them to fit your process.**
247
+
248
+ ## License
249
+
250
+ [**ISC License**](https://github.com/Spectra010s/git-aic/main/#license)
251
+
252
+ ## Author
253
+
254
+ Spectra010s
255
+
256
+ - [Twitter](https://x.com/Spectra010s)
257
+ - [LinkedIn](https://www.linkedin.com/in/adeloye-adetayo-273723253)
258
+
259
+ ## Parent Repository
260
+
261
+ This project is a fork and standalone version of:
262
+
263
+ [https://github.com/samueltuoyo15/Commit-Message-Tool](https://github.com/samueltuoyo15/Commit-Message-Tool)
264
+
265
+ ---
266
+
267
+ ![License](https://img.shields.io/badge/License-ISC-blue.svg)
268
+ ![TypeScript](https://img.shields.io/badge/Language-TypeScript-blue?style=flat&logo=typescript&logoColor=white)
269
+ ![Node.js](https://img.shields.io/badge/Runtime-Node.js-green?style=flat&logo=nodedotjs&logoColor=white)
package/dist/cli.js CHANGED
@@ -5,13 +5,45 @@ import chalk from "chalk";
5
5
  import { getGitDiff } from "./git.js";
6
6
  import { generateCommitMessage } from "./llm.js";
7
7
  import { getUserConfirmation } from "./confirm.js";
8
+ import { getConfig, setApiKey } from "./config.js";
9
+ process.on("SIGINT", () => {
10
+ process.exit(0);
11
+ });
8
12
  const git = simpleGit();
9
13
  const program = new Command();
10
14
  program
11
- .name("commit")
15
+ .name("git aic")
12
16
  .description("AI-powered Git commit generator using Google Gemini")
13
17
  .version("1.0.0")
14
- .option("-p, --push", "push after committing");
18
+ .option("-p, --push", "push after committing")
19
+ .option("-i, --issue <number>", "Link commit to GitHub issue");
20
+ program
21
+ .command("config")
22
+ .description("Configure the Gemini API Key settings")
23
+ .option("-k, --key <key>", "Set your Gemini API Key")
24
+ .option("--show", "Show the full API key")
25
+ .action(async (options) => {
26
+ const cfg = await getConfig();
27
+ if (options.key) {
28
+ await setApiKey(options.key);
29
+ console.log(chalk.green("API Key saved successfully!"));
30
+ return;
31
+ }
32
+ if (cfg.apiKey) {
33
+ if (options.show) {
34
+ console.log(chalk.green("Current API Key:"), cfg.apiKey);
35
+ }
36
+ else {
37
+ const styled = cfg.apiKey.slice(0, 4) +
38
+ chalk.dim("*".repeat(cfg.apiKey.length - 8)) +
39
+ cfg.apiKey.slice(-4);
40
+ console.log(chalk.green("Current API Key:"), styled);
41
+ }
42
+ }
43
+ else {
44
+ console.log(chalk.yellow("No API key set"));
45
+ }
46
+ });
15
47
  program.action(async (options) => {
16
48
  try {
17
49
  const diff = await getGitDiff();
@@ -23,17 +55,20 @@ program.action(async (options) => {
23
55
  console.log(chalk.blue("\nFiles being committed:"));
24
56
  status.staged.forEach((file) => console.log(chalk.cyan(`- ${file}`)));
25
57
  console.log("");
26
- let currentMessage = "";
58
+ let currentMsg = "";
27
59
  let confirmed = false;
60
+ let finalMsg = "";
61
+ const issueSuffix = options.issue ? `, closes #${options.issue}` : "";
28
62
  console.log(chalk.blue("Analyzing staged changes...\n"));
29
63
  while (!confirmed) {
30
- currentMessage = await generateCommitMessage(diff);
31
- const { choice, message } = await getUserConfirmation(currentMessage);
32
- if (choice === 'y') {
33
- currentMessage = message;
64
+ let currentMsg = await generateCommitMessage(diff);
65
+ currentMsg = `${currentMsg}${issueSuffix}`;
66
+ const { choice, message } = await getUserConfirmation(currentMsg);
67
+ if (choice === "y") {
68
+ finalMsg = message;
34
69
  confirmed = true;
35
70
  }
36
- else if (choice === 'r') {
71
+ else if (choice === "r") {
37
72
  console.log(chalk.yellow("Regenerating...\n"));
38
73
  continue;
39
74
  }
@@ -42,8 +77,8 @@ program.action(async (options) => {
42
77
  process.exit(0);
43
78
  }
44
79
  }
45
- console.log(chalk.blue(`> ran: git commit -m "${currentMessage}"`));
46
- await git.commit(currentMessage);
80
+ console.log(chalk.blue(`> ran: git commit -m "${finalMsg}"`));
81
+ await git.commit(finalMsg);
47
82
  console.log(chalk.green("\nCommit successful"));
48
83
  if (options.push) {
49
84
  console.log(chalk.blue("> ran: git push"));
@@ -52,8 +87,14 @@ program.action(async (options) => {
52
87
  }
53
88
  }
54
89
  catch (error) {
55
- console.error(chalk.red("\nCommit failed:"), error);
56
- process.exit(1);
90
+ let isAbort = false;
91
+ if (typeof error === "object" && error !== null && "code" in error) {
92
+ const e = error;
93
+ isAbort = e.code === "ABORT_ERR";
94
+ }
95
+ const msg = isAbort ? "Operation cancelled" : error;
96
+ console.error(chalk.red("\n\nCommit failed:"), msg);
97
+ process.exit(isAbort ? 0 : 1);
57
98
  }
58
99
  });
59
100
  program.parse(process.argv);
package/dist/config.js ADDED
@@ -0,0 +1,41 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import os from "os";
4
+ import chalk from "chalk";
5
+ function getConfigPath() {
6
+ const toolName = "git-aic";
7
+ if (process.platform === "win32") {
8
+ const appData = process.env.APPDATA;
9
+ if (!appData)
10
+ throw new Error("APPDATA not defined");
11
+ return path.join(appData, toolName, "config.json");
12
+ }
13
+ else {
14
+ const configDir = path.join(os.homedir(), ".config", toolName);
15
+ return path.join(configDir, "config.json");
16
+ }
17
+ }
18
+ export async function getConfig() {
19
+ const configPath = getConfigPath();
20
+ try {
21
+ const content = await fs.readFile(configPath, "utf-8");
22
+ return JSON.parse(content);
23
+ }
24
+ catch (err) {
25
+ if (err.code === "ENOENT")
26
+ return {};
27
+ console.error(chalk.red("Failed to read config:"), err.message);
28
+ return {};
29
+ }
30
+ }
31
+ export async function saveConfig(data) {
32
+ const configPath = getConfigPath();
33
+ const dir = path.dirname(configPath);
34
+ await fs.mkdir(dir, { recursive: true });
35
+ const current = await getConfig();
36
+ const newConfig = { ...current, ...data };
37
+ await fs.writeFile(configPath, JSON.stringify(newConfig, null, 2), "utf-8");
38
+ }
39
+ export async function setApiKey(key) {
40
+ await saveConfig({ apiKey: key });
41
+ }
package/dist/confirm.js CHANGED
@@ -6,20 +6,26 @@ export const getUserConfirmation = async (message) => {
6
6
  output: process.stdout,
7
7
  });
8
8
  console.log(chalk.green(`\nProposed: "${message}"`));
9
- const answer = await rl.question(chalk.blue('Confirm commit? [y=yes, n=no, r=retry, e=edit]: '));
9
+ const answer = await rl.question(chalk.blue("Confirm commit? [y=yes, n=no, r=retry, e=edit]: "));
10
10
  rl.close();
11
- const choice = (answer.toLowerCase() || 'y').trim();
12
- if (choice === 'e') {
11
+ const choice = (answer.toLowerCase() || "y").trim();
12
+ if (choice === "e") {
13
13
  const editRl = readline.createInterface({
14
14
  input: process.stdin,
15
15
  output: process.stdout,
16
- terminal: true
16
+ terminal: true,
17
17
  });
18
18
  console.log(chalk.cyan("\nEdit the message:"));
19
19
  editRl.write(message);
20
- const editedMessage = await editRl.question("> ");
20
+ let editedMessage = "";
21
+ while (!editedMessage.trim()) {
22
+ editedMessage = await editRl.question("> ");
23
+ if (!editedMessage.trim()) {
24
+ console.log(chalk.red("Commit message cannot be empty. Please type something."));
25
+ }
26
+ }
21
27
  editRl.close();
22
- return { choice: 'y', message: editedMessage };
28
+ return { choice: "y", message: editedMessage };
23
29
  }
24
30
  return { choice, message };
25
31
  };
package/dist/llm.js CHANGED
@@ -1,18 +1,21 @@
1
1
  import axios from "axios";
2
2
  import chalk from "chalk";
3
3
  import { buildPrompt } from "./prompt.js";
4
+ import { getConfig } from "./config.js";
4
5
  export const generateCommitMessage = async (rawDiff) => {
5
6
  const API_URL = "https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent";
6
- const API_KEY = process.env.GEMINI_COMMIT_MESSAGE_API_KEY;
7
+ const config = await getConfig();
8
+ const API_KEY = config.apiKey || process.env.GEMINI_COMMIT_MESSAGE_API_KEY;
7
9
  if (!API_KEY) {
8
10
  console.error(chalk.red("\nMissing GEMINI_COMMIT_MESSAGE_API_KEY environment variable.\n"));
9
11
  console.log("Please set your API key before running this command.\n");
10
12
  console.log(chalk.yellow("How to fix this:\n"));
11
- console.log(chalk.cyan("macOS / Linux:"));
13
+ console.log(chalk.gray("Recommended: use the config helper to save it permanently:\n git-aic config --key <your_api_key>\n"));
14
+ console.log(chalk.cyan("macOS / Linux (temporary):"));
12
15
  console.log(" export GEMINI_COMMIT_MESSAGE_API_KEY=your_api_key_here\n");
13
- console.log(chalk.cyan("Windows (PowerShell):"));
16
+ console.log(chalk.cyan("Windows (PowerShell, temporary):"));
14
17
  console.log(' setx GEMINI_COMMIT_MESSAGE_API_KEY "your_api_key_here"\n');
15
- console.log(chalk.gray("After setting the variable, restart your terminal.\n"));
18
+ console.log(chalk.gray("After setting the key, restart your terminal.\n"));
16
19
  process.exit(1);
17
20
  }
18
21
  const prompt = buildPrompt(rawDiff);
package/dist/prompt.js CHANGED
@@ -1,44 +1,44 @@
1
- export const buildPrompt = (diff) => `
2
- CRITICAL INSTRUCTIONS - READ CAREFULLY:
3
- You are an expert Git commit message writer. You MUST follow ALL these rules:
4
-
5
- 1. FORMAT: Use Conventional Commits format: <type>(<scope>): <description>
6
- - type: MUST be one of: feat, fix, refactor, chore, docs, style, test, perf
7
- - scope: Should be the module/file affected (e.g., "auth", "api", "ui", "config")
8
- - description: Clear, imperative description in present tense
9
-
10
- 2. DESCRIPTION REQUIREMENTS:
11
- - Start with an imperative verb (add, fix, remove, update, refactor, etc.)
12
- - Be specific about what changed
13
- - Keep it under 72 characters total (including type and scope)
14
- - NO trailing punctuation
15
- - NO emojis ever
16
- - MUST be a complete sentence
17
-
18
- 3. MESSAGE STRUCTURE:
19
- - The entire commit message must be exactly one line
20
- - Format: type(scope): description
21
- - Example: "feat(auth): add password reset functionality"
22
- - Example: "fix(api): handle null response in user endpoint"
23
- - Example: "refactor(ui): simplify component state management"
24
-
25
- 4. QUALITY CHECKS - YOUR OUTPUT MUST PASS:
26
- - Contains opening and closing parentheses
27
- - Has a colon after the parentheses
28
- - Description exists and is not empty
29
- - Total length ≤ 72 characters
30
- - No markdown formatting
31
- - No code blocks
32
- - No explanations or notes
33
-
34
- 5. FAILURE MODE:
35
- - If you cannot generate a proper message, return exactly: "chore: update code"
36
-
37
- YOUR TASK:
38
- Analyze this git diff and generate exactly ONE proper commit message following all rules above.
39
-
40
- Git diff:
41
- ${diff}
42
-
43
- Commit message:
1
+ export const buildPrompt = (diff) => `
2
+ CRITICAL INSTRUCTIONS - READ CAREFULLY:
3
+ You are an expert Git commit message writer. You MUST follow ALL these rules:
4
+
5
+ 1. FORMAT: Use Conventional Commits format: <type>(<scope>): <description>
6
+ - type: MUST be one of: feat, fix, refactor, chore, docs, style, test, perf
7
+ - scope: Should be the module/file affected (e.g., "auth", "api", "ui", "config")
8
+ - description: Clear, imperative description in present tense
9
+
10
+ 2. DESCRIPTION REQUIREMENTS:
11
+ - Start with an imperative verb (add, fix, remove, update, refactor, etc.)
12
+ - Be specific about what changed
13
+ - Keep it under 72 characters total (including type and scope)
14
+ - NO trailing punctuation
15
+ - NO emojis ever
16
+ - MUST be a complete sentence
17
+
18
+ 3. MESSAGE STRUCTURE:
19
+ - The entire commit message must be exactly one line
20
+ - Format: type(scope): description
21
+ - Example: "feat(auth): add password reset functionality"
22
+ - Example: "fix(api): handle null response in user endpoint"
23
+ - Example: "refactor(ui): simplify component state management"
24
+
25
+ 4. QUALITY CHECKS - YOUR OUTPUT MUST PASS:
26
+ - Contains opening and closing parentheses
27
+ - Has a colon after the parentheses
28
+ - Description exists and is not empty
29
+ - Total length ≤ 72 characters
30
+ - No markdown formatting
31
+ - No code blocks
32
+ - No explanations or notes
33
+
34
+ 5. FAILURE MODE:
35
+ - If you cannot generate a proper message, return exactly: "chore: update code"
36
+
37
+ YOUR TASK:
38
+ Analyze this git diff and generate exactly ONE proper commit message following all rules above.
39
+
40
+ Git diff:
41
+ ${diff}
42
+
43
+ Commit message:
44
44
  `.trim();
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "git-aic",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "AI-powered Git commit generator using Google Gemini",
5
- "homepage": "https://github.com/samueltuoyo15/Commit-Message-Tool/tree/#readme",
5
+ "homepage": "https://github.com/Spectra010s/git-aic",
6
6
  "bugs": {
7
- "url": "https://github.com/samueltuoyo15/Commit-Message-Tool/issues"
7
+ "url": "https://github.com/Spectra010s/git-aic/issues"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/samueltuoyo15/Commit-Message-Tool.git"
11
+ "url": "git+https://github.com/Spectra010s/git-aic.git"
12
12
  },
13
13
  "license": "ISC",
14
14
  "author": "Spectra010s",
@@ -17,9 +17,6 @@
17
17
  "bin": {
18
18
  "git-aic": "./dist/cli.js"
19
19
  },
20
- "files": [
21
- "dist"
22
- ],
23
20
  "scripts": {
24
21
  "build": "tsc",
25
22
  "prepare": "npm run build"
package/t.txt ADDED
@@ -0,0 +1,32 @@
1
+ # Git Aic v1.1.0
2
+
3
+ ## Highlights
4
+ - Fully standalone CLI — removed dependency on the original form network.
5
+ - AI-powered commit message generation with Google Gemini.
6
+ - Commit confirmation now gracefully exits if canceled.
7
+ - Empty commit messages are prevented during editing in confirmation prompt.
8
+ - `--issue` option added to link commits to GitHub issues.
9
+ - Flattened project structure for cleaner code organization.
10
+ - Axios errors for LLM requests are now handled properly to avoid crashes.
11
+ - CLI config system for managing your API key.
12
+ - Environment variable fallback supported.
13
+ - README updated with full usage, installation, and features.
14
+
15
+ ## Improvements
16
+ - TypeScript & type-safe implementation.
17
+ - Improved user experience — prompts only run when called.
18
+ - Conventional commit compliance enforced.
19
+ - Clear separation between developer install (contributors) and user install (global npm).
20
+
21
+ ## Notes
22
+ - Editable prompt system is not yet included — planned for v1.2.0.
23
+ - Users can now run `git aic` globally via npm.
24
+
25
+ ## What's Changed
26
+ • refactor(project): flatten project structure and update config by @Spectra010s in https://github.com/Spectra010s/git-aic/pull/1
27
+ • feat(cli): add --issue option to link commit to an issue, closes #3 by @Spectra010s in https://github.com/Spectra010s/git-aic/pull/4
28
+ • prevent empty commit message when editing in confirmation prompt by @Spectra010s in https://github.com/Spectra010s/git-aic/pull/6
29
+ • fix(cli): handle graceful process exit on cancellation, closes #7 by @Spectra010s in https://github.com/Spectra010s/git-aic/pull/8
30
+ • fix(llm): handle Axios errors for LLM requests by @Spectra010s in https://github.com/Spectra010s/git-aic/pull/10
31
+
32
+ Full Changelog: https://github.com/Spectra010s/git-aic/commits/v1.1.0