code-gate 0.1.0 → 1.0.1

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.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -114
  3. package/README_ZH.md +224 -0
  4. package/bin/code-gate.js +12 -19
  5. package/dist/__tests__/config.test.js +1 -1
  6. package/dist/__tests__/config.test.js.map +1 -1
  7. package/dist/__tests__/render.test.js +24 -7
  8. package/dist/__tests__/render.test.js.map +1 -1
  9. package/dist/cli/commands/hook.d.ts +1 -0
  10. package/dist/cli/commands/hook.js +164 -0
  11. package/dist/cli/commands/hook.js.map +1 -0
  12. package/dist/cli/commands/init.d.ts +1 -0
  13. package/dist/cli/commands/init.js +157 -0
  14. package/dist/cli/commands/init.js.map +1 -0
  15. package/dist/cli/commands/setup.d.ts +1 -0
  16. package/dist/cli/commands/setup.js +19 -0
  17. package/dist/cli/commands/setup.js.map +1 -0
  18. package/dist/cli/index.d.ts +2 -0
  19. package/dist/cli/index.js +26 -0
  20. package/dist/cli/index.js.map +1 -0
  21. package/dist/commands/hook.js +7 -0
  22. package/dist/commands/hook.js.map +1 -1
  23. package/dist/commands/init.js +20 -20
  24. package/dist/config/defaults.d.ts +2 -0
  25. package/dist/config/defaults.js +33 -0
  26. package/dist/config/defaults.js.map +1 -0
  27. package/dist/config/index.d.ts +4 -0
  28. package/dist/config/index.js +77 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/types.d.ts +55 -0
  31. package/dist/config/types.js +2 -0
  32. package/dist/config/types.js.map +1 -0
  33. package/dist/config.d.ts +111 -21
  34. package/dist/config.js +83 -21
  35. package/dist/config.js.map +1 -1
  36. package/dist/core/git.d.ts +7 -0
  37. package/dist/core/git.js +67 -0
  38. package/dist/core/git.js.map +1 -0
  39. package/dist/core/review-flow.js +105 -59
  40. package/dist/core/review-flow.js.map +1 -1
  41. package/dist/core/review.d.ts +6 -0
  42. package/dist/core/review.js +167 -0
  43. package/dist/core/review.js.map +1 -0
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.js +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/llm/base.d.ts +14 -0
  48. package/dist/llm/base.js +10 -0
  49. package/dist/llm/base.js.map +1 -0
  50. package/dist/llm/deepseek.js +3 -3
  51. package/dist/llm/deepseek.js.map +1 -1
  52. package/dist/llm/index.d.ts +4 -0
  53. package/dist/llm/index.js +41 -0
  54. package/dist/llm/index.js.map +1 -0
  55. package/dist/llm/ollama.js +2 -2
  56. package/dist/llm/ollama.js.map +1 -1
  57. package/dist/llm/providers/aliyun.d.ts +4 -0
  58. package/dist/llm/providers/aliyun.js +25 -0
  59. package/dist/llm/providers/aliyun.js.map +1 -0
  60. package/dist/llm/providers/anthropic.d.ts +4 -0
  61. package/dist/llm/providers/anthropic.js +52 -0
  62. package/dist/llm/providers/anthropic.js.map +1 -0
  63. package/dist/llm/providers/azure.d.ts +4 -0
  64. package/dist/llm/providers/azure.js +38 -0
  65. package/dist/llm/providers/azure.js.map +1 -0
  66. package/dist/llm/providers/cohere.d.ts +4 -0
  67. package/dist/llm/providers/cohere.js +39 -0
  68. package/dist/llm/providers/cohere.js.map +1 -0
  69. package/dist/llm/providers/deepseek.d.ts +4 -0
  70. package/dist/llm/providers/deepseek.js +25 -0
  71. package/dist/llm/providers/deepseek.js.map +1 -0
  72. package/dist/llm/providers/gemini.d.ts +4 -0
  73. package/dist/llm/providers/gemini.js +40 -0
  74. package/dist/llm/providers/gemini.js.map +1 -0
  75. package/dist/llm/providers/mistral.d.ts +4 -0
  76. package/dist/llm/providers/mistral.js +42 -0
  77. package/dist/llm/providers/mistral.js.map +1 -0
  78. package/dist/llm/providers/ollama.d.ts +5 -0
  79. package/dist/llm/providers/ollama.js +67 -0
  80. package/dist/llm/providers/ollama.js.map +1 -0
  81. package/dist/llm/providers/openai.d.ts +4 -0
  82. package/dist/llm/providers/openai.js +27 -0
  83. package/dist/llm/providers/openai.js.map +1 -0
  84. package/dist/llm/providers/volcengine.d.ts +4 -0
  85. package/dist/llm/providers/volcengine.js +29 -0
  86. package/dist/llm/providers/volcengine.js.map +1 -0
  87. package/dist/llm/providers/zhipu.d.ts +4 -0
  88. package/dist/llm/providers/zhipu.js +25 -0
  89. package/dist/llm/providers/zhipu.js.map +1 -0
  90. package/dist/locales/de.d.ts +2 -0
  91. package/dist/locales/de.js +33 -0
  92. package/dist/locales/de.js.map +1 -0
  93. package/dist/locales/en.d.ts +2 -0
  94. package/dist/locales/en.js +33 -0
  95. package/dist/locales/en.js.map +1 -0
  96. package/dist/locales/fr.d.ts +2 -0
  97. package/dist/locales/fr.js +33 -0
  98. package/dist/locales/fr.js.map +1 -0
  99. package/dist/locales/index.d.ts +3 -0
  100. package/dist/locales/index.js +41 -0
  101. package/dist/locales/index.js.map +1 -0
  102. package/dist/locales/ja.d.ts +2 -0
  103. package/dist/locales/ja.js +33 -0
  104. package/dist/locales/ja.js.map +1 -0
  105. package/dist/locales/ko.d.ts +2 -0
  106. package/dist/locales/ko.js +33 -0
  107. package/dist/locales/ko.js.map +1 -0
  108. package/dist/locales/types.d.ts +32 -0
  109. package/dist/locales/types.js +2 -0
  110. package/dist/locales/types.js.map +1 -0
  111. package/dist/locales/zh-CN.d.ts +2 -0
  112. package/dist/locales/zh-CN.js +33 -0
  113. package/dist/locales/zh-CN.js.map +1 -0
  114. package/dist/locales/zh-TW.d.ts +2 -0
  115. package/dist/locales/zh-TW.js +33 -0
  116. package/dist/locales/zh-TW.js.map +1 -0
  117. package/dist/ui/render/assets.d.ts +8 -0
  118. package/dist/ui/render/assets.js +89 -0
  119. package/dist/ui/render/assets.js.map +1 -0
  120. package/dist/ui/render/html.d.ts +35 -0
  121. package/dist/ui/render/html.js +294 -0
  122. package/dist/ui/render/html.js.map +1 -0
  123. package/dist/ui/render.d.ts +11 -0
  124. package/dist/ui/render.js +198 -13
  125. package/dist/ui/render.js.map +1 -1
  126. package/dist/ui/server.d.ts +4 -2
  127. package/dist/ui/server.js +30 -8
  128. package/dist/ui/server.js.map +1 -1
  129. package/dist/utils/logger.d.ts +3 -0
  130. package/dist/utils/logger.js +10 -0
  131. package/dist/utils/logger.js.map +1 -0
  132. package/package.json +27 -8
  133. 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
