vite-plugin-ai-code-review 1.0.3 → 1.0.4

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/dist/index.js CHANGED
@@ -1,28 +1,54 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var openai = require('@langchain/openai');
6
- var messages = require('@langchain/core/messages');
7
- var crypto = require('crypto');
8
- var child_process = require('child_process');
9
- var fs2 = require('fs');
10
- var path2 = require('path');
11
-
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
13
29
 
14
- var crypto__default = /*#__PURE__*/_interopDefault(crypto);
15
- var fs2__default = /*#__PURE__*/_interopDefault(fs2);
16
- var path2__default = /*#__PURE__*/_interopDefault(path2);
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ CodeReviewer: () => CodeReviewer,
34
+ GitUtils: () => GitUtils,
35
+ Reporter: () => Reporter,
36
+ default: () => index_default,
37
+ vitePluginAICodeReview: () => vitePluginAICodeReview
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
17
40
 
18
41
  // src/reviewer.ts
42
+ var import_openai = require("@langchain/openai");
43
+ var import_messages = require("@langchain/core/messages");
44
+ var import_crypto = __toESM(require("crypto"));
19
45
  var CodeReviewer = class {
20
46
  constructor(options) {
21
47
  this.llm = null;
22
48
  this.cache = /* @__PURE__ */ new Map();
23
49
  this.options = options;
24
50
  if (options.apiKey) {
25
- this.llm = new openai.ChatOpenAI({
51
+ this.llm = new import_openai.ChatOpenAI({
26
52
  openAIApiKey: options.apiKey,
27
53
  configuration: { baseURL: options.apiUrl },
28
54
  modelName: options.model,
@@ -52,7 +78,7 @@ var CodeReviewer = class {
52
78
  }
53
79
  return issues;
54
80
  } catch (error) {
55
- console.error(`\u274C \u5BA1\u67E5\u5931\u8D25: ${error.message}`);
81
+ console.error(`❌ 审查失败: ${error.message}`);
56
82
  return [];
57
83
  }
58
84
  }
@@ -83,64 +109,64 @@ var CodeReviewer = class {
83
109
  */
84
110
  buildSystemPrompt() {
85
111
  const { level, rules } = this.options;
86
- let prompt = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u4EE3\u7801\u5BA1\u67E5\u4E13\u5BB6\u3002\u8BF7\u5BA1\u67E5\u4EE3\u7801\u5E76\u8BC6\u522B\u95EE\u9898\u3002
112
+ let prompt = `你是一个专业的代码审查专家。请审查代码并识别问题。
87
113
 
88
- \u5BA1\u67E5\u7EA7\u522B: ${level}
114
+ 审查级别: ${level}
89
115
  `;
90
116
  if (rules.security !== "off") {
91
117
  prompt += `
92
- \u{1F512} \u5B89\u5168\u95EE\u9898 (${rules.security}):
93
- - XSS \u6F0F\u6D1E
94
- - SQL \u6CE8\u5165
95
- - eval() \u4F7F\u7528
96
- - \u654F\u611F\u4FE1\u606F\u6CC4\u9732
97
- - \u4E0D\u5B89\u5168\u7684\u4F9D\u8D56`;
118
+ 🔒 安全问题 (${rules.security}):
119
+ - XSS 漏洞
120
+ - SQL 注入
121
+ - eval() 使用
122
+ - 敏感信息泄露
123
+ - 不安全的依赖`;
98
124
  }
99
125
  if (rules.performance !== "off") {
100
126
  prompt += `
101
- \u26A1 \u6027\u80FD\u95EE\u9898 (${rules.performance}):
102
- - \u5927\u5FAA\u73AF
103
- - \u5185\u5B58\u6CC4\u6F0F
104
- - \u91CD\u590D\u8BA1\u7B97
105
- - \u4E0D\u5FC5\u8981\u7684\u6E32\u67D3
106
- - \u963B\u585E\u64CD\u4F5C`;
127
+ 性能问题 (${rules.performance}):
128
+ - 大循环
129
+ - 内存泄漏
130
+ - 重复计算
131
+ - 不必要的渲染
132
+ - 阻塞操作`;
107
133
  }
108
134
  if (rules.style !== "off") {
109
135
  prompt += `
110
- \u{1F4DD} \u4EE3\u7801\u89C4\u8303 (${rules.style}):
111
- - \u547D\u540D\u89C4\u8303
112
- - \u4EE3\u7801\u590D\u6742\u5EA6
113
- - \u91CD\u590D\u4EE3\u7801
114
- - \u6CE8\u91CA\u5B8C\u6574\u6027`;
136
+ 📝 代码规范 (${rules.style}):
137
+ - 命名规范
138
+ - 代码复杂度
139
+ - 重复代码
140
+ - 注释完整性`;
115
141
  }
116
142
  if (rules.bestPractice !== "off") {
117
143
  prompt += `
118
- \u{1F3A8} \u6700\u4F73\u5B9E\u8DF5 (${rules.bestPractice}):
119
- - \u9519\u8BEF\u5904\u7406
120
- - \u7C7B\u578B\u5B89\u5168
121
- - \u7EC4\u4EF6\u8BBE\u8BA1
122
- - \u72B6\u6001\u7BA1\u7406`;
144
+ 🎨 最佳实践 (${rules.bestPractice}):
145
+ - 错误处理
146
+ - 类型安全
147
+ - 组件设计
148
+ - 状态管理`;
123
149
  }
124
150
  prompt += `
125
151
 
126
- \u8FD4\u56DE JSON \u683C\u5F0F:
152
+ 返回 JSON 格式:
127
153
  {
128
154
  "issues": [
129
155
  {
130
- "line": 10, // \u5FC5\u987B\u662F\u51C6\u786E\u7684\u884C\u53F7\uFF01
156
+ "line": 10, // 必须是准确的行号!
131
157
  "category": "security",
132
158
  "severity": "error",
133
- "message": "\u4F7F\u7528\u4E86 eval()\uFF0C\u5B58\u5728\u5B89\u5168\u98CE\u9669",
134
- "suggestion": "\u4F7F\u7528 JSON.parse() \u6216\u5176\u4ED6\u5B89\u5168\u65B9\u6CD5"
159
+ "message": "使用了 eval(),存在安全风险",
160
+ "suggestion": "使用 JSON.parse() 或其他安全方法"
135
161
  }
136
162
  ]
137
163
  }
138
164
 
139
- **\u91CD\u8981\u63D0\u793A**\uFF1A
140
- 1. line \u5B57\u6BB5\u5FC5\u987B\u662F\u51C6\u786E\u7684\u884C\u53F7\uFF0C\u4E0E\u4EE3\u7801\u4E2D\u7684\u884C\u53F7\u4E00\u81F4
141
- 2. \u5982\u679C\u4EE3\u7801\u5E26\u6709\u884C\u53F7\u524D\u7F00\uFF08\u5982 "10: const x = 1"\uFF09\uFF0C\u8BF7\u63D0\u53D6\u6B63\u786E\u7684\u884C\u53F7
142
- 3. \u53EA\u8FD4\u56DE JSON\uFF0C\u4E0D\u8981\u5176\u4ED6\u89E3\u91CA`;
143
- return new messages.SystemMessage(prompt);
165
+ **重要提示**:
166
+ 1. line 字段必须是准确的行号,与代码中的行号一致
167
+ 2. 如果代码带有行号前缀(如 "10: const x = 1"),请提取正确的行号
168
+ 3. 只返回 JSON,不要其他解释`;
169
+ return new import_messages.SystemMessage(prompt);
144
170
  }
145
171
  /**
146
172
  * 构建用户提示
@@ -150,20 +176,20 @@ var CodeReviewer = class {
150
176
  const language = this.getLanguage(fileExt || "");
151
177
  const lines = code.split("\n");
152
178
  const codeWithLineNumbers = lines.map((line, index) => `${index + 1}: ${line}`).join("\n");
153
- return new messages.HumanMessage(`
154
- \u8BF7\u5BA1\u67E5\u4EE5\u4E0B ${language} \u4EE3\u7801\uFF1A
179
+ return new import_messages.HumanMessage(`
180
+ 请审查以下 ${language} 代码:
155
181
 
156
- \u6587\u4EF6: ${filePath}
157
- \u603B\u884C\u6570: ${lines.length}
182
+ 文件: ${filePath}
183
+ 总行数: ${lines.length}
158
184
 
159
- \u4EE3\u7801\uFF08\u5E26\u884C\u53F7\uFF09:
185
+ 代码(带行号):
160
186
  \`\`\`${language}
161
187
  ${codeWithLineNumbers}
162
188
  \`\`\`
163
189
 
164
- **\u91CD\u8981**\uFF1A\u8BF7\u8FD4\u56DE\u51C6\u786E\u7684\u884C\u53F7\uFF01\u884C\u53F7\u5FC5\u987B\u4E0E\u4E0A\u9762\u4EE3\u7801\u4E2D\u7684\u884C\u53F7\u4E00\u81F4\u3002
190
+ **重要**:请返回准确的行号!行号必须与上面代码中的行号一致。
165
191
 
166
- \u8BF7\u8FD4\u56DE JSON \u683C\u5F0F\u7684\u95EE\u9898\u5217\u8868\u3002
192
+ 请返回 JSON 格式的问题列表。
167
193
  `);
168
194
  }
169
195
  /**
@@ -178,7 +204,7 @@ ${codeWithLineNumbers}
178
204
  line: issue.line,
179
205
  category: issue.category || "best-practice",
180
206
  severity: issue.severity || "info",
181
- message: issue.message || "\u672A\u77E5\u95EE\u9898",
207
+ message: issue.message || "未知问题",
182
208
  suggestion: issue.suggestion,
183
209
  code: issue.code
184
210
  })).filter((issue) => {
@@ -207,7 +233,7 @@ ${codeWithLineNumbers}
207
233
  * 生成缓存键
208
234
  */
209
235
  getCacheKey(code) {
210
- return crypto__default.default.createHash("md5").update(code).digest("hex");
236
+ return import_crypto.default.createHash("md5").update(code).digest("hex");
211
237
  }
212
238
  /**
213
239
  * 清除缓存
@@ -226,6 +252,11 @@ ${codeWithLineNumbers}
226
252
  };
227
253
  }
228
254
  };
255
+
256
+ // src/git-utils.ts
257
+ var import_child_process = require("child_process");
258
+ var import_fs = __toESM(require("fs"));
259
+ var import_path = __toESM(require("path"));
229
260
  var GitUtils = class {
230
261
  /**
231
262
  * 获取 Git 变更的文件列表
@@ -234,29 +265,29 @@ var GitUtils = class {
234
265
  async getChangedFiles() {
235
266
  try {
236
267
  if (!this.isGitRepository()) {
237
- console.warn("\u26A0\uFE0F \u4E0D\u5728 Git \u4ED3\u5E93\u4E2D\uFF0C\u65E0\u6CD5\u83B7\u53D6\u53D8\u66F4\u6587\u4EF6");
268
+ console.warn("⚠️ 不在 Git 仓库中,无法获取变更文件");
238
269
  return [];
239
270
  }
240
- console.log(`\u{1F50D} [Git] \u5BF9\u6BD4\u7B56\u7565: HEAD~1 vs HEAD`);
271
+ console.log(`🔍 [Git] 对比策略: HEAD~1 vs HEAD`);
241
272
  const changedFiles = this.getCommitDiffFiles();
242
- console.log(`\u{1F50D} [Git] \u68C0\u6D4B\u5230 ${changedFiles.length} \u4E2A\u53D8\u66F4\u6587\u4EF6`);
273
+ console.log(`🔍 [Git] 检测到 ${changedFiles.length} 个变更文件`);
243
274
  changedFiles.forEach((f) => console.log(` - ${f}`));
244
275
  const existingFiles = changedFiles.map((file) => {
245
276
  const cleanFile = file.replace(/^[^/]+\//, "");
246
277
  return cleanFile;
247
278
  }).filter((file) => {
248
- const fullPath = path2__default.default.resolve(process.cwd(), file);
249
- const exists = fs2__default.default.existsSync(fullPath);
279
+ const fullPath = import_path.default.resolve(process.cwd(), file);
280
+ const exists = import_fs.default.existsSync(fullPath);
250
281
  if (!exists) {
251
- console.log(` \u26A0\uFE0F \u6587\u4EF6\u4E0D\u5B58\u5728: ${fullPath}`);
282
+ console.log(` ⚠️ 文件不存在: ${fullPath}`);
252
283
  }
253
284
  return exists;
254
285
  });
255
- console.log(`\u{1F50D} [Git] \u8FC7\u6EE4\u540E\u6587\u4EF6: ${existingFiles.length} \u4E2A`);
256
- existingFiles.forEach((f) => console.log(` \u2713 ${f}`));
286
+ console.log(`🔍 [Git] 过滤后文件: ${existingFiles.length} 个`);
287
+ existingFiles.forEach((f) => console.log(` ${f}`));
257
288
  return existingFiles;
258
289
  } catch (error) {
259
- console.warn(`\u26A0\uFE0F \u83B7\u53D6 Git \u53D8\u66F4\u6587\u4EF6\u5931\u8D25: ${error.message}`);
290
+ console.warn(`⚠️ 获取 Git 变更文件失败: ${error.message}`);
260
291
  return [];
261
292
  }
262
293
  }
@@ -265,7 +296,7 @@ var GitUtils = class {
265
296
  */
266
297
  isGitRepository() {
267
298
  try {
268
- child_process.execSync("git rev-parse --git-dir", {
299
+ (0, import_child_process.execSync)("git rev-parse --git-dir", {
269
300
  stdio: "ignore",
270
301
  cwd: process.cwd()
271
302
  });
@@ -279,7 +310,7 @@ var GitUtils = class {
279
310
  */
280
311
  getCommitDiffFiles() {
281
312
  try {
282
- const output = child_process.execSync("git diff --name-only HEAD~1 HEAD", {
313
+ const output = (0, import_child_process.execSync)("git diff --name-only HEAD~1 HEAD", {
283
314
  encoding: "utf-8",
284
315
  cwd: process.cwd()
285
316
  });
@@ -287,10 +318,10 @@ var GitUtils = class {
287
318
  if (files.length > 0) {
288
319
  return files;
289
320
  }
290
- console.log(` \u2139\uFE0F \u6CA1\u6709\u4E0A\u4E00\u6B21\u63D0\u4EA4\uFF0C\u83B7\u53D6\u5F53\u524D\u63D0\u4EA4\u7684\u6240\u6709\u6587\u4EF6`);
321
+ console.log(` ℹ️ 没有上一次提交,获取当前提交的所有文件`);
291
322
  return this.getLastCommitFiles();
292
323
  } catch (error) {
293
- console.log(` \u2139\uFE0F \u65E0\u6CD5\u5BF9\u6BD4\u63D0\u4EA4\uFF0C\u5C1D\u8BD5\u83B7\u53D6\u672A\u63D0\u4EA4\u7684\u53D8\u66F4`);
324
+ console.log(` ℹ️ 无法对比提交,尝试获取未提交的变更`);
294
325
  return this.getUncommittedFiles();
295
326
  }
296
327
  }
@@ -299,7 +330,7 @@ var GitUtils = class {
299
330
  */
300
331
  getLastCommitFiles() {
301
332
  try {
302
- const output = child_process.execSync(
333
+ const output = (0, import_child_process.execSync)(
303
334
  "git diff-tree --no-commit-id --name-only -r HEAD",
304
335
  {
305
336
  encoding: "utf-8",
@@ -316,11 +347,11 @@ var GitUtils = class {
316
347
  */
317
348
  getUncommittedFiles() {
318
349
  try {
319
- const unstagedOutput = child_process.execSync("git diff --name-only", {
350
+ const unstagedOutput = (0, import_child_process.execSync)("git diff --name-only", {
320
351
  encoding: "utf-8",
321
352
  cwd: process.cwd()
322
353
  });
323
- const stagedOutput = child_process.execSync("git diff --cached --name-only", {
354
+ const stagedOutput = (0, import_child_process.execSync)("git diff --cached --name-only", {
324
355
  encoding: "utf-8",
325
356
  cwd: process.cwd()
326
357
  });
@@ -336,7 +367,7 @@ var GitUtils = class {
336
367
  */
337
368
  async getRecentChangedFiles(commits = 1) {
338
369
  try {
339
- const output = child_process.execSync(`git diff --name-only HEAD~${commits}`, {
370
+ const output = (0, import_child_process.execSync)(`git diff --name-only HEAD~${commits}`, {
340
371
  encoding: "utf-8",
341
372
  cwd: process.cwd()
342
373
  });
@@ -350,7 +381,7 @@ var GitUtils = class {
350
381
  */
351
382
  getCurrentBranch() {
352
383
  try {
353
- const output = child_process.execSync("git rev-parse --abbrev-ref HEAD", {
384
+ const output = (0, import_child_process.execSync)("git rev-parse --abbrev-ref HEAD", {
354
385
  encoding: "utf-8",
355
386
  cwd: process.cwd()
356
387
  });
@@ -364,7 +395,7 @@ var GitUtils = class {
364
395
  */
365
396
  getFileStatus(filePath) {
366
397
  try {
367
- const output = child_process.execSync(`git status --short "${filePath}"`, {
398
+ const output = (0, import_child_process.execSync)(`git status --short "${filePath}"`, {
368
399
  encoding: "utf-8",
369
400
  cwd: process.cwd()
370
401
  });
@@ -380,6 +411,10 @@ var GitUtils = class {
380
411
  }
381
412
  }
382
413
  };
414
+
415
+ // src/reporter.ts
416
+ var import_fs2 = __toESM(require("fs"));
417
+ var import_path2 = __toESM(require("path"));
383
418
  var Reporter = class {
384
419
  constructor(options = {}) {
385
420
  this.options = options;
@@ -405,23 +440,23 @@ var Reporter = class {
405
440
  * 生成控制台报告
406
441
  */
407
442
  generateConsoleReport(issues) {
408
- console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
409
- console.log("\u{1F4CA} \u4EE3\u7801\u5BA1\u67E5\u62A5\u544A");
410
- console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
443
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
444
+ console.log("📊 代码审查报告");
445
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
411
446
  const errors = issues.filter((i) => i.severity === "error");
412
447
  const warnings = issues.filter((i) => i.severity === "warn");
413
448
  const infos = issues.filter((i) => i.severity === "info");
414
- console.log(`\u274C \u9519\u8BEF: ${errors.length}`);
415
- console.log(`\u26A0\uFE0F \u8B66\u544A: ${warnings.length}`);
416
- console.log(`\u2139\uFE0F \u4FE1\u606F: ${infos.length}`);
417
- console.log(`\u{1F4DD} \u603B\u8BA1: ${issues.length}
449
+ console.log(`❌ 错误: ${errors.length}`);
450
+ console.log(`⚠️ 警告: ${warnings.length}`);
451
+ console.log(`ℹ️ 信息: ${infos.length}`);
452
+ console.log(`📝 总计: ${issues.length}
418
453
  `);
419
454
  const byCategory = this.groupByCategory(issues);
420
- console.log("\u{1F4CB} \u95EE\u9898\u5206\u7C7B:");
455
+ console.log("📋 问题分类:");
421
456
  Object.entries(byCategory).forEach(([category, count]) => {
422
457
  console.log(` ${this.getCategoryIcon(category)} ${category}: ${count}`);
423
458
  });
424
- console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
459
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
425
460
  }
426
461
  /**
427
462
  * 生成 HTML 报告
@@ -433,7 +468,7 @@ var Reporter = class {
433
468
  <head>
434
469
  <meta charset="UTF-8">
435
470
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
436
- <title>\u4EE3\u7801\u5BA1\u67E5\u62A5\u544A</title>
471
+ <title>代码审查报告</title>
437
472
  <style>
438
473
  * { margin: 0; padding: 0; box-sizing: border-box; }
439
474
  body {
@@ -586,7 +621,7 @@ var Reporter = class {
586
621
  line-height: 1.6;
587
622
  }
588
623
  .issue-suggestion::before {
589
- content: "\u{1F4A1} \u5EFA\u8BAE: ";
624
+ content: "💡 建议: ";
590
625
  font-weight: bold;
591
626
  color: #2e7d32;
592
627
  font-size: 16px;
@@ -621,27 +656,27 @@ var Reporter = class {
621
656
  <body>
622
657
  <div class="container">
623
658
  <div class="header">
624
- <h1>\u{1F50D} \u4EE3\u7801\u5BA1\u67E5\u62A5\u544A</h1>
625
- <div class="time">\u751F\u6210\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}</div>
659
+ <h1>🔍 代码审查报告</h1>
660
+ <div class="time">生成时间: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}</div>
626
661
  </div>
627
662
 
628
663
  <div class="content">
629
664
  <div class="summary">
630
665
  <div class="summary-card error">
631
666
  <h2>${issues.filter((i) => i.severity === "error").length}</h2>
632
- <p>\u9519\u8BEF</p>
667
+ <p>错误</p>
633
668
  </div>
634
669
  <div class="summary-card warn">
635
670
  <h2>${issues.filter((i) => i.severity === "warn").length}</h2>
636
- <p>\u8B66\u544A</p>
671
+ <p>警告</p>
637
672
  </div>
638
673
  <div class="summary-card info">
639
674
  <h2>${issues.filter((i) => i.severity === "info").length}</h2>
640
- <p>\u4FE1\u606F</p>
675
+ <p>信息</p>
641
676
  </div>
642
677
  </div>
643
678
 
644
- <div class="section-title">\u{1F4CA} \u95EE\u9898\u5206\u7C7B\u7EDF\u8BA1</div>
679
+ <div class="section-title">📊 问题分类统计</div>
645
680
  <div class="category-stats">
646
681
  ${Object.entries(this.groupByCategory(issues)).map(
647
682
  ([category, count]) => `<div class="category-tag">${this.getCategoryIcon(
@@ -650,7 +685,7 @@ var Reporter = class {
650
685
  ).join("")}
651
686
  </div>
652
687
 
653
- <div class="section-title">\u{1F4CB} \u95EE\u9898\u8BE6\u60C5</div>
688
+ <div class="section-title">📋 问题详情</div>
654
689
  ${issues.map(
655
690
  (issue) => `
656
691
  <div class="issue">
@@ -658,7 +693,7 @@ var Reporter = class {
658
693
  <span class="issue-badge ${issue.severity}">${issue.severity.toUpperCase()}</span>
659
694
  <span class="issue-category">${issue.category}</span>
660
695
  <span class="issue-file">${issue.file}</span>
661
- ${issue.line ? `<span class="issue-line">\u884C ${issue.line}</span>` : ""}
696
+ ${issue.line ? `<span class="issue-line">行 ${issue.line}</span>` : ""}
662
697
  </div>
663
698
  <div class="issue-message">${issue.message}</div>
664
699
  ${issue.suggestion ? `<div class="issue-suggestion">${issue.suggestion}</div>` : ""}
@@ -675,13 +710,13 @@ var Reporter = class {
675
710
  </body>
676
711
  </html>
677
712
  `;
678
- const reportsDir = path2__default.default.join(process.cwd(), "ai-reports");
679
- if (!fs2__default.default.existsSync(reportsDir)) {
680
- fs2__default.default.mkdirSync(reportsDir, { recursive: true });
713
+ const reportsDir = import_path2.default.join(process.cwd(), "ai-reports");
714
+ if (!import_fs2.default.existsSync(reportsDir)) {
715
+ import_fs2.default.mkdirSync(reportsDir, { recursive: true });
681
716
  }
682
- const reportPath = path2__default.default.join(reportsDir, "code-review-report.html");
683
- fs2__default.default.writeFileSync(reportPath, html, "utf-8");
684
- console.log(`\u{1F4C4} HTML \u62A5\u544A\u5DF2\u751F\u6210: ${reportPath}
717
+ const reportPath = import_path2.default.join(reportsDir, "code-review-report.html");
718
+ import_fs2.default.writeFileSync(reportPath, html, "utf-8");
719
+ console.log(`📄 HTML 报告已生成: ${reportPath}
685
720
  `);
686
721
  }
687
722
  /**
@@ -691,45 +726,45 @@ var Reporter = class {
691
726
  const errors = issues.filter((i) => i.severity === "error");
692
727
  const warnings = issues.filter((i) => i.severity === "warn");
693
728
  const infos = issues.filter((i) => i.severity === "info");
694
- let markdown = `# \u{1F50D} \u4EE3\u7801\u5BA1\u67E5\u62A5\u544A
729
+ let markdown = `# 🔍 代码审查报告
695
730
 
696
- \u751F\u6210\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}
731
+ 生成时间: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}
697
732
 
698
- ## \u{1F4CA} \u6982\u89C8
733
+ ## 📊 概览
699
734
 
700
- | \u7C7B\u578B | \u6570\u91CF |
735
+ | 类型 | 数量 |
701
736
  |------|------|
702
- | \u274C \u9519\u8BEF | ${errors.length} |
703
- | \u26A0\uFE0F \u8B66\u544A | ${warnings.length} |
704
- | \u2139\uFE0F \u4FE1\u606F | ${infos.length} |
705
- | \u{1F4DD} \u603B\u8BA1 | ${issues.length} |
737
+ | 错误 | ${errors.length} |
738
+ | ⚠️ 警告 | ${warnings.length} |
739
+ | ℹ️ 信息 | ${infos.length} |
740
+ | 📝 总计 | ${issues.length} |
706
741
 
707
- ## \u{1F4CB} \u95EE\u9898\u8BE6\u60C5
742
+ ## 📋 问题详情
708
743
 
709
744
  `;
710
745
  issues.forEach((issue, index) => {
711
746
  const icon = this.getSeverityIcon(issue.severity);
712
747
  markdown += `### ${index + 1}. ${icon} ${issue.category}
713
748
 
714
- **\u6587\u4EF6**: \`${issue.file}${issue.line ? `:${issue.line}` : ""}\`
715
- **\u4E25\u91CD\u7A0B\u5EA6**: ${issue.severity}
716
- **\u95EE\u9898**: ${issue.message}
749
+ **文件**: \`${issue.file}${issue.line ? `:${issue.line}` : ""}\`
750
+ **严重程度**: ${issue.severity}
751
+ **问题**: ${issue.message}
717
752
 
718
753
  `;
719
754
  if (issue.suggestion) {
720
- markdown += `\u{1F4A1} **\u5EFA\u8BAE**: ${issue.suggestion}
755
+ markdown += `💡 **建议**: ${issue.suggestion}
721
756
 
722
757
  `;
723
758
  }
724
759
  markdown += "---\n\n";
725
760
  });
726
- const reportsDir = path2__default.default.join(process.cwd(), "ai-reports");
727
- if (!fs2__default.default.existsSync(reportsDir)) {
728
- fs2__default.default.mkdirSync(reportsDir, { recursive: true });
761
+ const reportsDir = import_path2.default.join(process.cwd(), "ai-reports");
762
+ if (!import_fs2.default.existsSync(reportsDir)) {
763
+ import_fs2.default.mkdirSync(reportsDir, { recursive: true });
729
764
  }
730
- const reportPath = path2__default.default.join(reportsDir, "code-review-report.md");
731
- fs2__default.default.writeFileSync(reportPath, markdown, "utf-8");
732
- console.log(`\u{1F4C4} Markdown \u62A5\u544A\u5DF2\u751F\u6210: ${reportPath}
765
+ const reportPath = import_path2.default.join(reportsDir, "code-review-report.md");
766
+ import_fs2.default.writeFileSync(reportPath, markdown, "utf-8");
767
+ console.log(`📄 Markdown 报告已生成: ${reportPath}
733
768
  `);
734
769
  }
735
770
  /**
@@ -746,13 +781,13 @@ var Reporter = class {
746
781
  },
747
782
  issues
748
783
  };
749
- const reportsDir = path2__default.default.join(process.cwd(), "ai-reports");
750
- if (!fs2__default.default.existsSync(reportsDir)) {
751
- fs2__default.default.mkdirSync(reportsDir, { recursive: true });
784
+ const reportsDir = import_path2.default.join(process.cwd(), "ai-reports");
785
+ if (!import_fs2.default.existsSync(reportsDir)) {
786
+ import_fs2.default.mkdirSync(reportsDir, { recursive: true });
752
787
  }
753
- const reportPath = path2__default.default.join(reportsDir, "code-review-report.json");
754
- fs2__default.default.writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf-8");
755
- console.log(`\u{1F4C4} JSON \u62A5\u544A\u5DF2\u751F\u6210: ${reportPath}
788
+ const reportPath = import_path2.default.join(reportsDir, "code-review-report.json");
789
+ import_fs2.default.writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf-8");
790
+ console.log(`📄 JSON 报告已生成: ${reportPath}
756
791
  `);
757
792
  }
758
793
  /**
@@ -770,12 +805,12 @@ var Reporter = class {
770
805
  */
771
806
  getCategoryIcon(category) {
772
807
  const icons = {
773
- security: "\u{1F512}",
774
- performance: "\u26A1",
775
- style: "\u{1F4DD}",
776
- "best-practice": "\u{1F3A8}"
808
+ security: "🔒",
809
+ performance: "",
810
+ style: "📝",
811
+ "best-practice": "🎨"
777
812
  };
778
- return icons[category] || "\u{1F4CB}";
813
+ return icons[category] || "📋";
779
814
  }
780
815
  /**
781
816
  * 获取严重程度图标
@@ -783,13 +818,13 @@ var Reporter = class {
783
818
  getSeverityIcon(severity) {
784
819
  switch (severity) {
785
820
  case "error":
786
- return "\u274C";
821
+ return "";
787
822
  case "warn":
788
- return "\u26A0\uFE0F";
823
+ return "⚠️";
789
824
  case "info":
790
- return "\u2139\uFE0F";
825
+ return "ℹ️";
791
826
  default:
792
- return "\u{1F4DD}";
827
+ return "📝";
793
828
  }
794
829
  }
795
830
  };
@@ -844,20 +879,20 @@ function vitePluginAICodeReview(options = {}) {
844
879
  name: "vite-plugin-ai-code-review",
845
880
  enforce: "post",
846
881
  configResolved(config) {
847
- console.log("\n\u{1F50D} AI Code Review \u5DF2\u542F\u52A8...");
848
- console.log(`\u{1F4C2} \u5BA1\u67E5\u6A21\u5F0F: ${mode}`);
849
- console.log(`\u{1F4CA} \u5BA1\u67E5\u7EA7\u522B: ${level}`);
850
- console.log(`\u{1F511} API Key: ${apiKey ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"}
882
+ console.log("\n🔍 AI Code Review 已启动...");
883
+ console.log(`📂 审查模式: ${mode}`);
884
+ console.log(`📊 审查级别: ${level}`);
885
+ console.log(`🔑 API Key: ${apiKey ? "已配置" : "未配置"}
851
886
  `);
852
887
  },
853
888
  async buildStart() {
854
889
  if (!apiKey) {
855
- console.warn("\u26A0\uFE0F \u672A\u914D\u7F6E API Key\uFF0C\u8DF3\u8FC7\u4EE3\u7801\u5BA1\u67E5");
890
+ console.warn("⚠️ 未配置 API Key,跳过代码审查");
856
891
  return;
857
892
  }
858
893
  if (mode === "changed") {
859
894
  filesToReview = await gitUtils.getChangedFiles();
860
- console.log(`\u{1F50D} [Git] \u68C0\u6D4B\u5230 ${filesToReview.length} \u4E2A\u53D8\u66F4\u6587\u4EF6`);
895
+ console.log(`🔍 [Git] 检测到 ${filesToReview.length} 个变更文件`);
861
896
  filesToReview.forEach((f) => console.log(` - ${f}`));
862
897
  } else if (mode === "manual") {
863
898
  filesToReview = files;
@@ -868,16 +903,16 @@ function vitePluginAICodeReview(options = {}) {
868
903
  (file) => shouldReview(file, include, exclude)
869
904
  );
870
905
  if (mode !== "all" && filesToReview.length > 0) {
871
- console.log(`\u{1F4DD} \u8FC7\u6EE4\u540E\u9700\u8981\u5BA1\u67E5 ${filesToReview.length} \u4E2A\u6587\u4EF6
906
+ console.log(`📝 过滤后需要审查 ${filesToReview.length} 个文件
872
907
  `);
873
908
  for (const file of filesToReview) {
874
909
  try {
875
- const fs3 = await import('fs');
876
- const path3 = await import('path');
910
+ const fs3 = await import("fs");
911
+ const path3 = await import("path");
877
912
  const fullPath = path3.resolve(process.cwd(), file);
878
913
  if (fs3.existsSync(fullPath)) {
879
914
  const code = fs3.readFileSync(fullPath, "utf-8");
880
- console.log(`\u{1F50D} [\u5BA1\u67E5] ${file}`);
915
+ console.log(`🔍 [审查] ${file}`);
881
916
  const issues = await reviewer.review(code, file);
882
917
  if (issues.length > 0) {
883
918
  allIssues.push(...issues);
@@ -889,22 +924,22 @@ function vitePluginAICodeReview(options = {}) {
889
924
  );
890
925
  console.log(` ${issue.message}`);
891
926
  if (issue.suggestion) {
892
- console.log(` \u{1F4A1} ${issue.suggestion}`);
927
+ console.log(` 💡 ${issue.suggestion}`);
893
928
  }
894
929
  });
895
930
  console.log("");
896
931
  }
897
932
  } else {
898
- console.log(`\u2705 \u672A\u53D1\u73B0\u95EE\u9898
933
+ console.log(`✅ 未发现问题
899
934
  `);
900
935
  }
901
936
  }
902
937
  } catch (error) {
903
- console.warn(`\u26A0\uFE0F \u5BA1\u67E5\u5931\u8D25 ${file}: ${error.message}`);
938
+ console.warn(`⚠️ 审查失败 ${file}: ${error.message}`);
904
939
  }
905
940
  }
906
941
  } else if (mode !== "all") {
907
- console.log(`\u{1F4DD} \u6CA1\u6709\u9700\u8981\u5BA1\u67E5\u7684\u6587\u4EF6
942
+ console.log(`📝 没有需要审查的文件
908
943
  `);
909
944
  }
910
945
  },
@@ -919,8 +954,8 @@ function vitePluginAICodeReview(options = {}) {
919
954
  return null;
920
955
  }
921
956
  try {
922
- console.log(`\u{1F50D} [\u5BA1\u67E5] ${id}`);
923
- const fs3 = await import('fs');
957
+ console.log(`🔍 [审查] ${id}`);
958
+ const fs3 = await import("fs");
924
959
  let sourceCode = code;
925
960
  if (fs3.existsSync(id)) {
926
961
  sourceCode = fs3.readFileSync(id, "utf-8");
@@ -936,27 +971,27 @@ function vitePluginAICodeReview(options = {}) {
936
971
  );
937
972
  console.log(` ${issue.message}`);
938
973
  if (issue.suggestion) {
939
- console.log(` \u{1F4A1} ${issue.suggestion}`);
974
+ console.log(` 💡 ${issue.suggestion}`);
940
975
  }
941
976
  });
942
977
  console.log("");
943
978
  }
944
979
  }
945
980
  } catch (error) {
946
- console.warn(`\u26A0\uFE0F \u5BA1\u67E5\u5931\u8D25 ${id}: ${error.message}`);
981
+ console.warn(`⚠️ 审查失败 ${id}: ${error.message}`);
947
982
  }
948
983
  return null;
949
984
  },
950
985
  async buildEnd() {
951
986
  if (allIssues.length === 0) {
952
- console.log("\u2728 \u4EE3\u7801\u5BA1\u67E5\u5B8C\u6210\uFF0C\u672A\u53D1\u73B0\u95EE\u9898\n");
987
+ console.log(" 代码审查完成,未发现问题\n");
953
988
  return;
954
989
  }
955
990
  await reporter.generate(allIssues);
956
991
  if (output.failOnError) {
957
992
  const errors = allIssues.filter((i) => i.severity === "error");
958
993
  if (errors.length > 0) {
959
- throw new Error(`\u4EE3\u7801\u5BA1\u67E5\u53D1\u73B0 ${errors.length} \u4E2A\u9519\u8BEF`);
994
+ throw new Error(`代码审查发现 ${errors.length} 个错误`);
960
995
  }
961
996
  }
962
997
  }
@@ -987,21 +1022,21 @@ function matchPattern(filePath, pattern) {
987
1022
  function getSeverityIcon(severity) {
988
1023
  switch (severity) {
989
1024
  case "error":
990
- return "\u274C";
1025
+ return "";
991
1026
  case "warn":
992
- return "\u26A0\uFE0F";
1027
+ return "⚠️";
993
1028
  case "info":
994
- return "\u2139\uFE0F";
1029
+ return "ℹ️";
995
1030
  default:
996
- return "\u{1F4DD}";
1031
+ return "📝";
997
1032
  }
998
1033
  }
999
1034
  var index_default = vitePluginAICodeReview;
1000
-
1001
- exports.CodeReviewer = CodeReviewer;
1002
- exports.GitUtils = GitUtils;
1003
- exports.Reporter = Reporter;
1004
- exports.default = index_default;
1005
- exports.vitePluginAICodeReview = vitePluginAICodeReview;
1006
- //# sourceMappingURL=index.js.map
1035
+ // Annotate the CommonJS export names for ESM import in node:
1036
+ 0 && (module.exports = {
1037
+ CodeReviewer,
1038
+ GitUtils,
1039
+ Reporter,
1040
+ vitePluginAICodeReview
1041
+ });
1007
1042
  //# sourceMappingURL=index.js.map