@dongowu/git-ai-cli 1.0.4 → 1.0.7
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 +134 -117
- package/dist/cli.js +54 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/commit.d.ts +1 -0
- package/dist/commands/commit.d.ts.map +1 -1
- package/dist/commands/commit.js +45 -20
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +178 -42
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/msg.d.ts +18 -0
- package/dist/commands/msg.d.ts.map +1 -0
- package/dist/commands/msg.js +100 -0
- package/dist/commands/msg.js.map +1 -0
- package/dist/utils/ai.d.ts.map +1 -1
- package/dist/utils/ai.js +2 -0
- package/dist/utils/ai.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,50 +17,83 @@
|
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="#-快速开始">快速开始</a> •
|
|
20
|
-
<a href="
|
|
20
|
+
<a href="#-使用方式">使用方式</a> •
|
|
21
21
|
<a href="#-支持的模型">支持的模型</a> •
|
|
22
22
|
<a href="#english">English</a>
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## 🚀 快速开始
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
📁 Staged files:
|
|
34
|
-
src/utils/ai.ts
|
|
35
|
-
src/commands/commit.ts
|
|
36
|
-
|
|
37
|
-
✨ Generated commit message:
|
|
30
|
+
# 1. 安装
|
|
31
|
+
npm install -g @dongowu/git-ai-cli
|
|
38
32
|
|
|
39
|
-
|
|
33
|
+
# 2. 配置 (选择 AI 服务商,输入 API Key)
|
|
34
|
+
git-ai config
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
🔄 Regenerate
|
|
45
|
-
❌ Cancel
|
|
36
|
+
# 3. 使用
|
|
37
|
+
git add .
|
|
38
|
+
git-ai
|
|
46
39
|
```
|
|
47
40
|
|
|
48
41
|
---
|
|
49
42
|
|
|
50
|
-
##
|
|
43
|
+
## 📖 使用方式
|
|
44
|
+
|
|
45
|
+
### 方式一:手动调用(推荐新手)
|
|
51
46
|
|
|
52
47
|
```bash
|
|
53
|
-
#
|
|
54
|
-
|
|
48
|
+
git add . # 暂存更改
|
|
49
|
+
git-ai # 生成消息 → 选择操作 → 提交
|
|
50
|
+
```
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
**交互选项:**
|
|
53
|
+
- 🚀 Commit - 使用生成的消息提交
|
|
54
|
+
- 📝 Edit - 编辑后提交
|
|
55
|
+
- 🔄 Regenerate - 重新生成
|
|
56
|
+
- ❌ Cancel - 取消
|
|
57
|
+
|
|
58
|
+
### 方式二:Git Hook 集成(推荐老手)
|
|
59
|
+
|
|
60
|
+
安装后,`git commit` 会自动生成消息,无需手动运行 `git-ai`:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 一次性安装
|
|
64
|
+
git-ai hook install
|
|
58
65
|
|
|
59
|
-
#
|
|
66
|
+
# 之后正常使用 git
|
|
60
67
|
git add .
|
|
61
|
-
git
|
|
68
|
+
git commit # 自动生成消息,打开编辑器确认
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**跳过 Hook:**
|
|
72
|
+
```bash
|
|
73
|
+
git commit -m "手动消息" # 已有消息时自动跳过
|
|
74
|
+
GIT_AI_DISABLED=1 git commit # 临时禁用
|
|
75
|
+
git-ai hook remove # 永久移除
|
|
62
76
|
```
|
|
63
77
|
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 🛠 命令速查
|
|
81
|
+
|
|
82
|
+
| 命令 | 说明 | 使用场景 |
|
|
83
|
+
|------|------|----------|
|
|
84
|
+
| `git-ai` | 交互式生成并提交 | 日常使用 |
|
|
85
|
+
| `git-ai -y` | 跳过确认直接提交 | CI/CD、快速提交 |
|
|
86
|
+
| `git-ai -n 3` | 生成 3 条候选消息 | 选择最佳消息 |
|
|
87
|
+
| `git-ai msg` | 仅输出消息到 stdout | 脚本集成 |
|
|
88
|
+
| `git-ai msg --json` | JSON 格式输出 | 程序化处理 |
|
|
89
|
+
| `git-ai msg --quiet` | 静默模式(无 spinner) | Hook 调用 |
|
|
90
|
+
| `git-ai config` | 配置 AI 服务商 | 初始化/切换模型 |
|
|
91
|
+
| `git-ai hook install` | 安装 Git Hook | 集成到 git commit |
|
|
92
|
+
| `git-ai hook status` | 查看 Hook 状态 | 检查是否已安装 |
|
|
93
|
+
| `git-ai hook remove` | 移除 Hook | 禁用自动生成 |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
64
97
|
## ✨ 特性
|
|
65
98
|
|
|
66
99
|
| 特性 | 描述 |
|
|
@@ -68,12 +101,13 @@ git-ai
|
|
|
68
101
|
| 🤖 **多模型支持** | DeepSeek、通义千问、智谱GLM、Moonshot、OpenAI 等 10+ 模型 |
|
|
69
102
|
| 🏠 **本地部署** | 支持 Ollama、LM Studio,数据不出本机 |
|
|
70
103
|
| 🔍 **智能 Diff** | 自动过滤 lock 文件,Token 优化截断 |
|
|
71
|
-
|
|
|
104
|
+
| 🪝 **Git Hook** | 无缝集成到 git commit 流程 |
|
|
72
105
|
| ⚡ **一键提交** | `-y` 参数跳过确认,CI/CD 友好 |
|
|
73
106
|
| 🎯 **多条候选** | `-n 3` 生成多条消息供选择 |
|
|
74
|
-
| 🪝 **Git Hook** | 自动集成到 git commit 流程 |
|
|
75
107
|
| 📝 **规范化** | 遵循 Conventional Commits 标准 |
|
|
76
|
-
|
|
|
108
|
+
| 🔄 **自动重试** | 30 秒超时 + 2 次自动重试 |
|
|
109
|
+
|
|
110
|
+
---
|
|
77
111
|
|
|
78
112
|
## 🤖 支持的模型
|
|
79
113
|
|
|
@@ -81,13 +115,13 @@ git-ai
|
|
|
81
115
|
|
|
82
116
|
| 服务商 | 默认模型 | 获取 API Key |
|
|
83
117
|
|--------|----------|--------------|
|
|
84
|
-
| **DeepSeek**
|
|
118
|
+
| **DeepSeek** | `deepseek-chat` | [platform.deepseek.com](https://platform.deepseek.com/) |
|
|
85
119
|
| **Qwen** (通义千问) | `qwen-turbo` | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com/) |
|
|
86
120
|
| **Zhipu** (智谱 GLM) | `glm-4-flash` | [open.bigmodel.cn](https://open.bigmodel.cn/) |
|
|
87
121
|
| **Moonshot** (月之暗面) | `moonshot-v1-8k` | [platform.moonshot.cn](https://platform.moonshot.cn/) |
|
|
88
122
|
| **Baichuan** (百川) | `Baichuan4` | [platform.baichuan-ai.com](https://platform.baichuan-ai.com/) |
|
|
89
123
|
| **Yi** (零一万物) | `yi-lightning` | [platform.lingyiwanwu.com](https://platform.lingyiwanwu.com/) |
|
|
90
|
-
| **SiliconFlow**
|
|
124
|
+
| **SiliconFlow** | `Qwen2.5-7B` | [cloud.siliconflow.cn](https://cloud.siliconflow.cn/) |
|
|
91
125
|
|
|
92
126
|
### 国际大模型
|
|
93
127
|
|
|
@@ -102,9 +136,9 @@ git-ai
|
|
|
102
136
|
| **Ollama** | `qwen2.5:7b` | [ollama.ai](https://ollama.ai/) |
|
|
103
137
|
| **LM Studio** | `local-model` | [lmstudio.ai](https://lmstudio.ai/) |
|
|
104
138
|
|
|
105
|
-
|
|
139
|
+
---
|
|
106
140
|
|
|
107
|
-
|
|
141
|
+
## ⚙️ 配置
|
|
108
142
|
|
|
109
143
|
```bash
|
|
110
144
|
git-ai config
|
|
@@ -117,7 +151,7 @@ git-ai config
|
|
|
117
151
|
4. 选择输出语言(中文/英文)
|
|
118
152
|
5. 可选:自定义 System Prompt
|
|
119
153
|
|
|
120
|
-
|
|
154
|
+
**配置文件位置:**
|
|
121
155
|
|
|
122
156
|
| 系统 | 路径 |
|
|
123
157
|
|------|------|
|
|
@@ -125,62 +159,59 @@ git-ai config
|
|
|
125
159
|
| Linux | `~/.config/git-ai-cli-nodejs/config.json` |
|
|
126
160
|
| Windows | `%APPDATA%/git-ai-cli-nodejs/Config/config.json` |
|
|
127
161
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
### 命令行选项
|
|
162
|
+
---
|
|
131
163
|
|
|
132
|
-
|
|
133
|
-
# 一键提交(跳过确认,CI/CD 友好)
|
|
134
|
-
git-ai -y
|
|
135
|
-
git-ai --yes
|
|
164
|
+
## 🪝 Git Hook 详解
|
|
136
165
|
|
|
137
|
-
|
|
138
|
-
git-ai -n 3
|
|
139
|
-
git-ai --num 3
|
|
166
|
+
### 工作原理
|
|
140
167
|
|
|
141
|
-
|
|
142
|
-
git
|
|
168
|
+
```
|
|
169
|
+
git commit (无 -m)
|
|
170
|
+
↓
|
|
171
|
+
prepare-commit-msg hook 触发
|
|
172
|
+
↓
|
|
173
|
+
git-ai msg --quiet 生成消息
|
|
174
|
+
↓
|
|
175
|
+
写入 COMMIT_MSG 文件
|
|
176
|
+
↓
|
|
177
|
+
打开编辑器确认
|
|
143
178
|
```
|
|
144
179
|
|
|
145
|
-
###
|
|
180
|
+
### Hook 特性
|
|
146
181
|
|
|
147
|
-
|
|
182
|
+
| 特性 | 说明 |
|
|
183
|
+
|------|------|
|
|
184
|
+
| **链式执行** | 已有 hook 会被保留并在 git-ai 之后执行 |
|
|
185
|
+
| **递归保护** | `GIT_AI_RUNNING` 环境变量防止无限循环 |
|
|
186
|
+
| **智能跳过** | 使用 `-m`、merge、amend 时自动跳过 |
|
|
187
|
+
| **手动禁用** | `GIT_AI_DISABLED=1 git commit` |
|
|
148
188
|
|
|
149
|
-
|
|
150
|
-
# 安装 hook
|
|
151
|
-
git-ai hook install
|
|
189
|
+
> ⚠️ **注意**: `git commit --no-verify` 不会跳过 prepare-commit-msg hook
|
|
152
190
|
|
|
153
|
-
|
|
154
|
-
git-ai hook status
|
|
191
|
+
### 脚本集成
|
|
155
192
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
```bash
|
|
194
|
+
# 获取消息用于脚本
|
|
195
|
+
MSG=$(git-ai msg --quiet)
|
|
196
|
+
git commit -m "$MSG"
|
|
159
197
|
|
|
160
|
-
|
|
198
|
+
# JSON 格式(含元数据)
|
|
199
|
+
git-ai msg --json | jq '.message'
|
|
161
200
|
|
|
162
|
-
|
|
163
|
-
git
|
|
164
|
-
git commit # 自动调用 git-ai 生成消息
|
|
201
|
+
# 多条消息(用 ---END--- 分隔)
|
|
202
|
+
git-ai msg -n 3 --quiet
|
|
165
203
|
```
|
|
166
204
|
|
|
167
|
-
|
|
205
|
+
---
|
|
168
206
|
|
|
169
|
-
|
|
207
|
+
## 🔧 自动忽略的文件
|
|
170
208
|
|
|
171
|
-
以下文件会自动从 Diff
|
|
209
|
+
以下文件会自动从 Diff 分析中排除,节省 Token:
|
|
172
210
|
|
|
173
211
|
- **Lock 文件**: `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lockb`
|
|
174
212
|
- **压缩文件**: `*.min.js`, `*.min.css`, `*.map`
|
|
175
213
|
- **构建产物**: `dist/`, `build/`, `.next/`
|
|
176
214
|
|
|
177
|
-
### 自定义 Prompt
|
|
178
|
-
|
|
179
|
-
在配置时选择「自定义 System Prompt」,可以:
|
|
180
|
-
- 强制添加 Emoji 前缀
|
|
181
|
-
- 使用特定语言
|
|
182
|
-
- 遵循团队规范
|
|
183
|
-
|
|
184
215
|
---
|
|
185
216
|
|
|
186
217
|
## English
|
|
@@ -194,67 +225,53 @@ npm install -g @dongowu/git-ai-cli
|
|
|
194
225
|
### Quick Start
|
|
195
226
|
|
|
196
227
|
```bash
|
|
197
|
-
# Configure AI provider
|
|
198
|
-
git-ai config
|
|
199
|
-
|
|
200
|
-
# Generate commit message
|
|
228
|
+
git-ai config # Configure AI provider
|
|
201
229
|
git add .
|
|
202
|
-
git-ai
|
|
230
|
+
git-ai # Generate and commit
|
|
203
231
|
```
|
|
204
232
|
|
|
205
|
-
###
|
|
206
|
-
|
|
207
|
-
- **Multi-model**: DeepSeek, Qwen, Zhipu GLM, Moonshot, OpenAI, and 10+ more
|
|
208
|
-
- **Local deployment**: Ollama, LM Studio - keep your data private
|
|
209
|
-
- **Smart diff**: Auto-filter lock files, token optimization
|
|
210
|
-
- **Interactive**: Commit / Edit / Regenerate / Cancel
|
|
211
|
-
- **One-click commit**: `-y` flag for CI/CD pipelines
|
|
212
|
-
- **Multiple choices**: `-n 3` to generate multiple options
|
|
213
|
-
- **Git Hook**: Auto-integrate with `git commit`
|
|
214
|
-
- **Conventional Commits**: Standard commit message format
|
|
215
|
-
|
|
216
|
-
### CLI Options
|
|
233
|
+
### Two Ways to Use
|
|
217
234
|
|
|
235
|
+
**Manual Mode:**
|
|
218
236
|
```bash
|
|
219
|
-
|
|
220
|
-
git-ai
|
|
237
|
+
git add .
|
|
238
|
+
git-ai # Interactive: generate → choose action → commit
|
|
239
|
+
git-ai -y # Auto commit (skip confirmation)
|
|
240
|
+
git-ai -n 3 # Generate 3 options to choose from
|
|
241
|
+
```
|
|
221
242
|
|
|
222
|
-
|
|
223
|
-
|
|
243
|
+
**Git Hook Mode:**
|
|
244
|
+
```bash
|
|
245
|
+
git-ai hook install # One-time setup
|
|
224
246
|
|
|
225
|
-
#
|
|
226
|
-
git
|
|
227
|
-
git-
|
|
228
|
-
git-ai hook status # Check status
|
|
247
|
+
# Then just use git normally
|
|
248
|
+
git add .
|
|
249
|
+
git commit # Auto-generates message, opens editor
|
|
229
250
|
```
|
|
230
251
|
|
|
231
|
-
###
|
|
252
|
+
### Command Reference
|
|
232
253
|
|
|
254
|
+
| Command | Description |
|
|
255
|
+
|---------|-------------|
|
|
256
|
+
| `git-ai` | Interactive commit |
|
|
257
|
+
| `git-ai -y` | Skip confirmation |
|
|
258
|
+
| `git-ai -n 3` | Generate 3 options |
|
|
259
|
+
| `git-ai msg` | Output message only (stdout) |
|
|
260
|
+
| `git-ai msg --json` | JSON output with metadata |
|
|
261
|
+
| `git-ai msg --quiet` | Silent mode (no spinner) |
|
|
262
|
+
| `git-ai config` | Configure AI provider |
|
|
263
|
+
| `git-ai hook install` | Install Git hook |
|
|
264
|
+
| `git-ai hook remove` | Remove Git hook |
|
|
265
|
+
|
|
266
|
+
### Skip Hook
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
git commit -m "message" # Auto-skipped when message provided
|
|
270
|
+
GIT_AI_DISABLED=1 git commit # Temporarily disable
|
|
271
|
+
git-ai hook remove # Permanently remove
|
|
233
272
|
```
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
└────────┬────────┘
|
|
237
|
-
▼
|
|
238
|
-
┌─────────────────┐
|
|
239
|
-
│ git-ai │
|
|
240
|
-
└────────┬────────┘
|
|
241
|
-
▼
|
|
242
|
-
┌─────────────────┐
|
|
243
|
-
│ Analyze Diff │
|
|
244
|
-
└────────┬────────┘
|
|
245
|
-
▼
|
|
246
|
-
┌─────────────────┐
|
|
247
|
-
│ AI Generate │
|
|
248
|
-
└────────┬────────┘
|
|
249
|
-
▼
|
|
250
|
-
┌─────────────────────────────┐
|
|
251
|
-
│ Choose Action: │
|
|
252
|
-
│ • Commit │
|
|
253
|
-
│ • Edit │
|
|
254
|
-
│ • Regenerate │
|
|
255
|
-
│ • Cancel │
|
|
256
|
-
└─────────────────────────────┘
|
|
257
|
-
```
|
|
273
|
+
|
|
274
|
+
> ⚠️ Note: `--no-verify` does NOT skip prepare-commit-msg hooks
|
|
258
275
|
|
|
259
276
|
---
|
|
260
277
|
|
package/dist/cli.js
CHANGED
|
@@ -4,16 +4,25 @@ import chalk from 'chalk';
|
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { runConfig } from './commands/config.js';
|
|
6
6
|
import { runCommit } from './commands/commit.js';
|
|
7
|
+
import { runMsg } from './commands/msg.js';
|
|
7
8
|
import { runHook } from './commands/hook.js';
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
9
10
|
const pkg = require('../package.json');
|
|
10
11
|
const cli = cac('git-ai');
|
|
12
|
+
// Default command (backward compatible) - interactive commit
|
|
11
13
|
cli
|
|
12
|
-
.command('', 'Generate AI-powered commit message')
|
|
14
|
+
.command('', 'Generate AI-powered commit message (interactive)')
|
|
13
15
|
.option('-y, --yes', 'Skip confirmation and commit directly')
|
|
14
16
|
.option('-n, --num <count>', 'Generate multiple commit messages to choose from', { default: 1 })
|
|
17
|
+
.option('--hook', '[deprecated] Use `git-ai msg` instead')
|
|
15
18
|
.action(async (options) => {
|
|
16
19
|
try {
|
|
20
|
+
// Deprecated --hook redirects to msg command behavior
|
|
21
|
+
if (options.hook) {
|
|
22
|
+
const { runMsg } = await import('./commands/msg.js');
|
|
23
|
+
await runMsg({ quiet: true });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
17
26
|
await runCommit({
|
|
18
27
|
autoCommit: options.yes ?? false,
|
|
19
28
|
numChoices: Math.min(Math.max(Number(options.num) || 1, 1), 5),
|
|
@@ -25,6 +34,49 @@ cli
|
|
|
25
34
|
process.exit(1);
|
|
26
35
|
}
|
|
27
36
|
});
|
|
37
|
+
// Explicit commit subcommand
|
|
38
|
+
cli
|
|
39
|
+
.command('commit', 'Generate and commit with AI message (interactive)')
|
|
40
|
+
.option('-y, --yes', 'Skip confirmation and commit directly')
|
|
41
|
+
.option('-n, --num <count>', 'Generate multiple commit messages to choose from', { default: 1 })
|
|
42
|
+
.action(async (options) => {
|
|
43
|
+
try {
|
|
44
|
+
await runCommit({
|
|
45
|
+
autoCommit: options.yes ?? false,
|
|
46
|
+
numChoices: Math.min(Math.max(Number(options.num) || 1, 1), 5),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
51
|
+
console.error(chalk.red(`\n❌ Error: ${message}\n`));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Message-only command (for hooks and scripts)
|
|
56
|
+
cli
|
|
57
|
+
.command('msg', 'Generate commit message only (stdout, for hooks/scripts)')
|
|
58
|
+
.option('-n, --num <count>', 'Generate multiple messages', { default: 1 })
|
|
59
|
+
.option('--json', 'Output as JSON')
|
|
60
|
+
.option('--quiet', 'Suppress spinner and colors')
|
|
61
|
+
.action(async (options) => {
|
|
62
|
+
try {
|
|
63
|
+
await runMsg({
|
|
64
|
+
num: Math.min(Math.max(Number(options.num) || 1, 1), 5),
|
|
65
|
+
json: options.json ?? false,
|
|
66
|
+
quiet: options.quiet ?? false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (options.json) {
|
|
71
|
+
console.log(JSON.stringify({ success: false, error: String(error) }));
|
|
72
|
+
}
|
|
73
|
+
else if (!options.quiet) {
|
|
74
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
75
|
+
console.error(chalk.red(`\n❌ Error: ${message}\n`));
|
|
76
|
+
}
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
28
80
|
cli
|
|
29
81
|
.command('config', 'Configure AI provider settings')
|
|
30
82
|
.action(async () => {
|
|
@@ -38,7 +90,7 @@ cli
|
|
|
38
90
|
}
|
|
39
91
|
});
|
|
40
92
|
cli
|
|
41
|
-
.command('hook <action>', 'Manage Git hooks (install/remove)')
|
|
93
|
+
.command('hook <action>', 'Manage Git hooks (install/remove/status)')
|
|
42
94
|
.action(async (action) => {
|
|
43
95
|
try {
|
|
44
96
|
await runHook(action);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAyB,CAAC;AAE/D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;AAE1B,GAAG;KACA,OAAO,CAAC,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAYD,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJ1E"}
|
package/dist/commands/commit.js
CHANGED
|
@@ -4,51 +4,76 @@ import ora from 'ora';
|
|
|
4
4
|
import { getConfig } from '../utils/config.js';
|
|
5
5
|
import { isGitInstalled, isInGitRepo, getStagedFiles, getFilteredDiff, commit, } from '../utils/git.js';
|
|
6
6
|
import { createAIClient, generateCommitMessage, } from '../utils/ai.js';
|
|
7
|
-
function exitWithError(message, hint) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function exitWithError(message, hint, silent = false) {
|
|
8
|
+
if (!silent) {
|
|
9
|
+
console.error(chalk.red(`❌ ${message}`));
|
|
10
|
+
if (hint) {
|
|
11
|
+
console.log(chalk.gray(` ${hint}`));
|
|
12
|
+
}
|
|
11
13
|
}
|
|
12
14
|
process.exit(1);
|
|
13
15
|
}
|
|
14
16
|
export async function runCommit(options = {}) {
|
|
15
|
-
const { autoCommit = false, numChoices = 1 } = options;
|
|
17
|
+
const { autoCommit = false, numChoices = 1, hookMode = false } = options;
|
|
18
|
+
// Recursion guard - prevent hook from triggering another git-ai
|
|
19
|
+
if (process.env.GIT_AI_RUNNING === '1') {
|
|
20
|
+
if (!hookMode) {
|
|
21
|
+
console.log(chalk.yellow('⚠️ git-ai is already running (recursion prevented)'));
|
|
22
|
+
}
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
process.env.GIT_AI_RUNNING = '1';
|
|
16
26
|
// Environment checks
|
|
17
27
|
if (!(await isGitInstalled())) {
|
|
18
|
-
exitWithError('Git is not installed. Please install git first.');
|
|
28
|
+
exitWithError('Git is not installed. Please install git first.', undefined, hookMode);
|
|
19
29
|
}
|
|
20
30
|
if (!(await isInGitRepo())) {
|
|
21
|
-
exitWithError('Not in a git repository.');
|
|
31
|
+
exitWithError('Not in a git repository.', undefined, hookMode);
|
|
22
32
|
}
|
|
23
33
|
const stagedFiles = await getStagedFiles();
|
|
24
34
|
if (stagedFiles.length === 0) {
|
|
25
|
-
exitWithError('No staged changes found.', 'Use `git add <files>` to stage your changes first.');
|
|
35
|
+
exitWithError('No staged changes found.', 'Use `git add <files>` to stage your changes first.', hookMode);
|
|
26
36
|
}
|
|
27
37
|
// Check config
|
|
28
38
|
const config = getConfig();
|
|
29
39
|
if (!config) {
|
|
30
40
|
exitWithError('Configuration not found.', 'Run `git-ai config` to set up your AI provider.');
|
|
31
41
|
}
|
|
32
|
-
// Show staged files
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
// Show staged files (skip in hook mode)
|
|
43
|
+
if (!hookMode) {
|
|
44
|
+
console.log(chalk.cyan('\n📁 Staged files:'));
|
|
45
|
+
stagedFiles.forEach((file) => {
|
|
46
|
+
console.log(chalk.gray(` ${file}`));
|
|
47
|
+
});
|
|
48
|
+
}
|
|
37
49
|
// Get filtered diff
|
|
38
50
|
const { diff, truncated, ignoredFiles } = await getFilteredDiff(stagedFiles);
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
if (!hookMode) {
|
|
52
|
+
if (ignoredFiles.length > 0) {
|
|
53
|
+
const preview = ignoredFiles.slice(0, 8).join(', ');
|
|
54
|
+
const more = ignoredFiles.length > 8 ? ` (+${ignoredFiles.length - 8} more)` : '';
|
|
55
|
+
console.log(chalk.gray(`\n🧹 Ignored from diff (token optimization): ${preview}${more}`));
|
|
56
|
+
}
|
|
57
|
+
if (truncated) {
|
|
58
|
+
console.log(chalk.yellow('\n⚠️ Diff was truncated due to size limits.'));
|
|
59
|
+
}
|
|
46
60
|
}
|
|
47
61
|
// Create AI client
|
|
48
62
|
const client = createAIClient(config);
|
|
49
63
|
const input = { diff, stagedFiles, ignoredFiles, truncated };
|
|
50
64
|
// Generate commit message(s)
|
|
51
65
|
let commitMessage;
|
|
66
|
+
if (hookMode) {
|
|
67
|
+
// Hook mode: silent generation, output only the message
|
|
68
|
+
try {
|
|
69
|
+
commitMessage = await generateCommitMessage(client, input, config);
|
|
70
|
+
console.log(commitMessage);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
52
77
|
if (numChoices > 1) {
|
|
53
78
|
// Generate multiple choices
|
|
54
79
|
const messages = await generateMultipleWithSpinner(client, input, config, numChoices);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,WAAW,EACX,cAAc,EACd,eAAe,EACf,MAAM,GACP,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,qBAAqB,GAEtB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AA6JA,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB3D"}
|
package/dist/commands/hook.js
CHANGED
|
@@ -3,33 +3,126 @@ import { execa } from 'execa';
|
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
const HOOK_NAME = 'prepare-commit-msg';
|
|
6
|
+
const HOOK_MARKER = '# git-ai-hook-start';
|
|
7
|
+
const HOOK_END_MARKER = '# git-ai-hook-end';
|
|
8
|
+
// Hook script with all protections
|
|
6
9
|
const HOOK_SCRIPT = `#!/bin/sh
|
|
10
|
+
${HOOK_MARKER}
|
|
7
11
|
# git-ai hook - auto-generate commit message
|
|
8
|
-
# To disable
|
|
9
|
-
|
|
10
|
-
COMMIT_MSG_FILE
|
|
11
|
-
COMMIT_SOURCE
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
if [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
# To disable: GIT_AI_DISABLED=1 git commit
|
|
13
|
+
|
|
14
|
+
COMMIT_MSG_FILE="$1"
|
|
15
|
+
COMMIT_SOURCE="$2"
|
|
16
|
+
|
|
17
|
+
# Skip if disabled
|
|
18
|
+
if [ "$GIT_AI_DISABLED" = "1" ]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Recursion guard - skip if git-ai is already running
|
|
23
|
+
# (e.g., when git-ai commit calls git commit internally)
|
|
24
|
+
if [ "$GIT_AI_RUNNING" = "1" ]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Only run for regular commits (not merge, squash, amend, etc.)
|
|
29
|
+
if [ -n "$COMMIT_SOURCE" ]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Check if there's already a non-comment message
|
|
34
|
+
if [ -s "$COMMIT_MSG_FILE" ]; then
|
|
35
|
+
EXISTING_MSG=$(grep -v "^#" "$COMMIT_MSG_FILE" | grep -v "^$" | head -1)
|
|
36
|
+
if [ -n "$EXISTING_MSG" ]; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Generate commit message using git-ai msg
|
|
42
|
+
if command -v git-ai >/dev/null 2>&1; then
|
|
43
|
+
MSG=$(git-ai msg --quiet 2>/dev/null)
|
|
44
|
+
EXIT_CODE=$?
|
|
45
|
+
|
|
46
|
+
if [ $EXIT_CODE -eq 0 ] && [ -n "$MSG" ]; then
|
|
47
|
+
# Preserve existing comments, prepend AI message
|
|
48
|
+
if [ -f "$COMMIT_MSG_FILE" ]; then
|
|
49
|
+
COMMENTS=$(grep "^#" "$COMMIT_MSG_FILE" || true)
|
|
50
|
+
printf '%s\\n\\n%s\\n' "$MSG" "$COMMENTS" > "$COMMIT_MSG_FILE"
|
|
51
|
+
else
|
|
52
|
+
printf '%s\\n' "$MSG" > "$COMMIT_MSG_FILE"
|
|
20
53
|
fi
|
|
21
54
|
fi
|
|
55
|
+
fi
|
|
56
|
+
${HOOK_END_MARKER}
|
|
57
|
+
|
|
58
|
+
`;
|
|
59
|
+
// Wrapper template for chaining with existing hook
|
|
60
|
+
const WRAPPER_TEMPLATE = `#!/bin/sh
|
|
61
|
+
${HOOK_MARKER}
|
|
62
|
+
# git-ai hook wrapper - chains with existing hook
|
|
63
|
+
# To disable: GIT_AI_DISABLED=1 git commit
|
|
22
64
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
65
|
+
COMMIT_MSG_FILE="$1"
|
|
66
|
+
COMMIT_SOURCE="$2"
|
|
67
|
+
SHA1="$3"
|
|
68
|
+
|
|
69
|
+
# Skip if disabled
|
|
70
|
+
if [ "$GIT_AI_DISABLED" = "1" ]; then
|
|
71
|
+
if [ -x "__ORIGINAL_HOOK__" ]; then
|
|
72
|
+
"__ORIGINAL_HOOK__" "$COMMIT_MSG_FILE" "$COMMIT_SOURCE" "$SHA1"
|
|
73
|
+
fi
|
|
74
|
+
exit $?
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Recursion guard - skip if git-ai is already running
|
|
78
|
+
if [ "$GIT_AI_RUNNING" = "1" ]; then
|
|
79
|
+
if [ -x "__ORIGINAL_HOOK__" ]; then
|
|
80
|
+
"__ORIGINAL_HOOK__" "$COMMIT_MSG_FILE" "$COMMIT_SOURCE" "$SHA1"
|
|
81
|
+
fi
|
|
82
|
+
exit $?
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Only run for regular commits
|
|
86
|
+
if [ -n "$COMMIT_SOURCE" ]; then
|
|
87
|
+
if [ -x "__ORIGINAL_HOOK__" ]; then
|
|
88
|
+
"__ORIGINAL_HOOK__" "$COMMIT_MSG_FILE" "$COMMIT_SOURCE" "$SHA1"
|
|
89
|
+
fi
|
|
90
|
+
exit $?
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Check if there's already a non-comment message
|
|
94
|
+
if [ -s "$COMMIT_MSG_FILE" ]; then
|
|
95
|
+
EXISTING_MSG=$(grep -v "^#" "$COMMIT_MSG_FILE" | grep -v "^$" | head -1)
|
|
96
|
+
if [ -n "$EXISTING_MSG" ]; then
|
|
97
|
+
if [ -x "__ORIGINAL_HOOK__" ]; then
|
|
98
|
+
"__ORIGINAL_HOOK__" "$COMMIT_MSG_FILE" "$COMMIT_SOURCE" "$SHA1"
|
|
29
99
|
fi
|
|
100
|
+
exit $?
|
|
30
101
|
fi
|
|
31
102
|
fi
|
|
32
103
|
|
|
104
|
+
# Generate commit message using git-ai msg
|
|
105
|
+
if command -v git-ai >/dev/null 2>&1; then
|
|
106
|
+
MSG=$(git-ai msg --quiet 2>/dev/null)
|
|
107
|
+
EXIT_CODE=$?
|
|
108
|
+
|
|
109
|
+
if [ $EXIT_CODE -eq 0 ] && [ -n "$MSG" ]; then
|
|
110
|
+
if [ -f "$COMMIT_MSG_FILE" ]; then
|
|
111
|
+
COMMENTS=$(grep "^#" "$COMMIT_MSG_FILE" || true)
|
|
112
|
+
printf '%s\\n\\n%s\\n' "$MSG" "$COMMENTS" > "$COMMIT_MSG_FILE"
|
|
113
|
+
else
|
|
114
|
+
printf '%s\\n' "$MSG" > "$COMMIT_MSG_FILE"
|
|
115
|
+
fi
|
|
116
|
+
fi
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Call original hook
|
|
120
|
+
if [ -x "__ORIGINAL_HOOK__" ]; then
|
|
121
|
+
"__ORIGINAL_HOOK__" "$COMMIT_MSG_FILE" "$COMMIT_SOURCE" "$SHA1"
|
|
122
|
+
exit $?
|
|
123
|
+
fi
|
|
124
|
+
${HOOK_END_MARKER}
|
|
125
|
+
|
|
33
126
|
exit 0
|
|
34
127
|
`;
|
|
35
128
|
async function getGitHooksPath() {
|
|
@@ -53,6 +146,10 @@ async function isInGitRepo() {
|
|
|
53
146
|
return false;
|
|
54
147
|
}
|
|
55
148
|
}
|
|
149
|
+
function isGitAiHook(content) {
|
|
150
|
+
// Only match our specific marker to avoid false positives
|
|
151
|
+
return content.includes(HOOK_MARKER);
|
|
152
|
+
}
|
|
56
153
|
export async function runHook(action) {
|
|
57
154
|
if (!['install', 'remove', 'status'].includes(action)) {
|
|
58
155
|
console.error(chalk.red(`❌ Unknown action: ${action}`));
|
|
@@ -78,13 +175,22 @@ export async function runHook(action) {
|
|
|
78
175
|
async function showStatus(hookFile) {
|
|
79
176
|
if (existsSync(hookFile)) {
|
|
80
177
|
const content = readFileSync(hookFile, 'utf-8');
|
|
81
|
-
if (content
|
|
178
|
+
if (isGitAiHook(content)) {
|
|
82
179
|
console.log(chalk.green('✅ git-ai hook is installed'));
|
|
83
180
|
console.log(chalk.gray(` Location: ${hookFile}`));
|
|
181
|
+
// Check if it's a wrapper
|
|
182
|
+
const originalHook = `${hookFile}.original`;
|
|
183
|
+
if (existsSync(originalHook)) {
|
|
184
|
+
console.log(chalk.cyan(' Mode: Wrapper (chained with original hook)'));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
console.log(chalk.cyan(' Mode: Standalone'));
|
|
188
|
+
}
|
|
84
189
|
}
|
|
85
190
|
else {
|
|
86
191
|
console.log(chalk.yellow('⚠️ A prepare-commit-msg hook exists but is not from git-ai'));
|
|
87
192
|
console.log(chalk.gray(` Location: ${hookFile}`));
|
|
193
|
+
console.log(chalk.gray(' Run `git-ai hook install` to add git-ai (will chain with existing hook)'));
|
|
88
194
|
}
|
|
89
195
|
}
|
|
90
196
|
else {
|
|
@@ -92,26 +198,51 @@ async function showStatus(hookFile) {
|
|
|
92
198
|
}
|
|
93
199
|
}
|
|
94
200
|
async function installHook(hookFile, hooksPath) {
|
|
201
|
+
// Ensure hooks directory exists
|
|
202
|
+
if (!existsSync(hooksPath)) {
|
|
203
|
+
await execa('mkdir', ['-p', hooksPath]);
|
|
204
|
+
}
|
|
95
205
|
// Check if hook already exists
|
|
96
206
|
if (existsSync(hookFile)) {
|
|
97
207
|
const content = readFileSync(hookFile, 'utf-8');
|
|
98
|
-
if (content
|
|
99
|
-
|
|
208
|
+
if (isGitAiHook(content)) {
|
|
209
|
+
// Already has git-ai, update it
|
|
210
|
+
console.log(chalk.yellow('⚠️ git-ai hook already installed, updating...'));
|
|
211
|
+
// Check if there's an original hook
|
|
212
|
+
const originalHook = `${hookFile}.original`;
|
|
213
|
+
if (existsSync(originalHook)) {
|
|
214
|
+
// Re-create wrapper with updated script
|
|
215
|
+
const wrapper = WRAPPER_TEMPLATE.replace(/__ORIGINAL_HOOK__/g, originalHook);
|
|
216
|
+
writeFileSync(hookFile, wrapper);
|
|
217
|
+
chmodSync(hookFile, 0o755);
|
|
218
|
+
console.log(chalk.green('✅ git-ai hook updated (wrapper mode)'));
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
writeFileSync(hookFile, HOOK_SCRIPT);
|
|
222
|
+
chmodSync(hookFile, 0o755);
|
|
223
|
+
console.log(chalk.green('✅ git-ai hook updated'));
|
|
224
|
+
}
|
|
100
225
|
return;
|
|
101
226
|
}
|
|
102
|
-
//
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
227
|
+
// Existing non-git-ai hook - use wrapper mode
|
|
228
|
+
const originalHook = `${hookFile}.original`;
|
|
229
|
+
// Backup original
|
|
230
|
+
writeFileSync(originalHook, content);
|
|
231
|
+
chmodSync(originalHook, 0o755);
|
|
232
|
+
console.log(chalk.gray(` Original hook saved to: ${originalHook}`));
|
|
233
|
+
// Install wrapper
|
|
234
|
+
const wrapper = WRAPPER_TEMPLATE.replace(/__ORIGINAL_HOOK__/g, originalHook);
|
|
235
|
+
writeFileSync(hookFile, wrapper);
|
|
236
|
+
chmodSync(hookFile, 0o755);
|
|
237
|
+
console.log(chalk.green('✅ git-ai hook installed (wrapper mode)'));
|
|
238
|
+
console.log(chalk.cyan(' Your original hook will still be executed after git-ai'));
|
|
106
239
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
240
|
+
else {
|
|
241
|
+
// No existing hook - install standalone
|
|
242
|
+
writeFileSync(hookFile, HOOK_SCRIPT);
|
|
243
|
+
chmodSync(hookFile, 0o755);
|
|
244
|
+
console.log(chalk.green('✅ git-ai hook installed'));
|
|
110
245
|
}
|
|
111
|
-
// Write hook script
|
|
112
|
-
writeFileSync(hookFile, HOOK_SCRIPT);
|
|
113
|
-
chmodSync(hookFile, 0o755);
|
|
114
|
-
console.log(chalk.green('✅ git-ai hook installed successfully!'));
|
|
115
246
|
console.log(chalk.gray(` Location: ${hookFile}`));
|
|
116
247
|
console.log('');
|
|
117
248
|
console.log(chalk.cyan('📝 How it works:'));
|
|
@@ -128,20 +259,25 @@ async function removeHook(hookFile) {
|
|
|
128
259
|
return;
|
|
129
260
|
}
|
|
130
261
|
const content = readFileSync(hookFile, 'utf-8');
|
|
131
|
-
if (!content
|
|
262
|
+
if (!isGitAiHook(content)) {
|
|
132
263
|
console.log(chalk.yellow('⚠️ The existing hook is not from git-ai, skipping removal'));
|
|
133
264
|
return;
|
|
134
265
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
writeFileSync(hookFile,
|
|
266
|
+
// Check for original hook
|
|
267
|
+
const originalHook = `${hookFile}.original`;
|
|
268
|
+
if (existsSync(originalHook)) {
|
|
269
|
+
// Restore original hook
|
|
270
|
+
const originalContent = readFileSync(originalHook, 'utf-8');
|
|
271
|
+
writeFileSync(hookFile, originalContent);
|
|
141
272
|
chmodSync(hookFile, 0o755);
|
|
142
|
-
unlinkSync(
|
|
143
|
-
console.log(chalk.
|
|
273
|
+
unlinkSync(originalHook);
|
|
274
|
+
console.log(chalk.green('✅ git-ai hook removed'));
|
|
275
|
+
console.log(chalk.gray(' Original hook restored'));
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// Just remove the hook
|
|
279
|
+
unlinkSync(hookFile);
|
|
280
|
+
console.log(chalk.green('✅ git-ai hook removed'));
|
|
144
281
|
}
|
|
145
|
-
console.log(chalk.green('✅ git-ai hook removed successfully!'));
|
|
146
282
|
}
|
|
147
283
|
//# sourceMappingURL=hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,SAAS,GAAG,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,SAAS,GAAG,oBAAoB,CAAC;AACvC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAC1C,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C,mCAAmC;AACnC,MAAM,WAAW,GAAG;EAClB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CX,eAAe;;CAEhB,CAAC;AAEF,mDAAmD;AACnD,MAAM,gBAAgB,GAAG;EACvB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+DX,eAAe;;;CAGhB,CAAC;AAEF,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC;QACH,2CAA2C;QAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC7E,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,0DAA0D;IAC1D,OAAO,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAc;IAC1C,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,WAAW,EAAE,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE5C,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;YAEpD,0BAA0B;YAC1B,MAAM,YAAY,GAAG,GAAG,QAAQ,WAAW,CAAC;YAC5C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6DAA6D,CAAC,CAAC,CAAC;YACzF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAiB;IAC5D,gCAAgC;IAChC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,+BAA+B;IAC/B,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEhD,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,gCAAgC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gDAAgD,CAAC,CAAC,CAAC;YAE5E,oCAAoC;YACpC,MAAM,YAAY,GAAG,GAAG,QAAQ,WAAW,CAAC;YAC5C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7B,wCAAwC;gBACxC,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;gBAC7E,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACjC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBACrC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,OAAO;QACT,CAAC;QAED,8CAA8C;QAC9C,MAAM,YAAY,GAAG,GAAG,QAAQ,WAAW,CAAC;QAE5C,kBAAkB;QAClB,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC,CAAC;QAEtE,kBAAkB;QAClB,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;QAC7E,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,wCAAwC;QACxC,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACrC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4DAA4D,CAAC,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,MAAM,YAAY,GAAG,GAAG,QAAQ,WAAW,CAAC;IAE5C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,wBAAwB;QACxB,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC5D,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QACzC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3B,UAAU,CAAC,YAAY,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,uBAAuB;QACvB,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface MsgOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
quiet?: boolean;
|
|
4
|
+
num?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface MsgResult {
|
|
7
|
+
success: boolean;
|
|
8
|
+
message?: string;
|
|
9
|
+
messages?: string[];
|
|
10
|
+
error?: string;
|
|
11
|
+
metadata?: {
|
|
12
|
+
stagedFiles: string[];
|
|
13
|
+
truncated: boolean;
|
|
14
|
+
ignoredFiles: string[];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function runMsg(options?: MsgOptions): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=msg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg.d.ts","sourceRoot":"","sources":["../../src/commands/msg.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,EAAE,OAAO,CAAC;QACnB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;CACH;AAYD,wBAAsB,MAAM,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8FpE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { getConfig } from '../utils/config.js';
|
|
4
|
+
import { isGitInstalled, isInGitRepo, getStagedFiles, getFilteredDiff, } from '../utils/git.js';
|
|
5
|
+
import { createAIClient, generateCommitMessage, } from '../utils/ai.js';
|
|
6
|
+
function exitWithError(message, options) {
|
|
7
|
+
if (options.json) {
|
|
8
|
+
const result = { success: false, error: message };
|
|
9
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10
|
+
}
|
|
11
|
+
else if (!options.quiet) {
|
|
12
|
+
console.error(chalk.red(`❌ ${message}`));
|
|
13
|
+
}
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
export async function runMsg(options = {}) {
|
|
17
|
+
const { json = false, quiet = false, num = 1 } = options;
|
|
18
|
+
// Environment checks
|
|
19
|
+
if (!(await isGitInstalled())) {
|
|
20
|
+
exitWithError('Git is not installed.', options);
|
|
21
|
+
}
|
|
22
|
+
if (!(await isInGitRepo())) {
|
|
23
|
+
exitWithError('Not in a git repository.', options);
|
|
24
|
+
}
|
|
25
|
+
const stagedFiles = await getStagedFiles();
|
|
26
|
+
if (stagedFiles.length === 0) {
|
|
27
|
+
exitWithError('No staged changes found. Use `git add <files>` first.', options);
|
|
28
|
+
}
|
|
29
|
+
// Check config
|
|
30
|
+
const config = getConfig();
|
|
31
|
+
if (!config) {
|
|
32
|
+
exitWithError('Configuration not found. Run `git-ai config` first.', options);
|
|
33
|
+
}
|
|
34
|
+
// Get filtered diff
|
|
35
|
+
const { diff, truncated, ignoredFiles } = await getFilteredDiff(stagedFiles);
|
|
36
|
+
// Create AI client
|
|
37
|
+
const client = createAIClient(config);
|
|
38
|
+
const input = { diff, stagedFiles, ignoredFiles, truncated };
|
|
39
|
+
// Generate message(s)
|
|
40
|
+
try {
|
|
41
|
+
let spinner = null;
|
|
42
|
+
if (!quiet && !json) {
|
|
43
|
+
spinner = ora({
|
|
44
|
+
text: num > 1 ? `Generating ${num} commit messages...` : 'Generating commit message...',
|
|
45
|
+
color: 'cyan',
|
|
46
|
+
}).start();
|
|
47
|
+
}
|
|
48
|
+
if (num > 1) {
|
|
49
|
+
// Generate multiple messages
|
|
50
|
+
const promises = Array.from({ length: num }, () => generateCommitMessage(client, input, config));
|
|
51
|
+
const messages = await Promise.all(promises);
|
|
52
|
+
const unique = [...new Set(messages)];
|
|
53
|
+
if (spinner) {
|
|
54
|
+
spinner.stop();
|
|
55
|
+
}
|
|
56
|
+
if (json) {
|
|
57
|
+
const result = {
|
|
58
|
+
success: true,
|
|
59
|
+
messages: unique,
|
|
60
|
+
metadata: { stagedFiles, truncated, ignoredFiles },
|
|
61
|
+
};
|
|
62
|
+
console.log(JSON.stringify(result, null, 2));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Plain output: use delimiter for multi-line message safety
|
|
66
|
+
// Each message separated by ---END---
|
|
67
|
+
unique.forEach((msg, i) => {
|
|
68
|
+
console.log(msg);
|
|
69
|
+
if (i < unique.length - 1) {
|
|
70
|
+
console.log('---END---');
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Single message
|
|
77
|
+
const message = await generateCommitMessage(client, input, config);
|
|
78
|
+
if (spinner) {
|
|
79
|
+
spinner.stop();
|
|
80
|
+
}
|
|
81
|
+
if (json) {
|
|
82
|
+
const result = {
|
|
83
|
+
success: true,
|
|
84
|
+
message,
|
|
85
|
+
metadata: { stagedFiles, truncated, ignoredFiles },
|
|
86
|
+
};
|
|
87
|
+
console.log(JSON.stringify(result, null, 2));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Plain output
|
|
91
|
+
console.log(message);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
97
|
+
exitWithError(errorMessage, options);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=msg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg.js","sourceRoot":"","sources":["../../src/commands/msg.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/ai.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8B5C,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8B5C,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAOvD;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,4BAA4B,EACnC,MAAM,EAAE,QAAQ,GACf,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|
package/dist/utils/ai.js
CHANGED
|
@@ -29,6 +29,8 @@ export function createAIClient(config) {
|
|
|
29
29
|
return new OpenAI({
|
|
30
30
|
apiKey: config.apiKey || 'ollama',
|
|
31
31
|
baseURL: config.baseUrl,
|
|
32
|
+
timeout: 30000, // 30 second timeout
|
|
33
|
+
maxRetries: 2, // Built-in retry support
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
export async function generateCommitMessage(client, input, config) {
|
package/dist/utils/ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,wBAAwB,GAAG;;;;;;;;;;;;8CAYa,CAAC;AAE/C,MAAM,wBAAwB,GAAG;;;;;;;;;;;;6BAYJ,CAAC;AAE9B,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,OAAO,IAAI,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,wBAAwB,GAAG;;;;;;;;;;;;8CAYa,CAAC;AAE/C,MAAM,wBAAwB,GAAG;;;;;;;;;;;;6BAYJ,CAAC;AAE9B,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,OAAO,IAAI,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,KAAK,EAAE,oBAAoB;QACpC,UAAU,EAAE,CAAC,EAAG,yBAAyB;KAC1C,CAAC,CAAC;AACL,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,KAAmC,EACnC,MAAgB;IAEhB,MAAM,YAAY,GAChB,MAAM,CAAC,YAAY;QACnB,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;IAEjF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI;YACjB,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,sDAAsD,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CACR,IAAI;YACF,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,kDAAkD,CACvD,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,OAAO,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACpD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;SAC9C;QACD,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,GAAG;KAChB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|