ai-code-review-toolkit 0.0.2
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 +275 -0
- package/README.zh-CN.md +268 -0
- package/package.json +37 -0
- package/src/AIError.js +7 -0
- package/src/ai-review-cli.js +79 -0
- package/src/ai-review.js +392 -0
- package/src/cli.js +282 -0
- package/src/core.js +420 -0
- package/src/index.js +5 -0
- package/src/kb-index.js +251 -0
- package/src/prompts.js +63 -0
- package/src/providers/adapters/ollama.js +61 -0
- package/src/providers/adapters/openai.js +144 -0
- package/src/providers/base.js +120 -0
- package/src/providers/index.js +11 -0
- package/src/rag/embeddings.js +168 -0
- package/src/rag/fs.js +97 -0
- package/src/rag/index.js +121 -0
- package/src/rag/lancedb.js +14 -0
- package/src/rag/text.js +18 -0
- package/src/utils/openai.js +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# AI Code Review [中文文档](README.zh-CN.md)
|
|
2
|
+
|
|
3
|
+
AI-powered git pre-commit hook for automated code review with customizable rules.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🤖 **Multi-Model Support**: Works with OpenAI、Deepseek and Ollama、LM Studio
|
|
8
|
+
- 🔍 **Smart Diff Analysis**: Focuses on meaningful changes, ignores deletions
|
|
9
|
+
- ⚙️ **Customizable Rules**: Security, performance, style checks
|
|
10
|
+
- ✏️ **Custom Prompts**: Fully customize review criteria and prompts
|
|
11
|
+
- 📊 **Graded Feedback**: High/Medium/Low severity classification
|
|
12
|
+
- 🛠 **Easy Integration**: Simple npm install and config
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install --save-dev ai-code-review-kit
|
|
18
|
+
# or
|
|
19
|
+
yarn add -D ai-code-review-kit
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Add to git pre-commit hook:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx ai-review install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Check / uninstall / reinstall:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx ai-review check
|
|
32
|
+
npx ai-review uninstall
|
|
33
|
+
npx ai-review install --force
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or if you have husky installed:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx ai-review install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Yarn PnP is supported. If `.pnp.cjs` exists, the installed hook will prefer running via `yarn ai-review run` (fallback to `corepack yarn` if available).
|
|
43
|
+
|
|
44
|
+
Legacy (run by husky command):
|
|
45
|
+
|
|
46
|
+
```JSON
|
|
47
|
+
.package.json
|
|
48
|
+
{
|
|
49
|
+
"husky": {
|
|
50
|
+
"hooks": {
|
|
51
|
+
"pre-commit": "npx ai-review run"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
### Option 1: package.json
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
"aiCheckConfig": {
|
|
63
|
+
"providerType": "openai",
|
|
64
|
+
"apiKey": "your-api-key",
|
|
65
|
+
"model": "gpt-4",
|
|
66
|
+
"baseURL": "https://api.openai.com",
|
|
67
|
+
"timeoutMs": 120000,
|
|
68
|
+
"concurrency": 2,
|
|
69
|
+
"maxRetries": 1,
|
|
70
|
+
"retryDelayMs": 500,
|
|
71
|
+
"diffContextLines": 3,
|
|
72
|
+
"maxChunkSize": 4000,
|
|
73
|
+
"language": "english",
|
|
74
|
+
"ignoreDeletions": true,
|
|
75
|
+
"stripUnchangedCommentLines": true,
|
|
76
|
+
"checkSecurity": true,
|
|
77
|
+
"checkPerformance": true,
|
|
78
|
+
"checkStyle": false,
|
|
79
|
+
"enabledFileExtensions": ".html, .js, .jsx, .ts, .tsx, .vue"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Option 2: .env file
|
|
84
|
+
|
|
85
|
+
```env
|
|
86
|
+
providerType=openai
|
|
87
|
+
baseURL=http://localhost:11434
|
|
88
|
+
model=gpt-4
|
|
89
|
+
maxChunkSize=4000
|
|
90
|
+
language=chinese
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If both `package.json` (`aiCheckConfig`) and `.env` exist, configurations will be merged and `.env` will take precedence.
|
|
94
|
+
|
|
95
|
+
Environment variables (process.env) override both `.env` and `package.json`.
|
|
96
|
+
|
|
97
|
+
To avoid conflicts with common system env vars (e.g. `LANGUAGE`), this tool only reads:
|
|
98
|
+
|
|
99
|
+
- Exact config keys (case-sensitive), e.g. `providerType`, `baseURL`, `apiKey`
|
|
100
|
+
- Or prefixed keys (recommended): `AI_REVIEW_*` / `AI_CODE_REVIEW_KIT_*`, e.g. `AI_REVIEW_PROVIDER_TYPE`, `AI_REVIEW_BASE_URL`, `AI_REVIEW_API_KEY`
|
|
101
|
+
|
|
102
|
+
Note on `baseURL` / `embeddingsBaseURL`:
|
|
103
|
+
|
|
104
|
+
- Use an API root like `https://example.com` or `https://example.com/v1`.
|
|
105
|
+
- Avoid setting a full endpoint like `.../v1/responses` / `.../v1/chat/completions`. (The tool will try to normalize these, but root URLs are more predictable.)
|
|
106
|
+
|
|
107
|
+
## Knowledge Base (Local RAG)
|
|
108
|
+
|
|
109
|
+
This project supports a **local, project-level RAG** based on **LanceDB**.
|
|
110
|
+
|
|
111
|
+
Workflow:
|
|
112
|
+
|
|
113
|
+
1. Build index locally (one-time / incremental per your needs)
|
|
114
|
+
2. During review, the tool embeds the current diff chunk, retrieves top-K relevant snippets from the index, and injects them into the prompt.
|
|
115
|
+
3. If index is missing, RAG will be skipped automatically (fallback to normal review).
|
|
116
|
+
|
|
117
|
+
Build index:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx ai-review index
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Minimal config (add into `aiCheckConfig`):
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"enableRag": true,
|
|
128
|
+
"knowledgeBasePaths": ["."],
|
|
129
|
+
"knowledgeBaseIndexDir": ".ai-reviewer-cache/lancedb",
|
|
130
|
+
"knowledgeBaseTable": "project_kb",
|
|
131
|
+
"ragTopK": 6,
|
|
132
|
+
"ragMaxChars": 8000,
|
|
133
|
+
"embeddingsBaseURL": "https://api.openai.com",
|
|
134
|
+
"embeddingsModel": "text-embedding-3-small"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Notes:
|
|
139
|
+
|
|
140
|
+
- Cache directory: `.ai-reviewer-cache/` (recommended to keep ignored by git)
|
|
141
|
+
- LanceDB keeps historical versions by default. This tool prunes old versions after each `ai-review index` run to avoid unbounded cache growth. You can also safely delete `.ai-reviewer-cache/` anytime and rebuild.
|
|
142
|
+
- Embeddings config precedence:
|
|
143
|
+
- `embeddingsBaseURL/embeddingsApiKey/embeddingsModel` if provided
|
|
144
|
+
- otherwise fallback to `baseURL/apiKey` (if compatible)
|
|
145
|
+
|
|
146
|
+
### Full Configuration Options
|
|
147
|
+
|
|
148
|
+
| Parameter | Type | Default | Description |
|
|
149
|
+
|-----------|------|---------|-------------|
|
|
150
|
+
| providerType | string | "openai" | AI provider type (openai、deepseek、zhipu, ollama or LMStudio) |
|
|
151
|
+
| apiKey | string | - | Provider API key (not required for Ollama or LMStudio) |
|
|
152
|
+
| model | string | "gpt-3.5-turbo" | Model name |
|
|
153
|
+
| temperature | number | 0.2 | Controls randomness of AI output (higher = more random) |
|
|
154
|
+
| baseURL | string | `"https://api.openai.com"` (OpenAI)<br>`"https://api.deepseek.com"` (Deepseek)<br>`"https://open.bigmodel.cn/api/paas/v4"` (Zhipu)<br>`"http://localhost:11434"` (Ollama)<br>`"http://127.0.0.1:1234"` (LM Studio)| API base URL (can include or omit the `/v1` suffix) |
|
|
155
|
+
| useResponsesApi | boolean | false | Force using the Responses API (`/responses`) for OpenAI-compatible providers |
|
|
156
|
+
| timeoutMs | number | 120000 | Request timeout (ms) |
|
|
157
|
+
| concurrency | number | 2 | Max parallel AI requests |
|
|
158
|
+
| maxRetries | number | 1 | Retry count on transient API/format errors |
|
|
159
|
+
| retryDelayMs | number | 500 | Base retry delay (ms), exponential backoff |
|
|
160
|
+
| diffContextLines | number | 3 | `git diff --unified` context lines |
|
|
161
|
+
| maxChunkSize | number | 12000 | Max diff chunk size (characters) |
|
|
162
|
+
| customPrompts | string | '' |Custom prompt templates. When provided, these will completely replace the default security (checkSecurity), performance (checkPerformance) and style (checkStyle) checks. |
|
|
163
|
+
| language | string | "chinese" | Output language |
|
|
164
|
+
| strict | boolean | true | Fail on API errors |
|
|
165
|
+
| skipReview | boolean | false | Skip AI review (always pass) |
|
|
166
|
+
| correctedResult | boolean | true | When the result field in the AI's returned result does not match the specific detection item result in the list, the system will automatically correct the final determination result based on the actual detection problem. |
|
|
167
|
+
| showNormal | boolean | false | Show low/medium severity issues |
|
|
168
|
+
| ignoreDeletions | boolean | true | Remove deleted lines (`-...`) before sending diff to AI |
|
|
169
|
+
| stripUnchangedCommentLines | boolean | true | Remove unchanged comment-only context lines (e.g. ` // ...`) |
|
|
170
|
+
| checkSecurity | boolean | true | Enable security checks |
|
|
171
|
+
| checkPerformance | boolean | true | Enable performance checks |
|
|
172
|
+
| checkStyle | boolean | false | Enable style checks |
|
|
173
|
+
| enabledFileExtensions | string | '.html, .js, .jsx, .ts, .tsx, .vue' | File types to review |
|
|
174
|
+
| enableRag | boolean | false | Enable local RAG knowledge retrieval |
|
|
175
|
+
| knowledgeBasePaths | string\|string[] | '' | Paths to index (e.g. ["."] or "src,docs") |
|
|
176
|
+
| knowledgeBaseIndexDir | string | '.ai-reviewer-cache/lancedb' | LanceDB index directory (relative to repo root) |
|
|
177
|
+
| knowledgeBaseTable | string | 'project_kb' | LanceDB table name |
|
|
178
|
+
| ragTopK | number | 6 | Retrieve top K snippets |
|
|
179
|
+
| ragMaxChars | number | 8000 | Max chars injected into prompt |
|
|
180
|
+
| embeddingsProviderType | string | '' | Embeddings provider type (defaults to `providerType`) |
|
|
181
|
+
| embeddingsBaseURL | string | '' | Embeddings baseURL (provider default if omitted) |
|
|
182
|
+
| embeddingsApiKey | string | '' | API key for embeddings endpoint |
|
|
183
|
+
| embeddingsModel | string | provider default | Embeddings model (OpenAI: `text-embedding-3-small`, Zhipu: `embedding-3`) |
|
|
184
|
+
| embeddingsDimensions | number | null | Optional embeddings output dimensions (if supported by the model/provider) |
|
|
185
|
+
|
|
186
|
+
## Review Process
|
|
187
|
+
|
|
188
|
+
1. **Diff Extraction**: Gets staged changes via `git diff --cached`
|
|
189
|
+
2. **File Filtering**: Only processes specified file extensions
|
|
190
|
+
3. **Chunk Splitting**: Splits large diffs into manageable chunks
|
|
191
|
+
4. **AI Analysis**: Sends chunks to configured AI provider
|
|
192
|
+
5. **Result Aggregation**: Combines results from all chunks
|
|
193
|
+
6. **Output**: Displays issues grouped by severity
|
|
194
|
+
|
|
195
|
+
## Example Output
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
Find 1 changed files...
|
|
199
|
+
Running code review with AI: The content will be reviewed in 1 sessions for better accuracy.
|
|
200
|
+
|
|
201
|
+
X Code review was not passed.Please fix the following high-level issues and try again.
|
|
202
|
+
- src/auth.js: [高] - 安全问题 - 硬编码的API密钥
|
|
203
|
+
Suggested fix: 使用环境变量存储敏感信息
|
|
204
|
+
- src/db.js: [中] - 性能问题 - 缺少数据库连接池
|
|
205
|
+
Suggested fix: 实现连接池减少连接开销
|
|
206
|
+
|
|
207
|
+
√ Code review passed.
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Supported Providers
|
|
212
|
+
|
|
213
|
+
### OpenAI
|
|
214
|
+
|
|
215
|
+
- Required: `apiKey`
|
|
216
|
+
- Optional: `model` (default: gpt-3.5-turbo), `baseURL` (default: https://api.openai.com)
|
|
217
|
+
- Models: gpt-4, gpt-3.5-turbo
|
|
218
|
+
|
|
219
|
+
### Deepseek
|
|
220
|
+
|
|
221
|
+
- Required: `apiKey`
|
|
222
|
+
- Optional: `model` (default: deepseek-chat), `baseURL` (default: https://api.deepseek.com)
|
|
223
|
+
- Models: deepseek-chat、deepseek-reasoner
|
|
224
|
+
|
|
225
|
+
### Zhipu (BigModel)
|
|
226
|
+
|
|
227
|
+
- Required: `apiKey`
|
|
228
|
+
- Optional: `model` (default: glm-4), `baseURL` (default: https://open.bigmodel.cn/api/paas/v4)
|
|
229
|
+
- Embeddings: set `embeddingsProviderType: "zhipu"` and `embeddingsModel: "embedding-3"` (optional `embeddingsDimensions`)
|
|
230
|
+
|
|
231
|
+
### Ollama (Local AI Models)
|
|
232
|
+
|
|
233
|
+
- Required: None (runs locally)
|
|
234
|
+
- Optional: `model` (default: gpt-3.5-turbo), `baseURL` (default: http://localhost:11434)
|
|
235
|
+
- Setup:
|
|
236
|
+
1. Install Ollama: https://ollama.ai/
|
|
237
|
+
2. Download models: `ollama pull <model-name>`
|
|
238
|
+
3. Common models: llama2, codellama, mistral
|
|
239
|
+
- Example .env configuration:
|
|
240
|
+
```env
|
|
241
|
+
providerType=ollama
|
|
242
|
+
model=codellama
|
|
243
|
+
baseURL=http://localhost:11434
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### LMStudio (Local AI Models)
|
|
247
|
+
|
|
248
|
+
- Required: None (runs locally)
|
|
249
|
+
- Optional: `model` (default: qwen/qwq-32b), `baseURL` (default: http://127.0.0.1:1234)
|
|
250
|
+
|
|
251
|
+
## Troubleshooting
|
|
252
|
+
|
|
253
|
+
### Hook not running
|
|
254
|
+
|
|
255
|
+
- Verify `.git/hooks/pre-commit` exists and is executable
|
|
256
|
+
- Check file contains `node path/to/ai-review.js`
|
|
257
|
+
|
|
258
|
+
### API Errors
|
|
259
|
+
|
|
260
|
+
- Verify API key and base URL (not required for Ollama)
|
|
261
|
+
- Check network connectivity
|
|
262
|
+
- Set `strict: false` to allow commit on API errors
|
|
263
|
+
|
|
264
|
+
### No changes found
|
|
265
|
+
|
|
266
|
+
- Check `enabledFileExtensions` matches your file types
|
|
267
|
+
- Verify changes are staged (`git add`)
|
|
268
|
+
|
|
269
|
+
### The returned data format does not conform to the specification
|
|
270
|
+
|
|
271
|
+
The model fails to produce valid JSON output, indicating potential limitations in its instruction-following capability. Ensure the model is capable of generating structured data.
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
ISC
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# AI 代码审查 [English Md](README.md)
|
|
2
|
+
|
|
3
|
+
基于人工智能的git pre-commit钩子,提供自动化代码审查功能,支持自定义规则。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- 🤖 **多模型支持**: 支持OpenAI、Deepseek、Ollama和LM Studio
|
|
8
|
+
- 🔍 **智能差异分析**: 聚焦有意义的变更,忽略删除内容
|
|
9
|
+
- ⚙️ **可定制规则**: 安全检查、性能优化、代码风格
|
|
10
|
+
- ✏️ **自定义提示**: 完全自定义审查标准和提示词
|
|
11
|
+
- 📊 **分级反馈**: 高/中/低严重性分类
|
|
12
|
+
- 🛠 **简单集成**: 通过npm安装和配置
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install --save-dev ai-code-review-kit
|
|
18
|
+
# 或
|
|
19
|
+
yarn add -D ai-code-review-kit
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
添加到git pre-commit钩子:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx ai-review install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
检查 / 卸载 / 强制重装:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx ai-review check
|
|
32
|
+
npx ai-review uninstall
|
|
33
|
+
npx ai-review install --force
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
如果已安装husky:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx ai-review install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
支持 Yarn PnP:如果仓库根目录存在`.pnp.cjs`,已安装的 hook 会优先通过 `yarn ai-review run` 执行(若可用则回退到 `corepack yarn`)。
|
|
43
|
+
|
|
44
|
+
旧方式(由 husky 命令执行):
|
|
45
|
+
|
|
46
|
+
```JSON
|
|
47
|
+
.package.json
|
|
48
|
+
{
|
|
49
|
+
"husky": {
|
|
50
|
+
"hooks": {
|
|
51
|
+
"pre-commit": "npx ai-review run"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 配置
|
|
58
|
+
|
|
59
|
+
### 方式1: package.json
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
"aiCheckConfig": {
|
|
63
|
+
"providerType": "openai",
|
|
64
|
+
"apiKey": "your-api-key",
|
|
65
|
+
"model": "gpt-4",
|
|
66
|
+
"baseURL": "https://api.openai.com",
|
|
67
|
+
"timeoutMs": 120000,
|
|
68
|
+
"concurrency": 2,
|
|
69
|
+
"maxRetries": 1,
|
|
70
|
+
"retryDelayMs": 500,
|
|
71
|
+
"diffContextLines": 3,
|
|
72
|
+
"maxChunkSize": 4000,
|
|
73
|
+
"language": "english",
|
|
74
|
+
"ignoreDeletions": true,
|
|
75
|
+
"stripUnchangedCommentLines": true,
|
|
76
|
+
"checkSecurity": true,
|
|
77
|
+
"checkPerformance": true,
|
|
78
|
+
"checkStyle": false,
|
|
79
|
+
"enabledFileExtensions": ".html, .js, .jsx, .ts, .tsx, .vue"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 方式2: .env文件
|
|
84
|
+
|
|
85
|
+
```env
|
|
86
|
+
providerType=openai
|
|
87
|
+
baseURL=http://localhost:11434
|
|
88
|
+
model=gpt-4
|
|
89
|
+
maxChunkSize=4000
|
|
90
|
+
language=chinese
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
如果同时存在`package.json`(`aiCheckConfig`)和`.env`,将合并配置,并以`.env`优先。
|
|
94
|
+
|
|
95
|
+
环境变量(process.env)优先级最高,会覆盖 `.env` 和 `package.json`。
|
|
96
|
+
|
|
97
|
+
为避免与系统常见环境变量冲突(例如 `LANGUAGE`),本工具只会读取:
|
|
98
|
+
|
|
99
|
+
- 与配置项完全同名(区分大小写)的 env,例如 `providerType`、`baseURL`、`apiKey`
|
|
100
|
+
- 或带前缀(推荐)的 env:`AI_REVIEW_*` / `AI_CODE_REVIEW_KIT_*`,例如 `AI_REVIEW_PROVIDER_TYPE`、`AI_REVIEW_BASE_URL`、`AI_REVIEW_API_KEY`
|
|
101
|
+
|
|
102
|
+
关于 `baseURL` / `embeddingsBaseURL`:
|
|
103
|
+
|
|
104
|
+
- 建议填写 API 根路径,例如 `https://example.com` 或 `https://example.com/v1`
|
|
105
|
+
- 避免填写完整 endpoint,例如 `.../v1/responses` / `.../v1/chat/completions`(工具会尝试自动归一化,但根路径更稳定)
|
|
106
|
+
|
|
107
|
+
## 项目知识库(本地 RAG)
|
|
108
|
+
|
|
109
|
+
支持基于 **LanceDB** 的本地项目级 RAG:先离线构建索引,review 时针对当前 diff chunk 做向量检索,把相关片段注入到 prompt 中增强审查。
|
|
110
|
+
|
|
111
|
+
构建索引(手动触发):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx ai-review index
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
最小配置示例(写入 `aiCheckConfig`):
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"enableRag": true,
|
|
122
|
+
"knowledgeBasePaths": ["."],
|
|
123
|
+
"knowledgeBaseIndexDir": ".ai-reviewer-cache/lancedb",
|
|
124
|
+
"knowledgeBaseTable": "project_kb",
|
|
125
|
+
"ragTopK": 6,
|
|
126
|
+
"ragMaxChars": 8000,
|
|
127
|
+
"embeddingsBaseURL": "https://api.openai.com",
|
|
128
|
+
"embeddingsModel": "text-embedding-3-small"
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
说明:
|
|
133
|
+
|
|
134
|
+
- 缓存目录:`.ai-reviewer-cache/`(建议加入 gitignore,不提交)
|
|
135
|
+
- LanceDB 默认会保留历史版本。本工具会在每次 `ai-review index` 后自动清理旧版本,避免缓存无限增长;你也可以随时安全删除 `.ai-reviewer-cache/` 并重新构建。
|
|
136
|
+
- 若索引不存在,会提示你执行 `ai-review index`,并自动降级为普通 review(不会阻断)
|
|
137
|
+
- embeddings 配置优先级:优先使用 `embeddingsBaseURL/embeddingsApiKey/embeddingsModel`,否则回退到 `baseURL/apiKey`(需兼容 OpenAI embeddings 接口)
|
|
138
|
+
|
|
139
|
+
### 完整配置选项
|
|
140
|
+
|
|
141
|
+
| 参数 | 类型 | 默认值 | 描述 |
|
|
142
|
+
|-----------|------|---------|-------------|
|
|
143
|
+
| providerType | string | "openai" | AI提供商类型(openai、deepseek、zhipu、ollama或LMStudio) |
|
|
144
|
+
| apiKey | string | - | 提供商API密钥(Ollama和LM Studio不需要) |
|
|
145
|
+
| model | string | "gpt-3.5-turbo" | 模型名称 |
|
|
146
|
+
| temperature | number | 0.2 | 控制AI输出的随机性(值越高越随机) |
|
|
147
|
+
| baseURL | string | `"https://api.openai.com"` (OpenAI)<br>`"https://api.deepseek.com"` (Deepseek)<br>`"https://open.bigmodel.cn/api/paas/v4"` (智谱)<br>`"http://localhost:11434"` (Ollama)<br>`"http://127.0.0.1:1234"` (LM Studio)| API基础URL(可包含或省略`/v1`后缀) |
|
|
148
|
+
| useResponsesApi | boolean | false | 强制对 OpenAI 兼容提供商使用 Responses API(`/responses`) |
|
|
149
|
+
| timeoutMs | number | 120000 | 请求超时时间(毫秒) |
|
|
150
|
+
| concurrency | number | 2 | 最大并行AI请求数 |
|
|
151
|
+
| maxRetries | number | 1 | 调用失败/格式错误时的重试次数 |
|
|
152
|
+
| retryDelayMs | number | 500 | 重试基础延迟(毫秒),指数退避 |
|
|
153
|
+
| diffContextLines | number | 3 | `git diff --unified`上下文行数 |
|
|
154
|
+
| maxChunkSize | number | 12000 | 最大差异块大小(字符数) |
|
|
155
|
+
| customPrompts | string | '' |自定义提示模板。当提供时,将完全替换默认的安全(checkSecurity)、性能(checkPerformance)和风格(checkStyle)检查。 |
|
|
156
|
+
| language | string | "chinese" | 输出语言 |
|
|
157
|
+
| strict | boolean | true | 调用API时如果发生错误导致pre-commit结果不通过 |
|
|
158
|
+
| skipReview | boolean | false | 跳过 AI 审查(直接通过) |
|
|
159
|
+
| correctedResult | boolean | true | 当AI返回结果中的result字段与列表中特定检测项结果不匹配时,系统会根据实际检测问题自动修正最终判定结果。 |
|
|
160
|
+
| showNormal | boolean | false | 显示低/中严重性问题 |
|
|
161
|
+
| ignoreDeletions | boolean | true | 发送给AI前移除删除行(`-...`) |
|
|
162
|
+
| stripUnchangedCommentLines | boolean | true | 移除未变更的纯注释上下文行(例如` // ...`) |
|
|
163
|
+
| checkSecurity | boolean | true | 启用安全检查 |
|
|
164
|
+
| checkPerformance | boolean | true | 启用性能检查 |
|
|
165
|
+
| checkStyle | boolean | false | 启用风格检查 |
|
|
166
|
+
| enabledFileExtensions | string | '.html, .js, .jsx, .ts, .tsx, .vue' | 需要审查的文件类型 |
|
|
167
|
+
| enableRag | boolean | false | 开启本地 RAG 知识检索增强 |
|
|
168
|
+
| knowledgeBasePaths | string\|string[] | '' | 需要索引的路径(例如 ["."] 或 "src,docs") |
|
|
169
|
+
| knowledgeBaseIndexDir | string | '.ai-reviewer-cache/lancedb' | LanceDB 索引目录(相对仓库根目录) |
|
|
170
|
+
| knowledgeBaseTable | string | 'project_kb' | LanceDB 表名 |
|
|
171
|
+
| ragTopK | number | 6 | 检索 Top K 片段 |
|
|
172
|
+
| ragMaxChars | number | 8000 | 注入 prompt 的最大字符数 |
|
|
173
|
+
| embeddingsProviderType | string | '' | embeddings 提供商类型(默认跟随 `providerType`) |
|
|
174
|
+
| embeddingsBaseURL | string | '' | embeddings baseURL(不填则使用提供商默认值) |
|
|
175
|
+
| embeddingsApiKey | string | '' | embeddings 接口的 API key |
|
|
176
|
+
| embeddingsModel | string | 提供商默认 | embeddings 模型(OpenAI: `text-embedding-3-small`,智谱: `embedding-3`) |
|
|
177
|
+
| embeddingsDimensions | number | null | embeddings 输出维度(可选,需模型/服务端支持) |
|
|
178
|
+
|
|
179
|
+
## 审查流程
|
|
180
|
+
|
|
181
|
+
1. **差异提取**: 通过`git diff --cached`获取暂存变更
|
|
182
|
+
2. **文件过滤**: 仅处理指定扩展名的文件
|
|
183
|
+
3. **分块处理**: 将大差异分割为可管理的块
|
|
184
|
+
4. **AI分析**: 将块发送到配置的AI提供商
|
|
185
|
+
5. **结果聚合**: 合并所有块的结果
|
|
186
|
+
6. **输出**: 按严重性分组显示问题
|
|
187
|
+
|
|
188
|
+
## 示例输出
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
Find 1 changed files...
|
|
192
|
+
Running code review with AI: The content will be reviewed in 1 sessions for better accuracy.
|
|
193
|
+
|
|
194
|
+
X Code review was not passed.Please fix the following high-level issues and try again.
|
|
195
|
+
- src/auth.js: [高] - 安全问题 - 硬编码的API密钥
|
|
196
|
+
Suggested fix: 使用环境变量存储敏感信息
|
|
197
|
+
- src/db.js: [中] - 性能问题 - 缺少数据库连接池
|
|
198
|
+
Suggested fix: 实现连接池减少连接开销
|
|
199
|
+
|
|
200
|
+
√ Code review passed.
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## 支持的提供商
|
|
205
|
+
|
|
206
|
+
### OpenAI
|
|
207
|
+
|
|
208
|
+
- 必填: `apiKey`
|
|
209
|
+
- 可选: `model` (默认: gpt-3.5-turbo), `baseURL` (默认: https://api.openai.com)
|
|
210
|
+
- 模型: gpt-4, gpt-3.5-turbo
|
|
211
|
+
|
|
212
|
+
### Deepseek
|
|
213
|
+
|
|
214
|
+
- 必填: `apiKey`
|
|
215
|
+
- 可选: `model` (默认: deepseek-chat), `baseURL` (默认: https://api.deepseek.com)
|
|
216
|
+
- 模型: deepseek-chat、deepseek-reasoner
|
|
217
|
+
|
|
218
|
+
### 智谱(BigModel)
|
|
219
|
+
|
|
220
|
+
- 必填: `apiKey`
|
|
221
|
+
- 可选: `model`(默认: glm-4), `baseURL`(默认: https://open.bigmodel.cn/api/paas/v4)
|
|
222
|
+
- embeddings:建议设置 `embeddingsProviderType: "zhipu"` 且 `embeddingsModel: "embedding-3"`(可选 `embeddingsDimensions`)
|
|
223
|
+
|
|
224
|
+
### Ollama (本地AI模型)
|
|
225
|
+
|
|
226
|
+
- 必填: 无(本地运行)
|
|
227
|
+
- 可选: `model` (默认: gpt-3.5-turbo), `baseURL` (默认: http://localhost:11434)
|
|
228
|
+
- 设置:
|
|
229
|
+
1. 安装Ollama: https://ollama.ai/
|
|
230
|
+
2. 下载模型: `ollama pull <模型名称>`
|
|
231
|
+
3. 常用模型: llama2, codellama, mistral
|
|
232
|
+
- 示例.env配置:
|
|
233
|
+
```env
|
|
234
|
+
providerType=ollama
|
|
235
|
+
model=codellama
|
|
236
|
+
baseURL=http://localhost:11434
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### LMStudio (本地AI模型)
|
|
240
|
+
|
|
241
|
+
- 必填: 无(本地运行)
|
|
242
|
+
- 可选: `model` (默认: qwen/qwq-32b), `baseURL` (默认: http://127.0.0.1:1234)
|
|
243
|
+
|
|
244
|
+
## 故障排除
|
|
245
|
+
|
|
246
|
+
### 钩子未运行
|
|
247
|
+
|
|
248
|
+
- 检查`.git/hooks/pre-commit`是否存在且可执行
|
|
249
|
+
- 确认文件包含`node path/to/ai-review.js`
|
|
250
|
+
|
|
251
|
+
### API错误
|
|
252
|
+
|
|
253
|
+
- 验证API密钥和基础URL(Ollama不需要)
|
|
254
|
+
- 检查网络连接
|
|
255
|
+
- 设置`strict: false`允许API错误时提交
|
|
256
|
+
|
|
257
|
+
### 未发现变更
|
|
258
|
+
|
|
259
|
+
- 检查`enabledFileExtensions`是否匹配您的文件类型
|
|
260
|
+
- 确认变更已暂存(`git add`)
|
|
261
|
+
|
|
262
|
+
### The returned data format does not conform to the specification
|
|
263
|
+
|
|
264
|
+
模型未能生成有效的JSON输出,表明其遵循指令的能力可能有限。请确保模型能够生成结构化数据。
|
|
265
|
+
|
|
266
|
+
## 许可证
|
|
267
|
+
|
|
268
|
+
ISC
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-code-review-toolkit",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "AI-powered git code review toolkit with optional local RAG knowledge base",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"README.md",
|
|
13
|
+
"README.zh-CN.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"pre-commit": "node src/ai-review.js",
|
|
17
|
+
"test": "node --test"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"ai-review": "./src/ai-review-cli.js"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ai",
|
|
24
|
+
"code-review",
|
|
25
|
+
"git",
|
|
26
|
+
"git-hooks",
|
|
27
|
+
"rag",
|
|
28
|
+
"lancedb"
|
|
29
|
+
],
|
|
30
|
+
"author": "puppy,liweihao",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@lancedb/lancedb": "^0.26.2",
|
|
34
|
+
"axios": "^1.13.6",
|
|
35
|
+
"chalk": "^5.4.1"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/AIError.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import { main as hookMain } from './cli.js'
|
|
5
|
+
import { main as runMain } from './ai-review.js'
|
|
6
|
+
import { main as indexMain } from './kb-index.js'
|
|
7
|
+
|
|
8
|
+
function printHelp() {
|
|
9
|
+
console.log(`Usage: ai-review <command> [options]
|
|
10
|
+
|
|
11
|
+
Commands:
|
|
12
|
+
install Install git pre-commit hook (auto-detect husky)
|
|
13
|
+
check Check whether hook is installed
|
|
14
|
+
uninstall Remove installed hook block
|
|
15
|
+
run Run code review for staged changes
|
|
16
|
+
index Build local RAG knowledge index (LanceDB)
|
|
17
|
+
`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function hasTargetArg(args) {
|
|
21
|
+
return args.some((a, i) => {
|
|
22
|
+
if (a === '--target' || a === '-t') return true
|
|
23
|
+
if (typeof a === 'string' && a.startsWith('--target=')) return true
|
|
24
|
+
// -t <value> handled above
|
|
25
|
+
return false
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
30
|
+
const [command, ...rest] = argv
|
|
31
|
+
if (!command || command === '-h' || command === '--help') {
|
|
32
|
+
printHelp()
|
|
33
|
+
process.exit(command ? 0 : 1)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (command === 'install') {
|
|
37
|
+
const args = [...rest]
|
|
38
|
+
if (!hasTargetArg(args)) {
|
|
39
|
+
args.unshift('auto')
|
|
40
|
+
args.unshift('--target')
|
|
41
|
+
}
|
|
42
|
+
return hookMain(args)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (command === 'check') {
|
|
46
|
+
const args = [...rest]
|
|
47
|
+
if (!hasTargetArg(args)) {
|
|
48
|
+
args.unshift('auto')
|
|
49
|
+
args.unshift('--target')
|
|
50
|
+
}
|
|
51
|
+
return hookMain(['--check', ...args])
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (command === 'uninstall' || command === 'remove') {
|
|
55
|
+
const args = [...rest]
|
|
56
|
+
if (!hasTargetArg(args)) {
|
|
57
|
+
args.unshift('auto')
|
|
58
|
+
args.unshift('--target')
|
|
59
|
+
}
|
|
60
|
+
return hookMain(['--uninstall', ...args])
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (command === 'run') {
|
|
64
|
+
return await runMain(rest)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (command === 'index') {
|
|
68
|
+
return await indexMain(rest)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.error(chalk.red(`Unknown command: ${command}`))
|
|
72
|
+
printHelp()
|
|
73
|
+
process.exit(1)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main().catch((err) => {
|
|
77
|
+
console.error(chalk.red(err?.message || err))
|
|
78
|
+
process.exit(1)
|
|
79
|
+
})
|