- # code-gate
2
-
3
- AI 助力的提交时代码 Review 工具,支持本地 Ollama 或 DeepSeek API,审查 `git commit` 的 `staged diff`,并以 GitHub Diff 风格在本地页面展示结果。
4
-
5
- ## 安装
6
- - `npm i -D code-gate`
7
-
8
- ## 初始化与集成
9
- - 推荐使用 `init` 命令,选择初始化方式并自动生成配置文件:
10
- - 原生 Git Hooks:`npx code-gate init -m git`
11
- - Husky:`npx code-gate init -m husky`
12
- - simple-git-hooks:`npx code-gate init -m simple`
13
- - 跳过配置文件生成:`npx code-gate init --no-config`
14
- - 仍支持旧方式:
15
- - 原生 Git Hooks 快速安装:`npx code-gate setup`
16
- - 该命令会创建 `.githooks/pre-commit` 并设置 `core.hooksPath`
17
-
18
- ## 手动初始化(不覆盖现有钩子)
19
- - Husky:
20
- - 编辑 `.husky/pre-commit`,在原有内容后追加一行:
21
- - `npx code-gate hook`
22
- - 确认 `git config core.hooksPath` 输出 `.husky`
23
- - 原生 Git Hooks:
24
- - 在项目根创建 `.githooks/pre-commit`,内容示例:
25
- - `#!/usr/bin/env sh`
26
- - `npx code-gate hook`
27
- - 设置 `core.hooksPath`:
28
- - `git config core.hooksPath .githooks`
29
- - 配置文件生成:
30
- - 在项目根新建 `code-gate.config.json`(可从下文示例复制并按需调整)
31
- - 如使用 DeepSeek,请在环境变量设置 `DEEPSEEK_API_KEY`
32
-
33
- ## 命令
34
- - `npx code-gate init` 交互式初始化(可选择 git/husky/simple,并生成配置文件)
35
- - `npx code-gate setup` 快速安装原生 Git Hook
36
- - `npx code-gate hook` 在 Hook 中执行交互式 Review
37
-
38
- ## 本地开发(link 调试)
39
- - `code-gate` 仓库:
40
- - `npm install`
41
- - `npm run build:watch`
42
- - `npm link`
43
- - 在目标项目:
44
- - `npm link code-gate`
45
- - `npx code-gate init -m git`(或 `husky`/`simple`)
46
- - `git add` + `git commit` 时触发审查流程
47
-
48
- ## 配置文件
49
- - 推荐使用 `.codegate.js`(支持注释与更灵活的写法),兼容旧的 `code-gate.config.json/.yaml`、`.code-gaterc.{json,yaml}`。
50
- - 示例(`.codegate.js`):
51
- ```js
52
- // provider: 选择使用的 AI 审查引擎,可选值: 'ollama' | 'deepseek'
53
- // review: 审查相关设置
54
- // - enabled: 是否启用审查
55
- // - provider: 覆盖顶层 provider,支持按需切换,可选值: 'ollama' | 'deepseek'
56
- // - mode: 审查展示模式,可选值: 'aggregate'(整合输出)| 'per_file'(按文件 Tab 展示)
57
- // ollama: 本地 Ollama 设置
58
- // - baseURL: Ollama 服务地址,默认 'http://localhost:11434'
59
- // - model: 模型名称,例如 'qwen3:8b'、'deepseek-r1:14b'
60
- // deepseek: DeepSeek 云端设置
61
- // - baseURL: API 地址,默认 'https://api.deepseek.com'
62
- // - apiKeyEnv: 存放密钥的环境变量名,默认 'DEEPSEEK_API_KEY'
63
- // - model: 模型名称,默认 'deepseek-chat'
64
- // fileTypes: 需要审查的文件类型扩展名列表
65
- // scope: 审查范围,可选值: 'staged' | 'allChanged' | { include?: string[], exclude?: string[] }
66
- // ui: 页面与交互设置
67
- // - openBrowser: 是否自动打开浏览器
68
- // - theme: 主题,目前仅 'github'
69
- // - port: 预览服务端口
70
- // limits: 限制项
71
- // - maxDiffLines: 最大 diff 行数
72
- // - maxFiles: 最大审查文件数
73
- // rules: 审查关注点,可选值: 'security' | 'performance' | 'style' | 'tests'
74
- // prompt: 通用提示词
75
- // output: 输出目录配置
76
- // - dir: 本地输出目录
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
- provider: 'deepseek',
79
- review: { enabled: true, mode: 'aggregate' },
80
- deepseek: { baseURL: 'https://api.deepseek.com', apiKeyEnv: 'DEEPSEEK_API_KEY', model: 'deepseek-chat' },
81
- ollama: { baseURL: 'http://localhost:11434', model: 'qwen3:8b' },
82
- fileTypes: ['ts', 'tsx', 'js', 'jsx', 'json', 'md', 'py', 'go', 'rs'],
83
- scope: 'staged',
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
- - 运行 `git commit` 时会询问是否进行 Review:
94
- - 选择否:正常提交。
95
- - 选择是:抓取 `staged diff` 调用 AI 审查,生成本地页面并打印预览 URL,再询问是否继续提交。
96
- - 非交互环境会自动跳过。
97
- - 如需在非交互环境强制执行,可在 `.husky/pre-commit` 中使用:`npx code-gate hook -f`
98
- - 页面顶部会显示 AI 状态(是否参与、Provider、Model、错误信息)
99
- - 支持按文件 Tab 展示:在配置中设置 `"review": { "mode": "per_file" }`,每个文件一个 Tab,Tabs 超出视野时横向滚动,每个文件顶部展示该文件的审查内容
100
-
101
- ## 故障排查
102
- - 页面只有 diff、没有 AI 审查内容:
103
- - DeepSeek:确保设置了环境变量 `DEEPSEEK_API_KEY`,并且 `provider` 为 `deepseek`;可在 shell 中 `export DEEPSEEK_API_KEY="your_key"`
104
- - Ollama:确保本地 Ollama 正在运行(默认 `http://localhost:11434`),并且模型已安装;例如 `ollama list` 查看,`ollama pull qwen2.5-coder`
105
- - 可在 `code-gate.config.json` 中切换 `provider`,调整 `prompt` 与 `ui.port`
106
- - 出错时页面顶部会显示原因与解决建议
107
-
108
- ## DeepSeek 集成
109
- - 使用 OpenAI 兼容接口 `https://api.deepseek.com`,需在环境变量设置密钥:`DEEPSEEK_API_KEY`。
110
- - 参考文档:https://api-docs.deepseek.com/
111
-
112
- ## Ollama 集成
113
- - 通过本地 HTTP 接口调用,不内置安装;需用户自行安装与启动 Ollama。
114
- - 默认地址:`http://localhost:11434`
115
-
116
- ## 注意
117
- - 不会将密钥写入仓库;配置建议走环境变量。
118
- - Diff 会消耗模型 token,可通过 `limits` 控制。
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
- import('../dist/cli.js')
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
- const { createRequire } = await import('module')
13
- const require = createRequire(import.meta.url)
14
- const path = require('path')
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('code-gate is not built yet. Run `npm run build`.')
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,cAAc,CAAA;AAEzC,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"}
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"}