code-gate 0.1.0 → 1.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/LICENSE +21 -0
- package/README.md +222 -114
- package/README_ZH.md +224 -0
- package/bin/code-gate.js +12 -19
- package/dist/__tests__/config.test.js +1 -1
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/render.test.js +24 -7
- package/dist/__tests__/render.test.js.map +1 -1
- package/dist/cli/commands/hook.d.ts +1 -0
- package/dist/cli/commands/hook.js +164 -0
- package/dist/cli/commands/hook.js.map +1 -0
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.js +157 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +1 -0
- package/dist/cli/commands/setup.js +19 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +26 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/hook.js +7 -0
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/init.js +20 -20
- package/dist/config/defaults.d.ts +2 -0
- package/dist/config/defaults.js +33 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +77 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +55 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config.d.ts +111 -21
- package/dist/config.js +83 -21
- package/dist/config.js.map +1 -1
- package/dist/core/git.d.ts +7 -0
- package/dist/core/git.js +67 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/review-flow.js +105 -59
- package/dist/core/review-flow.js.map +1 -1
- package/dist/core/review.d.ts +6 -0
- package/dist/core/review.js +167 -0
- package/dist/core/review.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/llm/base.d.ts +14 -0
- package/dist/llm/base.js +10 -0
- package/dist/llm/base.js.map +1 -0
- package/dist/llm/deepseek.js +3 -3
- package/dist/llm/deepseek.js.map +1 -1
- package/dist/llm/index.d.ts +4 -0
- package/dist/llm/index.js +41 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/ollama.js +2 -2
- package/dist/llm/ollama.js.map +1 -1
- package/dist/llm/providers/aliyun.d.ts +4 -0
- package/dist/llm/providers/aliyun.js +25 -0
- package/dist/llm/providers/aliyun.js.map +1 -0
- package/dist/llm/providers/anthropic.d.ts +4 -0
- package/dist/llm/providers/anthropic.js +52 -0
- package/dist/llm/providers/anthropic.js.map +1 -0
- package/dist/llm/providers/azure.d.ts +4 -0
- package/dist/llm/providers/azure.js +38 -0
- package/dist/llm/providers/azure.js.map +1 -0
- package/dist/llm/providers/cohere.d.ts +4 -0
- package/dist/llm/providers/cohere.js +39 -0
- package/dist/llm/providers/cohere.js.map +1 -0
- package/dist/llm/providers/deepseek.d.ts +4 -0
- package/dist/llm/providers/deepseek.js +25 -0
- package/dist/llm/providers/deepseek.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +4 -0
- package/dist/llm/providers/gemini.js +40 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/providers/mistral.d.ts +4 -0
- package/dist/llm/providers/mistral.js +42 -0
- package/dist/llm/providers/mistral.js.map +1 -0
- package/dist/llm/providers/ollama.d.ts +5 -0
- package/dist/llm/providers/ollama.js +67 -0
- package/dist/llm/providers/ollama.js.map +1 -0
- package/dist/llm/providers/openai.d.ts +4 -0
- package/dist/llm/providers/openai.js +27 -0
- package/dist/llm/providers/openai.js.map +1 -0
- package/dist/llm/providers/volcengine.d.ts +4 -0
- package/dist/llm/providers/volcengine.js +29 -0
- package/dist/llm/providers/volcengine.js.map +1 -0
- package/dist/llm/providers/zhipu.d.ts +4 -0
- package/dist/llm/providers/zhipu.js +25 -0
- package/dist/llm/providers/zhipu.js.map +1 -0
- package/dist/locales/de.d.ts +2 -0
- package/dist/locales/de.js +33 -0
- package/dist/locales/de.js.map +1 -0
- package/dist/locales/en.d.ts +2 -0
- package/dist/locales/en.js +33 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/fr.d.ts +2 -0
- package/dist/locales/fr.js +33 -0
- package/dist/locales/fr.js.map +1 -0
- package/dist/locales/index.d.ts +3 -0
- package/dist/locales/index.js +41 -0
- package/dist/locales/index.js.map +1 -0
- package/dist/locales/ja.d.ts +2 -0
- package/dist/locales/ja.js +33 -0
- package/dist/locales/ja.js.map +1 -0
- package/dist/locales/ko.d.ts +2 -0
- package/dist/locales/ko.js +33 -0
- package/dist/locales/ko.js.map +1 -0
- package/dist/locales/types.d.ts +32 -0
- package/dist/locales/types.js +2 -0
- package/dist/locales/types.js.map +1 -0
- package/dist/locales/zh-CN.d.ts +2 -0
- package/dist/locales/zh-CN.js +33 -0
- package/dist/locales/zh-CN.js.map +1 -0
- package/dist/locales/zh-TW.d.ts +2 -0
- package/dist/locales/zh-TW.js +33 -0
- package/dist/locales/zh-TW.js.map +1 -0
- package/dist/ui/render/assets.d.ts +8 -0
- package/dist/ui/render/assets.js +89 -0
- package/dist/ui/render/assets.js.map +1 -0
- package/dist/ui/render/html.d.ts +35 -0
- package/dist/ui/render/html.js +295 -0
- package/dist/ui/render/html.js.map +1 -0
- package/dist/ui/render.d.ts +11 -0
- package/dist/ui/render.js +198 -13
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/server.d.ts +4 -2
- package/dist/ui/server.js +30 -8
- package/dist/ui/server.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.js +10 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +27 -8
- package/scripts/hook.sh +12 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 鸡斯拉
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,118 +1,226 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="Code Gate Logo" width="120" />
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
[English](./README.md) | [简体中文](./README_ZH.md)
|
|
6
|
+
|
|
7
|
+
# Code Gate
|
|
8
|
+
|
|
9
|
+
**Your Lightweight Local AI Code Review Assistant**
|
|
10
|
+
|
|
11
|
+
Code Gate is an intelligent code review tool seamlessly integrated into your Git workflow. When you run `git commit`, it automatically analyzes staged code changes, utilizing local LLMs (Ollama) or cloud AI services to provide instant feedback on code quality, security suggestions, and optimization plans.
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
- **🔒 Privacy First**: Native support for Ollama local models.
|
|
16
|
+
- **☁️ Multi-Model Support**: Seamlessly integrates with DeepSeek, OpenAI, Anthropic, Aliyun Qwen, Doubao, and more.
|
|
17
|
+
- **🌍 Multi-Language**: Built-in support for English, Chinese (Simplified & Traditional), Japanese, Korean, German, and French.
|
|
18
|
+
- **⚡️ High Performance**: Intelligent concurrent processing for faster reviews across multiple files.
|
|
19
|
+
- **🛠️ Highly Customizable**: Custom prompts, file filtering rules, and review strategies.
|
|
20
|
+
- **📊 Visual Reports**: Generates intuitive HTML review reports with clear diffs and AI suggestions.
|
|
21
|
+
|
|
22
|
+
## 🚀 Quick Start
|
|
23
|
+
|
|
24
|
+
### 1. Installation
|
|
25
|
+
|
|
26
|
+
Install `code-gate` as a development dependency:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm i -D code-gate
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Initialization
|
|
33
|
+
|
|
34
|
+
We provide a one-click initialization command to configure Git Hooks.
|
|
35
|
+
|
|
36
|
+
**Automatic Init (Recommended)**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Interactive selection for Git Hooks or Husky
|
|
40
|
+
npx code-gate init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
You can also specify arguments if you prefer a specific hook manager:
|
|
44
|
+
|
|
45
|
+
- **Native Git Hooks**: `npx code-gate init -m git`
|
|
46
|
+
- **Husky**: `npx code-gate init -m husky`
|
|
47
|
+
|
|
48
|
+
> After initialization, you can choose to add the generated config file to `.gitignore`.
|
|
49
|
+
|
|
50
|
+
### 3. Usage
|
|
51
|
+
|
|
52
|
+
Just commit your code as usual:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git add .
|
|
56
|
+
git commit -m "feat: new feature"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Code Gate intercepts the commit:
|
|
60
|
+
1. Analyzes code changes.
|
|
61
|
+
<div align="left" style="margin-left: 20px">
|
|
62
|
+
<img src="assets/step1.png" width="300" />
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
2. Starts a local server and generates a review report.
|
|
66
|
+
|
|
67
|
+
3. Automatically opens the report in your browser.
|
|
68
|
+
<div align="left">
|
|
69
|
+
<img src="assets/step2.png" width="600" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
4. You choose to **Confirm Commit** or **Cancel** in the terminal.
|
|
73
|
+
<div align="left" style="margin-left: 20px">
|
|
74
|
+
<img src="assets/step3.png" width="300" />
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## ⚙️ Configuration
|
|
80
|
+
|
|
81
|
+
The `code-gate.config.js` in your project root controls all behaviors.
|
|
82
|
+
|
|
83
|
+
### Basic Configuration
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
export default {
|
|
87
|
+
provider: 'ollama',
|
|
88
|
+
providerOptions: {
|
|
89
|
+
ollama: {
|
|
90
|
+
baseURL: 'http://localhost:11434',
|
|
91
|
+
model: 'qwen2.5-coder',
|
|
92
|
+
concurrencyFiles: 1
|
|
93
|
+
},
|
|
94
|
+
deepseek: {
|
|
95
|
+
baseURL: 'https://api.deepseek.com',
|
|
96
|
+
apiKeyEnv: 'DEEPSEEK_API_KEY',
|
|
97
|
+
model: 'deepseek-chat',
|
|
98
|
+
concurrencyFiles: 4
|
|
99
|
+
}
|
|
100
|
+
// openai: { baseURL: 'https://api.openai.com/v1', apiKeyEnv: 'OPENAI_API_KEY', model: 'gpt-4o-mini' },
|
|
101
|
+
// anthropic: { baseURL: 'https://api.anthropic.com', apiKeyEnv: 'ANTHROPIC_API_KEY', model: 'claude-3-5-sonnet' },
|
|
102
|
+
// azureOpenAI: { endpoint: 'https://your-endpoint.openai.azure.com', apiKeyEnv: 'AZURE_OPENAI_KEY', deployment: 'gpt-4o-mini', apiVersion: '2024-08-01-preview' },
|
|
103
|
+
// aliyun: { baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', apiKeyEnv: 'DASHSCOPE_API_KEY', model: 'qwen-plus' },
|
|
104
|
+
// volcengine: { baseURL: 'https://ark.cn-beijing.volces.com/api/v3', apiKeyEnv: 'VOLCENGINE_API_KEY', model: 'doubao-pro-32k' },
|
|
105
|
+
// zhipu: { baseURL: 'https://open.bigmodel.cn/api/paas/v4', apiKeyEnv: 'ZHIPU_API_KEY', model: 'glm-4' }
|
|
106
|
+
},
|
|
107
|
+
language: 'en',
|
|
108
|
+
fileTypes: ['ts', 'tsx', 'css'],
|
|
109
|
+
ui: {
|
|
110
|
+
openBrowser: true,
|
|
111
|
+
port: 5175
|
|
112
|
+
},
|
|
113
|
+
limits: {
|
|
114
|
+
maxDiffLines: 10000,
|
|
115
|
+
maxFiles: 100
|
|
116
|
+
},
|
|
117
|
+
prompt: 'as a senior code reviewer, please review the code changes and provide feedback on security, performance, code style, and test coverage. Highlight any issues or areas for improvement, and offer concrete suggestions with code examples if possible.',
|
|
118
|
+
output: {
|
|
119
|
+
dir: '.review-logs'
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### API Key Configuration
|
|
125
|
+
|
|
126
|
+
Choose the appropriate configuration scheme based on your project needs. Taking deepseek as an example.
|
|
127
|
+
For security, avoid hardcoding API Keys in the config file.
|
|
128
|
+
|
|
129
|
+
**Option A: Config File**
|
|
130
|
+
|
|
131
|
+
Set in `.code-gate.js`:
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
77
134
|
export default {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
ui: { openBrowser: true, theme: 'github', port: 5175 },
|
|
85
|
-
limits: { maxDiffLines: 10000, maxFiles: 100 },
|
|
86
|
-
rules: { focus: ['security', 'performance', 'style', 'tests'] },
|
|
87
|
-
prompt: '作为资深代码审查工程师,从安全、性能、代码风格与测试覆盖角度审查本次变更,指出问题与改进建议,并给出必要的示例补丁。',
|
|
88
|
-
output: { dir: '.code-gate' }
|
|
135
|
+
providerOptions: {
|
|
136
|
+
deepseek: {
|
|
137
|
+
// ...other config
|
|
138
|
+
apiKey: 'your-deepseek-api-key'
|
|
139
|
+
}
|
|
140
|
+
}
|
|
89
141
|
}
|
|
90
142
|
```
|
|
91
143
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
-
|
|
118
|
-
|
|
144
|
+
**Option B: Git Hook Injection**
|
|
145
|
+
|
|
146
|
+
Export temporarily in `.githooks/pre-commit` or `.husky/pre-commit`:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
#!/bin/sh
|
|
150
|
+
export DEEPSEEK_API_KEY=[your-deepseek-api-key]
|
|
151
|
+
./node_modules/.bin/code-gate-hook
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Option C: Environment Variables (Recommended)**
|
|
155
|
+
|
|
156
|
+
Set in your `.env` file or system environment:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
export DEEPSEEK_API_KEY=[your-deepseek-api-key]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 📖 Configuration Details
|
|
163
|
+
|
|
164
|
+
| Parameter | Type | Default | Description |
|
|
165
|
+
| :--- | :--- | :--- | :--- |
|
|
166
|
+
| `provider` | `string` | `'ollama'` | AI Provider. Supports `ollama`, `deepseek`, `openai`, `anthropic`, `aliyun`, `volcengine`, `zhipu`, etc. |
|
|
167
|
+
| `providerOptions` | `object` | `{}` | Specific configurations for each Provider (see table below) |
|
|
168
|
+
| `fileTypes` | `string[]` | `[]` | List of file extensions to review (whitelist). Reviews all files if empty or undefined. |
|
|
169
|
+
| `exclude` | `string[]` | `['**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml']` | List of files or directories to ignore (blacklist), supports glob patterns (e.g., `node_modules/**`). Higher priority than `fileTypes`. |
|
|
170
|
+
| `ui.openBrowser` | `boolean` | `true` | Auto-open browser for report preview |
|
|
171
|
+
| `ui.port` | `number` | `5175` | Preview server port |
|
|
172
|
+
| `limits.maxDiffLines` | `number` | `10000` | Max diff lines per review. Exceeding may cause incomplete review or excessive token usage. |
|
|
173
|
+
| `limits.maxFiles` | `number` | `100` | Max number of files to review |
|
|
174
|
+
| `reviewMode` | `string` | `'files'` | Review Mode: `'summary'` (summary only), `'files'` (file details only), `'both'` (both) |
|
|
175
|
+
| `language` | `string` | `'en'` | UI & Prompt Language. Options: `'en'`, `'zh-CN'`, `'zh-TW'`, `'ja'`, `'ko'`, `'de'`, `'fr'` |
|
|
176
|
+
| `prompt` | `string` | `...` | Universal system prompt sent to AI |
|
|
177
|
+
| `output.dir` | `string` | `'.review-logs'` | Output directory for local reports and static assets |
|
|
178
|
+
|
|
179
|
+
### providerOptions Configuration
|
|
180
|
+
|
|
181
|
+
Each Provider supports the following fields, with `request` option for timeout and retry control.
|
|
182
|
+
|
|
183
|
+
**Key Parameters:**
|
|
184
|
+
- `baseURL`: API base URL (e.g., `https://api.deepseek.com` or `http://localhost:11434`)
|
|
185
|
+
- `apiKey`: API Key (specified directly in config, not recommended for committing)
|
|
186
|
+
- `apiKeyEnv`: Environment variable name storing the API Key (Recommended, e.g., `DEEPSEEK_API_KEY`)
|
|
187
|
+
- `model`: Model name to use (e.g., `deepseek-chat`, `qwen2.5-coder`)
|
|
188
|
+
- `concurrencyFiles`: Number of concurrent file reviews (Recommended: Cloud API 4-8, Local Model 1)
|
|
189
|
+
- `request`: Advanced request configuration (see "Advanced Configuration" below)
|
|
190
|
+
|
|
191
|
+
| Provider | Configurable Parameters |
|
|
192
|
+
| :--- | :--- |
|
|
193
|
+
| **deepseek** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `concurrencyFiles`, `request` |
|
|
194
|
+
| **ollama** | `baseURL`, `model`, `concurrencyFiles`, `request` |
|
|
195
|
+
| **openai** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
196
|
+
| **anthropic** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
197
|
+
| **aliyun** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
198
|
+
| **volcengine** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
199
|
+
| **zhipu** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
200
|
+
| **azureOpenAI** | `endpoint`, `apiKey`, `apiKeyEnv`, `deployment`, `apiVersion`, `request` |
|
|
201
|
+
|
|
202
|
+
#### Advanced Configuration (request)
|
|
203
|
+
|
|
204
|
+
Configure in `providerOptions.<provider>.request` to control request behavior:
|
|
205
|
+
|
|
206
|
+
| Parameter | Type | Default | Description |
|
|
207
|
+
| :--- | :--- | :--- | :--- |
|
|
208
|
+
| `timeout` | `number` | `undefined` | Request timeout (ms). Recommended to set higher for Ollama (e.g., 15000+) |
|
|
209
|
+
| `retries` | `number` | `0` | Number of retries on request failure |
|
|
210
|
+
| `backoffMs` | `number` | `300` | Retry interval (ms) |
|
|
211
|
+
|
|
212
|
+
> **Note**: `concurrencyFiles` controls the number of concurrent file reviews (Default: DeepSeek=4, Ollama=1, Others=4).
|
|
213
|
+
|
|
214
|
+
## ❓ FAQ
|
|
215
|
+
|
|
216
|
+
**Q: Report shows diffs but no AI suggestions?**
|
|
217
|
+
- Check `provider` configuration.
|
|
218
|
+
- If using Ollama, ensure local service is running (`ollama serve`) and model is pulled (`ollama pull qwen2.5-coder`).
|
|
219
|
+
- If using Cloud API, check API Key validity and network connection.
|
|
220
|
+
|
|
221
|
+
**Q: How to skip review in CI/CD?**
|
|
222
|
+
Code Gate detects non-interactive environments and skips automatically. To force skip, use `git commit --no-verify`.
|
|
223
|
+
|
|
224
|
+
## 📄 License
|
|
225
|
+
|
|
226
|
+
MIT
|
package/README_ZH.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="Code Gate Logo" width="120" />
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
[English](./README.md) | [简体中文](./README_ZH.md)
|
|
6
|
+
|
|
7
|
+
# Code Gate
|
|
8
|
+
|
|
9
|
+
**您的轻量级本地 AI 代码审查助手**
|
|
10
|
+
|
|
11
|
+
Code Gate 是一款无缝集成到 Git 工作流中的智能代码审查工具。在您执行 `git commit` 时,它会自动分析暂存区(Staged)的代码变更,利用本地 LLM (Ollama) 或云端 AI 服务为您提供即时的代码质量反馈、安全建议和优化方案。
|
|
12
|
+
|
|
13
|
+
## ✨ 核心特性
|
|
14
|
+
|
|
15
|
+
- **🔒 数据隐私优先**:原生支持 Ollama 本地模型。
|
|
16
|
+
- **☁️ 多模型支持**:无缝对接 DeepSeek, OpenAI, Anthropic, 阿里云 Qwen, 豆包等主流 AI 服务。
|
|
17
|
+
- **🌍 多语言界面**:内置中(简/繁)、英、日、韩、德、法等多语言支持。
|
|
18
|
+
- **⚡️ 高效并发**:智能并发处理多文件审查,提升 Review 速度。
|
|
19
|
+
- **🛠️ 高度可定制**:支持自定义 Prompt、文件过滤规则及审查策略。
|
|
20
|
+
- **📊 可视化报告**:生成直观的 HTML 审查报告,提供清晰的 Diff 对比与 AI 建议。
|
|
21
|
+
|
|
22
|
+
## 🚀 快速开始
|
|
23
|
+
|
|
24
|
+
### 1. 安装
|
|
25
|
+
|
|
26
|
+
在项目中安装 `code-gate` 作为开发依赖:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm i -D code-gate
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. 初始化
|
|
33
|
+
|
|
34
|
+
提供一键初始化命令,自动配置 Git Hooks。
|
|
35
|
+
|
|
36
|
+
**自动初始化(推荐)**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 交互式选择 Git Hooks 或 Husky
|
|
40
|
+
npx code-gate init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
如果您已明确使用某种 Hook 管理方式,可以指定对应参数:
|
|
44
|
+
|
|
45
|
+
- **原生 Git Hooks**: `npx code-gate init -m git`
|
|
46
|
+
- **Husky**: `npx code-gate init -m husky`
|
|
47
|
+
|
|
48
|
+
> 初始化完成后,您可选择将生成的配置文件添加到 `.gitignore` 中。
|
|
49
|
+
|
|
50
|
+
### 3. 开始使用
|
|
51
|
+
|
|
52
|
+
只需像往常一样提交代码:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git add .
|
|
56
|
+
git commit -m "feat: new feature"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Code Gate 会自动拦截提交:
|
|
60
|
+
1. 分析代码变更。
|
|
61
|
+
<div align="left" style="margin-left: 20px">
|
|
62
|
+
<img src="assets/step1_cn.png" width="300" />
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
2. 启动本地服务并生成审查报告。
|
|
66
|
+
|
|
67
|
+
3. 自动打开浏览器展示报告。
|
|
68
|
+
<div align="left">
|
|
69
|
+
<img src="assets/step2_cn.png" width="600" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
4. 您可以在终端选择 **继续提交** 或 **取消修改**。
|
|
73
|
+
<div align="left" style="margin-left: 20px">
|
|
74
|
+
<img src="assets/step3_cn.png" width="300" />
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## ⚙️ 配置指南
|
|
80
|
+
|
|
81
|
+
在项目根目录下 `.code-gate.js` 配置
|
|
82
|
+
|
|
83
|
+
### 基础配置示例
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
export default {
|
|
87
|
+
provider: 'ollama',
|
|
88
|
+
providerOptions: {
|
|
89
|
+
ollama: {
|
|
90
|
+
baseURL: 'http://localhost:11434',
|
|
91
|
+
model: 'qwen2.5-coder',
|
|
92
|
+
concurrencyFiles: 1
|
|
93
|
+
},
|
|
94
|
+
deepseek: {
|
|
95
|
+
baseURL: 'https://api.deepseek.com',
|
|
96
|
+
apiKeyEnv: 'DEEPSEEK_API_KEY',
|
|
97
|
+
model: 'deepseek-chat',
|
|
98
|
+
concurrencyFiles: 4
|
|
99
|
+
}
|
|
100
|
+
// openai: { baseURL: 'https://api.openai.com/v1', apiKeyEnv: 'OPENAI_API_KEY', model: 'gpt-4o-mini' },
|
|
101
|
+
// anthropic: { baseURL: 'https://api.anthropic.com', apiKeyEnv: 'ANTHROPIC_API_KEY', model: 'claude-3-5-sonnet' },
|
|
102
|
+
// azureOpenAI: { endpoint: 'https://your-endpoint.openai.azure.com', apiKeyEnv: 'AZURE_OPENAI_KEY', deployment: 'gpt-4o-mini', apiVersion: '2024-08-01-preview' },
|
|
103
|
+
// aliyun: { baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', apiKeyEnv: 'DASHSCOPE_API_KEY', model: 'qwen-plus' },
|
|
104
|
+
// volcengine: { baseURL: 'https://ark.cn-beijing.volces.com/api/v3', apiKeyEnv: 'VOLCENGINE_API_KEY', model: 'doubao-pro-32k' },
|
|
105
|
+
// zhipu: { baseURL: 'https://open.bigmodel.cn/api/paas/v4', apiKeyEnv: 'ZHIPU_API_KEY', model: 'glm-4' }
|
|
106
|
+
},
|
|
107
|
+
language: 'zh-CN',
|
|
108
|
+
fileTypes: ['ts', 'tsx', 'css'],
|
|
109
|
+
ui: {
|
|
110
|
+
openBrowser: true,
|
|
111
|
+
port: 5175
|
|
112
|
+
},
|
|
113
|
+
limits: {
|
|
114
|
+
maxDiffLines: 10000,
|
|
115
|
+
maxFiles: 100
|
|
116
|
+
},
|
|
117
|
+
prompt: '作为资深代码审查工程师,从安全、性能、代码风格与测试覆盖角度审查本次变更,指出问题与改进建议,并给出必要的示例补丁。',
|
|
118
|
+
output: {
|
|
119
|
+
dir: '.review-logs'
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### API Key 配置方案
|
|
125
|
+
|
|
126
|
+
根据自己项目需要,选择合适的配置方案。这里以deepseek为例。
|
|
127
|
+
为了安全起见,建议不要将 API Key 暴露到公共仓库中。
|
|
128
|
+
|
|
129
|
+
**方案 A:配置文件中**
|
|
130
|
+
|
|
131
|
+
在 `.code-gate.js` 中设置:
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
export default {
|
|
135
|
+
providerOptions: {
|
|
136
|
+
deepseek: {
|
|
137
|
+
// ...其他配置
|
|
138
|
+
apiKey: 'your-deepseek-api-key'
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**方案 B:Git Hook 注入**
|
|
145
|
+
|
|
146
|
+
在 `.githooks/pre-commit` 或 `.husky/pre-commit` 中临时导出:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
#!/bin/sh
|
|
150
|
+
export DEEPSEEK_API_KEY=[your-deepseek-api-key]
|
|
151
|
+
./node_modules/.bin/code-gate-hook
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**方案 C:环境变量**
|
|
155
|
+
|
|
156
|
+
在 `.env` 文件或系统环境变量中设置:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
export DEEPSEEK_API_KEY=[your-deepseek-api-key]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 📖 配置详解
|
|
163
|
+
|
|
164
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
165
|
+
| :--- | :--- | :--- | :--- |
|
|
166
|
+
| `provider` | `string` | `'ollama'` | 选择使用的 AI 审查引擎。可选值: `'ollama'`, `'deepseek'`, `'openai'`, `'anthropic'`, `'aliyun'`, `'volcengine'`, `'zhipu'` 等 |
|
|
167
|
+
| `providerOptions` | `object` | `{}` | 各 Provider 的具体配置集合(见下表) |
|
|
168
|
+
| `fileTypes` | `string[]` | `[]` | 需要审查的文件类型扩展名列表(白名单)。若为空数组或未配置,则审查所有文件。 |
|
|
169
|
+
| `exclude` | `string[]` | `['**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml']` | 不需要审查的文件或目录列表(黑名单),支持 glob 模式匹配(如 `node_modules/**`)。优先级高于 `fileTypes`。 |
|
|
170
|
+
| `ui.openBrowser` | `boolean` | `true` | 是否自动打开浏览器预览 |
|
|
171
|
+
| `ui.port` | `number` | `5175` | 预览服务端口 |
|
|
172
|
+
| `limits.maxDiffLines` | `number` | `10000` | 最大 diff 行数,超出限制可能导致审查不完整或消耗过多 Token |
|
|
173
|
+
| `limits.maxFiles` | `number` | `100` | 最大审查文件数 |
|
|
174
|
+
| `reviewMode` | `string` | `'files'` | 审查模式:`'summary'` (仅汇总), `'files'` (仅文件详情), `'both'` (两者都有) |
|
|
175
|
+
| `language` | `string` | `'en'` | 界面与 Prompt 语言。可选值:`'en'`, `'zh-CN'`, `'zh-TW'`, `'ja'`, `'ko'`, `'de'`, `'fr'` |
|
|
176
|
+
| `prompt` | `string` | `...` | 发送给 AI 的通用系统提示词 |
|
|
177
|
+
| `output.dir` | `string` | `'.review-logs'` | 本地生成报告和静态资源的输出目录 |
|
|
178
|
+
|
|
179
|
+
### providerOptions 配置
|
|
180
|
+
每个 Provider 可配置以下字段,支持 `request` 选项控制请求超时与重试。
|
|
181
|
+
|
|
182
|
+
**关键参数说明:**
|
|
183
|
+
- `baseURL`: API 基础地址(如 `https://api.deepseek.com` 或 `http://localhost:11434`)
|
|
184
|
+
- `apiKey`: API 密钥(直接在配置中指定,不推荐提交到仓库)
|
|
185
|
+
- `apiKeyEnv`: 存储 API 密钥的环境变量名称(推荐方式,如 `DEEPSEEK_API_KEY`)
|
|
186
|
+
- `model`: 使用的模型名称(如 `deepseek-chat`, `qwen2.5-coder`)
|
|
187
|
+
- `concurrencyFiles`: 并发审查的文件数量(建议云端 API 设置 4-8,本地ollama模型设置 1)
|
|
188
|
+
- `request`: 高级请求配置(见下表“高级配置”)
|
|
189
|
+
|
|
190
|
+
| Provider | 可配置参数 |
|
|
191
|
+
| :--- | :--- |
|
|
192
|
+
| **ollama** | `baseURL`, `model`, `concurrencyFiles`, `request` |
|
|
193
|
+
| **deepseek** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `concurrencyFiles`, `request` |
|
|
194
|
+
| **openai** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
195
|
+
| **anthropic** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
196
|
+
| **aliyun** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
197
|
+
| **volcengine** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
198
|
+
| **zhipu** | `baseURL`, `apiKey`, `apiKeyEnv`, `model`, `request` |
|
|
199
|
+
| **azureOpenAI** | `endpoint`, `apiKey`, `apiKeyEnv`, `deployment`, `apiVersion`, `request` |
|
|
200
|
+
|
|
201
|
+
#### 高级配置 (request)
|
|
202
|
+
在 `providerOptions.<provider>.request` 中配置,用于控制请求行为:
|
|
203
|
+
|
|
204
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
205
|
+
| :--- | :--- | :--- | :--- |
|
|
206
|
+
| `timeout` | `number` | `undefined` | 请求超时时间(毫秒)。Ollama 默认建议设大一些(如 15000+) |
|
|
207
|
+
| `retries` | `number` | `0` | 请求失败重试次数 |
|
|
208
|
+
| `backoffMs` | `number` | `300` | 重试间隔时间(毫秒) |
|
|
209
|
+
|
|
210
|
+
> **注意**:`concurrencyFiles` 控制并发审查的文件数(默认 DeepSeek=4, Ollama=1, 其他=4)。
|
|
211
|
+
|
|
212
|
+
## ❓ 常见问题
|
|
213
|
+
|
|
214
|
+
**Q: 页面显示 Diff 但没有 AI 建议?**
|
|
215
|
+
- 检查 `provider` 配置是否正确。
|
|
216
|
+
- 若使用 Ollama,请确保本地服务已启动 (`ollama serve`) 且模型已下载 (`ollama pull qwen2.5-coder`)。
|
|
217
|
+
- 若使用云端 API,请检查 API Key 是否有效及网络连接。
|
|
218
|
+
|
|
219
|
+
**Q: 如何在 CI/CD 中跳过审查?**
|
|
220
|
+
Code Gate 会自动检测交互式环境。在 CI 环境中通常会自动跳过。如需强制跳过,可使用 `git commit --no-verify`。
|
|
221
|
+
|
|
222
|
+
## 📄 License
|
|
223
|
+
|
|
224
|
+
MIT
|
package/bin/code-gate.js
CHANGED
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
1
|
+
#!/usr/bin/env node --no-warnings
|
|
2
|
+
|
|
3
|
+
const cliPath = '../dist/cli/index.js'
|
|
4
|
+
|
|
5
|
+
import(cliPath)
|
|
3
6
|
.then(async (mod) => {
|
|
4
7
|
if (mod && typeof mod.run === 'function') {
|
|
5
8
|
await mod.run()
|
|
6
9
|
} else {
|
|
7
|
-
console.error('code-gate: CLI not found in dist/cli.js')
|
|
10
|
+
console.error('code-gate: CLI entry point not found in dist/cli/index.js')
|
|
8
11
|
process.exit(1)
|
|
9
12
|
}
|
|
10
13
|
})
|
|
11
|
-
.catch(async () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const url = require('url')
|
|
16
|
-
const fs = require('fs')
|
|
17
|
-
const dist = path.join(path.dirname(url.fileURLToPath(import.meta.url)), '..', 'dist', 'cli.js')
|
|
18
|
-
if (fs.existsSync(dist)) {
|
|
19
|
-
const mod = await import(url.pathToFileURL(dist).href)
|
|
20
|
-
if (mod && typeof mod.run === 'function') await mod.run()
|
|
21
|
-
else {
|
|
22
|
-
console.error('code-gate: CLI not found in dist/cli.js')
|
|
23
|
-
process.exit(1)
|
|
24
|
-
}
|
|
14
|
+
.catch(async (e) => {
|
|
15
|
+
if (e.code === 'ERR_MODULE_NOT_FOUND') {
|
|
16
|
+
console.error('code-gate is not built yet or path is incorrect. Run `npm run build`.')
|
|
17
|
+
console.error('Error:', e.message)
|
|
25
18
|
} else {
|
|
26
|
-
console.error('
|
|
27
|
-
process.exit(1)
|
|
19
|
+
console.error('Unexpected error:', e)
|
|
28
20
|
}
|
|
21
|
+
process.exit(1)
|
|
29
22
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { loadConfig } from '../config.js';
|
|
4
|
+
import { loadConfig } from '../config/index.js';
|
|
5
5
|
function withTempConfig(content, ext = '.json') {
|
|
6
6
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-gate-test-'));
|
|
7
7
|
const file = path.join(dir, `code-gate.config${ext}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,SAAS,cAAc,CAAC,OAAY,EAAE,GAAG,GAAG,OAAO;IACjD,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAA;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,GAAG,EAAE,CAAC,CAAA;IACrD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACnF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;AACtB,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC;QAC7B,QAAQ,EAAE,UAAU;QACpB,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE;QACtC,MAAM,EAAE,OAAO;KAChB,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,GAAG,CAAC,EAAE,EAAE,IAAI,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;IAClE,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;IAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;AAC9C,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|