@wuyanbin/ai-code-review 1.1.3 → 1.1.5
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/reviewer/index.d.ts.map +1 -1
- package/dist/reviewer/index.js +21 -2
- package/dist/reviewer/index.js.map +1 -1
- package/dist/reviewer/utils.d.ts +21 -0
- package/dist/reviewer/utils.d.ts.map +1 -1
- package/dist/reviewer/utils.js +103 -1
- package/dist/reviewer/utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/adapters/base.d.ts +0 -14
- package/dist/adapters/base.d.ts.map +0 -1
- package/dist/adapters/base.js +0 -3
- package/dist/adapters/base.js.map +0 -1
- package/dist/adapters/factory.d.ts +0 -13
- package/dist/adapters/factory.d.ts.map +0 -1
- package/dist/adapters/factory.js +0 -21
- package/dist/adapters/factory.js.map +0 -1
- package/dist/adapters/gemini.d.ts +0 -11
- package/dist/adapters/gemini.d.ts.map +0 -1
- package/dist/adapters/gemini.js +0 -61
- package/dist/adapters/gemini.js.map +0 -1
- package/dist/adapters/openai.d.ts +0 -7
- package/dist/adapters/openai.d.ts.map +0 -1
- package/dist/adapters/openai.js +0 -68
- package/dist/adapters/openai.js.map +0 -1
- package/dist/reviewer/adapters/base.d.ts +0 -14
- package/dist/reviewer/adapters/base.d.ts.map +0 -1
- package/dist/reviewer/adapters/base.js +0 -3
- package/dist/reviewer/adapters/base.js.map +0 -1
- package/dist/reviewer/adapters/factory.d.ts +0 -13
- package/dist/reviewer/adapters/factory.d.ts.map +0 -1
- package/dist/reviewer/adapters/factory.js +0 -21
- package/dist/reviewer/adapters/factory.js.map +0 -1
- package/dist/reviewer/adapters/gemini.d.ts +0 -11
- package/dist/reviewer/adapters/gemini.d.ts.map +0 -1
- package/dist/reviewer/adapters/gemini.js +0 -61
- package/dist/reviewer/adapters/gemini.js.map +0 -1
- package/dist/reviewer/adapters/openai.d.ts +0 -12
- package/dist/reviewer/adapters/openai.d.ts.map +0 -1
- package/dist/reviewer/adapters/openai.js +0 -54
- package/dist/reviewer/adapters/openai.js.map +0 -1
- package/dist/reviewer.d.ts +0 -9
- package/dist/reviewer.d.ts.map +0 -1
- package/dist/reviewer.js +0 -122
- package/dist/reviewer.js.map +0 -1
- package/dist/rules/index.d.ts +0 -13
- package/dist/rules/index.d.ts.map +0 -1
- package/dist/rules/index.js +0 -50
- package/dist/rules/index.js.map +0 -1
- package/dist/rules/react.d.ts +0 -6
- package/dist/rules/react.d.ts.map +0 -1
- package/dist/rules/react.js +0 -17
- package/dist/rules/react.js.map +0 -1
- package/dist/rules/typescript.d.ts +0 -6
- package/dist/rules/typescript.d.ts.map +0 -1
- package/dist/rules/typescript.js +0 -16
- package/dist/rules/typescript.js.map +0 -1
- package/dist/rules/vue.d.ts +0 -6
- package/dist/rules/vue.d.ts.map +0 -1
- package/dist/rules/vue.js +0 -16
- package/dist/rules/vue.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reviewer/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reviewer/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAuFxD;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EACZ,QAAQ,gBAAgB,KACvB,OAAO,CAAC,UAAU,GAAG,IAAI,CAkF3B,CAAC"}
|
package/dist/reviewer/index.js
CHANGED
|
@@ -41,10 +41,18 @@ const buildUserPrompt = (diff, rules) => {
|
|
|
41
41
|
" }",
|
|
42
42
|
" ]",
|
|
43
43
|
"}",
|
|
44
|
-
"
|
|
44
|
+
"重要说明:",
|
|
45
45
|
"1. 一定要保证输出是合法的 JSON,不能包含注释或多余文本;",
|
|
46
46
|
'2. 如果没有任何问题,也请返回 {"comments": []};',
|
|
47
|
-
"3.
|
|
47
|
+
"3. **line 字段必须是新文件中的绝对行号**,参考 diff 中 @@ 标记的 +行号;",
|
|
48
|
+
"4. 只对 diff 中以 + 开头的新增行或修改行进行评论;",
|
|
49
|
+
"5. file 字段使用 diff 中 b/ 后面的路径(即新文件路径)。",
|
|
50
|
+
"",
|
|
51
|
+
"Git diff 格式说明:",
|
|
52
|
+
"- diff 中的 @@ -a,b +c,d @@ 表示:新文件从第 c 行开始",
|
|
53
|
+
"- 以 + 开头的行是新增或修改的代码",
|
|
54
|
+
"- 以空格开头的行是上下文(未修改)",
|
|
55
|
+
"- 以 - 开头的行是删除的代码",
|
|
48
56
|
"",
|
|
49
57
|
"项目规范(摘要):",
|
|
50
58
|
rulesBrief,
|
|
@@ -82,6 +90,9 @@ const reviewCode = async (diff, config) => {
|
|
|
82
90
|
console.error("[reviewer] diff 为空,跳过审查");
|
|
83
91
|
return { comments: [] };
|
|
84
92
|
}
|
|
93
|
+
// 解析 diff,提取文件和行号映射
|
|
94
|
+
const diffFiles = (0, utils_1.parseDiffFiles)(effectiveDiff);
|
|
95
|
+
console.error(`[reviewer] 解析到 ${diffFiles.size} 个文件的变更信息`);
|
|
85
96
|
if (!config.ai.apiKey || !config.ai.endpoint) {
|
|
86
97
|
console.error("[reviewer] 缺少 API 配置");
|
|
87
98
|
return null;
|
|
@@ -104,6 +115,14 @@ const reviewCode = async (diff, config) => {
|
|
|
104
115
|
}
|
|
105
116
|
// 应用过滤和限制
|
|
106
117
|
let comments = result.comments || [];
|
|
118
|
+
// **关键步骤:验证并修正行号**
|
|
119
|
+
comments = comments.map((comment) => {
|
|
120
|
+
const correctedLine = (0, utils_1.validateAndFixLineNumber)(comment.file, comment.line, diffFiles);
|
|
121
|
+
return {
|
|
122
|
+
...comment,
|
|
123
|
+
line: correctedLine,
|
|
124
|
+
};
|
|
125
|
+
});
|
|
107
126
|
// 过滤 severity
|
|
108
127
|
if (config.review?.severity) {
|
|
109
128
|
const severityOrder = { info: 0, warning: 1, error: 2 };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reviewer/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAGH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reviewer/index.ts"],"names":[],"mappings":"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"}
|
package/dist/reviewer/utils.d.ts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff 文件信息,包含行号映射
|
|
3
|
+
*/
|
|
4
|
+
export interface DiffFileInfo {
|
|
5
|
+
path: string;
|
|
6
|
+
changedLines: Set<number>;
|
|
7
|
+
lineRanges: Array<{
|
|
8
|
+
start: number;
|
|
9
|
+
count: number;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 解析 Git diff,提取文件路径和变更行号
|
|
14
|
+
* 返回每个文件的变更信息
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseDiffFiles: (diff: string) => Map<string, DiffFileInfo>;
|
|
17
|
+
/**
|
|
18
|
+
* 验证并修正评论的行号
|
|
19
|
+
* 如果行号不在变更行集合中,尝试找到最近的变更行
|
|
20
|
+
*/
|
|
21
|
+
export declare const validateAndFixLineNumber: (file: string, line: number, diffFiles: Map<string, DiffFileInfo>) => number;
|
|
1
22
|
/**
|
|
2
23
|
* 简单的 glob -> RegExp 转换,只覆盖当前项目常用模式:
|
|
3
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/reviewer/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAwB9C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,OAG7D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,gBAAgB,MAAM,EAAE,GAAG,SAAS,KACnC,OAGF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,gBAAgB,MAAM,EAAE,GAAG,SAAS,KACnC,MAiEF,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/reviewer/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAE1B,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAuErE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,MAAM,MAAM,EACZ,MAAM,MAAM,EACZ,WAAW,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,KACnC,MA2CF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAwB9C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,OAG7D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,gBAAgB,MAAM,EAAE,GAAG,SAAS,KACnC,OAGF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,EACZ,gBAAgB,MAAM,EAAE,GAAG,SAAS,KACnC,MAiEF,CAAC"}
|
package/dist/reviewer/utils.js
CHANGED
|
@@ -1,6 +1,108 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterDiffByIgnore = exports.shouldIgnoreFile = exports.matchGlob = exports.globToRegExp = void 0;
|
|
3
|
+
exports.filterDiffByIgnore = exports.shouldIgnoreFile = exports.matchGlob = exports.globToRegExp = exports.validateAndFixLineNumber = exports.parseDiffFiles = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 解析 Git diff,提取文件路径和变更行号
|
|
6
|
+
* 返回每个文件的变更信息
|
|
7
|
+
*/
|
|
8
|
+
const parseDiffFiles = (diff) => {
|
|
9
|
+
const files = new Map();
|
|
10
|
+
const lines = diff.split("\n");
|
|
11
|
+
let currentFile = null;
|
|
12
|
+
let currentFileInfo = null;
|
|
13
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14
|
+
const line = lines[i];
|
|
15
|
+
// 检测新文件块:diff --git a/xxx b/xxx
|
|
16
|
+
if (line.startsWith("diff --git ")) {
|
|
17
|
+
const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
|
|
18
|
+
if (match) {
|
|
19
|
+
currentFile = match[2]; // 使用 b/ 路径(新文件路径)
|
|
20
|
+
currentFileInfo = {
|
|
21
|
+
path: currentFile,
|
|
22
|
+
changedLines: new Set(),
|
|
23
|
+
lineRanges: [],
|
|
24
|
+
};
|
|
25
|
+
files.set(currentFile, currentFileInfo);
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// 解析行号范围标记:@@ -a,b +c,d @@
|
|
30
|
+
// -a,b 表示旧文件从第 a 行开始的 b 行
|
|
31
|
+
// +c,d 表示新文件从第 c 行开始的 d 行
|
|
32
|
+
if (line.startsWith("@@") && currentFileInfo) {
|
|
33
|
+
const match = /@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/.exec(line);
|
|
34
|
+
if (match) {
|
|
35
|
+
const newStart = parseInt(match[1], 10);
|
|
36
|
+
const newCount = match[2] ? parseInt(match[2], 10) : 1;
|
|
37
|
+
currentFileInfo.lineRanges.push({
|
|
38
|
+
start: newStart,
|
|
39
|
+
count: newCount,
|
|
40
|
+
});
|
|
41
|
+
// 记录从 @@ 标记后开始的实际行号
|
|
42
|
+
let lineNumber = newStart;
|
|
43
|
+
// 继续向下解析,直到遇到下一个 @@ 或 diff --git
|
|
44
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
45
|
+
const contentLine = lines[j];
|
|
46
|
+
// 遇到下一个块,停止
|
|
47
|
+
if (contentLine.startsWith("@@") ||
|
|
48
|
+
contentLine.startsWith("diff --git ")) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
// + 开头的是新增行
|
|
52
|
+
if (contentLine.startsWith("+") && !contentLine.startsWith("+++")) {
|
|
53
|
+
currentFileInfo.changedLines.add(lineNumber);
|
|
54
|
+
lineNumber++;
|
|
55
|
+
}
|
|
56
|
+
// 空格开头的是上下文行(未变更)
|
|
57
|
+
else if (contentLine.startsWith(" ")) {
|
|
58
|
+
lineNumber++;
|
|
59
|
+
}
|
|
60
|
+
// - 开头的是删除行,不增加新文件的行号
|
|
61
|
+
// 其他行(如 \ No newline)也忽略
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return files;
|
|
67
|
+
};
|
|
68
|
+
exports.parseDiffFiles = parseDiffFiles;
|
|
69
|
+
/**
|
|
70
|
+
* 验证并修正评论的行号
|
|
71
|
+
* 如果行号不在变更行集合中,尝试找到最近的变更行
|
|
72
|
+
*/
|
|
73
|
+
const validateAndFixLineNumber = (file, line, diffFiles) => {
|
|
74
|
+
const fileInfo = diffFiles.get(file);
|
|
75
|
+
if (!fileInfo) {
|
|
76
|
+
// 文件不在 diff 中,返回原始行号
|
|
77
|
+
console.warn(`[utils] 文件 ${file} 不在 diff 中,无法验证行号`);
|
|
78
|
+
return line;
|
|
79
|
+
}
|
|
80
|
+
// 如果行号正好在变更行集合中,直接返回
|
|
81
|
+
if (fileInfo.changedLines.has(line)) {
|
|
82
|
+
return line;
|
|
83
|
+
}
|
|
84
|
+
// 行号不在变更集合中,尝试找到最近的变更行
|
|
85
|
+
const changedLinesArray = Array.from(fileInfo.changedLines).sort((a, b) => a - b);
|
|
86
|
+
if (changedLinesArray.length === 0) {
|
|
87
|
+
console.warn(`[utils] 文件 ${file} 没有变更行,返回原始行号 ${line}`);
|
|
88
|
+
return line;
|
|
89
|
+
}
|
|
90
|
+
// 找到最接近的变更行
|
|
91
|
+
let closest = changedLinesArray[0];
|
|
92
|
+
let minDistance = Math.abs(line - closest);
|
|
93
|
+
for (const changedLine of changedLinesArray) {
|
|
94
|
+
const distance = Math.abs(line - changedLine);
|
|
95
|
+
if (distance < minDistance) {
|
|
96
|
+
minDistance = distance;
|
|
97
|
+
closest = changedLine;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (closest !== line) {
|
|
101
|
+
console.warn(`[utils] 行号修正: ${file}:${line} -> ${closest} (偏差 ${minDistance} 行)`);
|
|
102
|
+
}
|
|
103
|
+
return closest;
|
|
104
|
+
};
|
|
105
|
+
exports.validateAndFixLineNumber = validateAndFixLineNumber;
|
|
4
106
|
/**
|
|
5
107
|
* 简单的 glob -> RegExp 转换,只覆盖当前项目常用模式:
|
|
6
108
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/reviewer/utils.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/reviewer/utils.ts"],"names":[],"mappings":";;;AAWA;;;GAGG;AACI,MAAM,cAAc,GAAG,CAAC,IAAY,EAA6B,EAAE;IACxE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,eAAe,GAAwB,IAAI,CAAC;IAEhD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,gCAAgC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,KAAK,EAAE,CAAC;gBACV,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB;gBAC1C,eAAe,GAAG;oBAChB,IAAI,EAAE,WAAW;oBACjB,YAAY,EAAE,IAAI,GAAG,EAAE;oBACvB,UAAU,EAAE,EAAE;iBACf,CAAC;gBACF,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;YAC1C,CAAC;YACD,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,0BAA0B;QAC1B,0BAA0B;QAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,eAAe,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEvD,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC;oBAC9B,KAAK,EAAE,QAAQ;oBACf,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;gBAEH,oBAAoB;gBACpB,IAAI,UAAU,GAAG,QAAQ,CAAC;gBAE1B,iCAAiC;gBACjC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBAE7B,YAAY;oBACZ,IACE,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC5B,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,EACrC,CAAC;wBACD,MAAM;oBACR,CAAC;oBAED,YAAY;oBACZ,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;wBAClE,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;wBAC7C,UAAU,EAAE,CAAC;oBACf,CAAC;oBACD,kBAAkB;yBACb,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACrC,UAAU,EAAE,CAAC;oBACf,CAAC;oBACD,sBAAsB;oBACtB,yBAAyB;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAvEW,QAAA,cAAc,kBAuEzB;AAEF;;;GAGG;AACI,MAAM,wBAAwB,GAAG,CACtC,IAAY,EACZ,IAAY,EACZ,SAAoC,EAC5B,EAAE;IACV,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,qBAAqB;QACrB,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,mBAAmB,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uBAAuB;IACvB,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,IAAI,CAC9D,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAChB,CAAC;IAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,iBAAiB,IAAI,EAAE,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY;IACZ,IAAI,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;IAE3C,KAAK,MAAM,WAAW,IAAI,iBAAiB,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;QAC9C,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC3B,WAAW,GAAG,QAAQ,CAAC;YACvB,OAAO,GAAG,WAAW,CAAC;QACxB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,iBAAiB,IAAI,IAAI,IAAI,OAAO,OAAO,QAAQ,WAAW,KAAK,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AA/CW,QAAA,wBAAwB,4BA+CnC;AAEF;;;;;;;GAOG;AACI,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE;IACtD,uCAAuC;IACvC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc;QACnD,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACnE,eAAe;QACf,OAAO,IAAI,MAAM,CAAC,IAAI,aAAa,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa;QAC5C,MAAM,WAAW,GAAG,IAAI;aACrB,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;aACrC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3B,4BAA4B;QAC5B,OAAO,IAAI,MAAM,CAAC,YAAY,WAAW,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,2BAA2B;IAC3B,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;SACrC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3B,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;AACpC,CAAC,CAAC;AAxBW,QAAA,YAAY,gBAwBvB;AAEK,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAW,EAAE;IACtE,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC,CAAC;AAHW,QAAA,SAAS,aAGpB;AAEK,MAAM,gBAAgB,GAAG,CAC9B,QAAgB,EAChB,cAAoC,EAC3B,EAAE;IACX,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,iBAAS,EAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC,CAAC;AANW,QAAA,gBAAgB,oBAM3B;AAEF;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,CAChC,IAAY,EACZ,cAAoC,EAC5B,EAAE;IACV,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,uBAAuB;IACvB,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,eAAe;YACf,WAAW,GAAG,IAAI,CAAC;YACnB,aAAa,GAAG,KAAK,CAAC;YAEtB,MAAM,KAAK,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,KAAK,EAAE,CAAC;gBACV,2BAA2B;gBAC3B,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,aAAa,GAAG,IAAA,wBAAgB,EAAC,WAAW,EAAE,cAAc,CAAC,CAAC;gBAE9D,IAAI,WAAW,EAAE,CAAC;oBAChB,IAAI,aAAa,EAAE,CAAC;wBAClB,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBAChC,CAAC;yBAAM,CAAC;wBACN,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,0CAA0C;YAC1C,SAAS;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CACX,yBAAyB,EACzB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;IACJ,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CACX,4BAA4B,EAC5B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC,CAAC;AApEW,QAAA,kBAAkB,sBAoE7B"}
|
package/package.json
CHANGED
package/dist/adapters/base.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模型适配器基础接口
|
|
3
|
-
*/
|
|
4
|
-
export interface ModelAdapter {
|
|
5
|
-
/**
|
|
6
|
-
* 调用模型进行代码审查
|
|
7
|
-
* @param model 模型名称
|
|
8
|
-
* @param systemPrompt 系统提示词
|
|
9
|
-
* @param userPrompt 用户提示词
|
|
10
|
-
* @returns AI 返回的原始内容,失败返回 null
|
|
11
|
-
*/
|
|
12
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,IAAI,CACF,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3B"}
|
package/dist/adapters/base.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模型适配器工厂
|
|
3
|
-
* 根据 endpoint 自动选择合适的适配器
|
|
4
|
-
*/
|
|
5
|
-
import { ModelAdapter } from "./base";
|
|
6
|
-
/**
|
|
7
|
-
* 创建模型适配器
|
|
8
|
-
* @param endpoint API 端点
|
|
9
|
-
* @param apiKey API 密钥
|
|
10
|
-
* @returns 对应的模型适配器实例
|
|
11
|
-
*/
|
|
12
|
-
export declare function createAdapter(endpoint: string, apiKey: string): ModelAdapter;
|
|
13
|
-
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/adapters/factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,YAAY,CAWd"}
|
package/dist/adapters/factory.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createAdapter = createAdapter;
|
|
4
|
-
const openai_1 = require("./openai");
|
|
5
|
-
const gemini_1 = require("./gemini");
|
|
6
|
-
/**
|
|
7
|
-
* 创建模型适配器
|
|
8
|
-
* @param endpoint API 端点
|
|
9
|
-
* @param apiKey API 密钥
|
|
10
|
-
* @returns 对应的模型适配器实例
|
|
11
|
-
*/
|
|
12
|
-
function createAdapter(endpoint, apiKey) {
|
|
13
|
-
// 判断是否为 Gemini
|
|
14
|
-
if (endpoint.includes("generativelanguage.googleapis.com") ||
|
|
15
|
-
endpoint.includes(":generateContent")) {
|
|
16
|
-
return new gemini_1.GeminiAdapter(endpoint, apiKey);
|
|
17
|
-
}
|
|
18
|
-
// 默认使用 OpenAI 适配器(支持 DeepSeek/Qwen/OpenAI 等兼容模型)
|
|
19
|
-
return new openai_1.OpenAIAdapter(endpoint, apiKey);
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/adapters/factory.ts"],"names":[],"mappings":";;AAcA,sCAcC;AAvBD,qCAAyC;AACzC,qCAAyC;AAEzC;;;;;GAKG;AACH,SAAgB,aAAa,CAC3B,QAAgB,EAChB,MAAc;IAEd,eAAe;IACf,IACE,QAAQ,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACtD,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EACrC,CAAC;QACD,OAAO,IAAI,sBAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,iDAAiD;IACjD,OAAO,IAAI,sBAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Gemini 模型适配器
|
|
3
|
-
*/
|
|
4
|
-
import { ModelAdapter } from "./base";
|
|
5
|
-
export declare class GeminiAdapter implements ModelAdapter {
|
|
6
|
-
private endpoint;
|
|
7
|
-
private apiKey;
|
|
8
|
-
constructor(endpoint: string, apiKey: string);
|
|
9
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAatC,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKtC,IAAI,CACR,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA0D1B"}
|
package/dist/adapters/gemini.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GeminiAdapter = void 0;
|
|
4
|
-
class GeminiAdapter {
|
|
5
|
-
constructor(endpoint, apiKey) {
|
|
6
|
-
this.endpoint = endpoint;
|
|
7
|
-
this.apiKey = apiKey;
|
|
8
|
-
}
|
|
9
|
-
async call(model, systemPrompt, userPrompt) {
|
|
10
|
-
try {
|
|
11
|
-
let url = this.endpoint;
|
|
12
|
-
// Gemini: API Key 在 Query 参数中
|
|
13
|
-
// 如果 endpoint 本身不含 ?key=... 则追加
|
|
14
|
-
if (!url.includes("key=")) {
|
|
15
|
-
const separator = url.includes("?") ? "&" : "?";
|
|
16
|
-
url = `${url}${separator}key=${this.apiKey}`;
|
|
17
|
-
}
|
|
18
|
-
// Gemini 的 Payload 结构
|
|
19
|
-
const payload = {
|
|
20
|
-
contents: [
|
|
21
|
-
{
|
|
22
|
-
parts: [
|
|
23
|
-
{
|
|
24
|
-
text: `${systemPrompt}\n\n${userPrompt}`, // Gemini 没有显式的 system role,通常合并到 prompt
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
generationConfig: {
|
|
30
|
-
response_mime_type: "application/json", // Gemini 1.5 Pro/Flash 支持指定 JSON 输出
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const response = await fetch(url, {
|
|
34
|
-
method: "POST",
|
|
35
|
-
headers: {
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify(payload),
|
|
39
|
-
});
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
console.error(`[GeminiAdapter] AI API 调用失败,status=${response.status}`);
|
|
42
|
-
const errorText = await response.text();
|
|
43
|
-
console.error(`[GeminiAdapter] 错误详情: ${errorText}`);
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
const resJson = (await response.json());
|
|
47
|
-
const rawContent = resJson.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
48
|
-
if (!rawContent) {
|
|
49
|
-
console.error("[GeminiAdapter] AI 返回内容为空");
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return String(rawContent).trim();
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
console.error("[GeminiAdapter] AI API 调用异常:", error);
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
exports.GeminiAdapter = GeminiAdapter;
|
|
61
|
-
//# sourceMappingURL=gemini.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":";;;AAgBA,MAAa,aAAa;IAIxB,YAAY,QAAgB,EAAE,MAAc;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,YAAoB,EACpB,UAAkB;QAElB,IAAI,CAAC;YACH,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;YAExB,8BAA8B;YAC9B,gCAAgC;YAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBAChD,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/C,CAAC;YAED,sBAAsB;YACtB,MAAM,OAAO,GAAG;gBACd,QAAQ,EAAE;oBACR;wBACE,KAAK,EAAE;4BACL;gCACE,IAAI,EAAE,GAAG,YAAY,OAAO,UAAU,EAAE,EAAE,wCAAwC;6BACnF;yBACF;qBACF;iBACF;gBACD,gBAAgB,EAAE;oBAChB,kBAAkB,EAAE,kBAAkB,EAAE,oCAAoC;iBAC7E;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,sCAAsC,QAAQ,CAAC,MAAM,EAAE,CACxD,CAAC;gBACF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;YAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YAEtE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAvED,sCAuEC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { ModelAdapter } from "./base";
|
|
2
|
-
export declare class OpenAIAdapter implements ModelAdapter {
|
|
3
|
-
private client;
|
|
4
|
-
constructor(endpoint: string, apiKey: string);
|
|
5
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAgCtC,IAAI,CACR,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA2B1B"}
|
package/dist/adapters/openai.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.OpenAIAdapter = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* OpenAI 兼容模型适配器
|
|
9
|
-
* 支持 OpenAI、DeepSeek、Qwen 等使用 OpenAI 兼容接口的模型
|
|
10
|
-
*/
|
|
11
|
-
const openai_1 = __importDefault(require("openai"));
|
|
12
|
-
class OpenAIAdapter {
|
|
13
|
-
constructor(endpoint, apiKey) {
|
|
14
|
-
// 自动补全 /chat/completions 路径(如果需要)
|
|
15
|
-
let baseURL = endpoint;
|
|
16
|
-
if (!baseURL.endsWith("/chat/completions") &&
|
|
17
|
-
!baseURL.endsWith("/v1") &&
|
|
18
|
-
!baseURL.endsWith("/v1/")) {
|
|
19
|
-
// 移除末尾斜杠
|
|
20
|
-
baseURL = baseURL.replace(/\/+$/, "");
|
|
21
|
-
// OpenAI SDK 期望的是 baseURL(不包含 /chat/completions)
|
|
22
|
-
// 如果用户提供了完整路径,我们需要截取
|
|
23
|
-
if (baseURL.endsWith("/chat/completions")) {
|
|
24
|
-
baseURL = baseURL.replace(/\/chat\/completions$/, "");
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
// 确保以 /v1 结尾(OpenAI SDK 标准)
|
|
28
|
-
if (!baseURL.endsWith("/v1") && !baseURL.endsWith("/v1/")) {
|
|
29
|
-
if (baseURL.includes("/compatible-mode/v1")) {
|
|
30
|
-
// Qwen 的特殊情况,已经包含了版本路径
|
|
31
|
-
}
|
|
32
|
-
else if (!baseURL.includes("/v1")) {
|
|
33
|
-
baseURL += "/v1";
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
this.client = new openai_1.default({
|
|
37
|
-
apiKey,
|
|
38
|
-
baseURL,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
async call(model, systemPrompt, userPrompt) {
|
|
42
|
-
try {
|
|
43
|
-
const response = await this.client.chat.completions.create({
|
|
44
|
-
model,
|
|
45
|
-
messages: [
|
|
46
|
-
{ role: "system", content: systemPrompt },
|
|
47
|
-
{ role: "user", content: userPrompt },
|
|
48
|
-
],
|
|
49
|
-
stream: false,
|
|
50
|
-
});
|
|
51
|
-
const rawContent = response.choices?.[0]?.message?.content;
|
|
52
|
-
if (!rawContent) {
|
|
53
|
-
console.error("[OpenAIAdapter] AI 返回内容为空");
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
return String(rawContent).trim();
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error("[OpenAIAdapter] AI API 调用异常:", error);
|
|
60
|
-
if (error instanceof Error) {
|
|
61
|
-
console.error("[OpenAIAdapter] 错误详情:", error.message);
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
exports.OpenAIAdapter = OpenAIAdapter;
|
|
68
|
-
//# sourceMappingURL=openai.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":";;;;;;AAAA;;;GAGG;AACH,oDAA4B;AAG5B,MAAa,aAAa;IAGxB,YAAY,QAAgB,EAAE,MAAc;QAC1C,kCAAkC;QAClC,IAAI,OAAO,GAAG,QAAQ,CAAC;QACvB,IACE,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACtC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YACxB,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACzB,CAAC;YACD,SAAS;YACT,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACtC,iDAAiD;YACjD,qBAAqB;YACrB,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC1C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1D,IAAI,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAC5C,uBAAuB;YACzB,CAAC;iBAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAM,CAAC;YACvB,MAAM;YACN,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,YAAoB,EACpB,UAAkB;QAElB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;gBACzD,KAAK;gBACL,QAAQ,EAAE;oBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;oBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;iBACtC;gBACD,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;YAE3D,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAlED,sCAkEC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模型适配器基础接口
|
|
3
|
-
*/
|
|
4
|
-
export interface ModelAdapter {
|
|
5
|
-
/**
|
|
6
|
-
* 调用模型进行代码审查
|
|
7
|
-
* @param model 模型名称
|
|
8
|
-
* @param systemPrompt 系统提示词
|
|
9
|
-
* @param userPrompt 用户提示词
|
|
10
|
-
* @returns AI 返回的原始内容,失败返回 null
|
|
11
|
-
*/
|
|
12
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/reviewer/adapters/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,IAAI,CACF,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/reviewer/adapters/base.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模型适配器工厂
|
|
3
|
-
* 根据 endpoint 自动选择合适的适配器
|
|
4
|
-
*/
|
|
5
|
-
import { ModelAdapter } from "./base";
|
|
6
|
-
/**
|
|
7
|
-
* 创建模型适配器
|
|
8
|
-
* @param endpoint API 端点
|
|
9
|
-
* @param apiKey API 密钥
|
|
10
|
-
* @returns 对应的模型适配器实例
|
|
11
|
-
*/
|
|
12
|
-
export declare function createAdapter(endpoint: string, apiKey: string): ModelAdapter;
|
|
13
|
-
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/reviewer/adapters/factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAW5E"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createAdapter = createAdapter;
|
|
4
|
-
const openai_1 = require("./openai");
|
|
5
|
-
const gemini_1 = require("./gemini");
|
|
6
|
-
/**
|
|
7
|
-
* 创建模型适配器
|
|
8
|
-
* @param endpoint API 端点
|
|
9
|
-
* @param apiKey API 密钥
|
|
10
|
-
* @returns 对应的模型适配器实例
|
|
11
|
-
*/
|
|
12
|
-
function createAdapter(endpoint, apiKey) {
|
|
13
|
-
// 判断是否为 Gemini
|
|
14
|
-
if (endpoint.includes("generativelanguage.googleapis.com") ||
|
|
15
|
-
endpoint.includes(":generateContent")) {
|
|
16
|
-
return new gemini_1.GeminiAdapter(endpoint, apiKey);
|
|
17
|
-
}
|
|
18
|
-
// 默认使用 OpenAI 适配器(支持 DeepSeek/Qwen/OpenAI 等兼容模型)
|
|
19
|
-
return new openai_1.OpenAIAdapter(endpoint, apiKey);
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/reviewer/adapters/factory.ts"],"names":[],"mappings":";;AAcA,sCAWC;AApBD,qCAAyC;AACzC,qCAAyC;AAEzC;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,QAAgB,EAAE,MAAc;IAC5D,eAAe;IACf,IACE,QAAQ,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACtD,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EACrC,CAAC;QACD,OAAO,IAAI,sBAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,iDAAiD;IACjD,OAAO,IAAI,sBAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Gemini 模型适配器
|
|
3
|
-
*/
|
|
4
|
-
import { ModelAdapter } from "./base";
|
|
5
|
-
export declare class GeminiAdapter implements ModelAdapter {
|
|
6
|
-
private endpoint;
|
|
7
|
-
private apiKey;
|
|
8
|
-
constructor(endpoint: string, apiKey: string);
|
|
9
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/reviewer/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAatC,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKtC,IAAI,CACR,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA0D1B"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GeminiAdapter = void 0;
|
|
4
|
-
class GeminiAdapter {
|
|
5
|
-
constructor(endpoint, apiKey) {
|
|
6
|
-
this.endpoint = endpoint;
|
|
7
|
-
this.apiKey = apiKey;
|
|
8
|
-
}
|
|
9
|
-
async call(model, systemPrompt, userPrompt) {
|
|
10
|
-
try {
|
|
11
|
-
let url = this.endpoint;
|
|
12
|
-
// Gemini: API Key 在 Query 参数中
|
|
13
|
-
// 如果 endpoint 本身不含 ?key=... 则追加
|
|
14
|
-
if (!url.includes("key=")) {
|
|
15
|
-
const separator = url.includes("?") ? "&" : "?";
|
|
16
|
-
url = `${url}${separator}key=${this.apiKey}`;
|
|
17
|
-
}
|
|
18
|
-
// Gemini 的 Payload 结构
|
|
19
|
-
const payload = {
|
|
20
|
-
contents: [
|
|
21
|
-
{
|
|
22
|
-
parts: [
|
|
23
|
-
{
|
|
24
|
-
text: `${systemPrompt}\n\n${userPrompt}`, // Gemini 没有显式的 system role,通常合并到 prompt
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
generationConfig: {
|
|
30
|
-
response_mime_type: "application/json", // Gemini 1.5 Pro/Flash 支持指定 JSON 输出
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const response = await fetch(url, {
|
|
34
|
-
method: "POST",
|
|
35
|
-
headers: {
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify(payload),
|
|
39
|
-
});
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
console.error(`[GeminiAdapter] AI API 调用失败,status=${response.status}`);
|
|
42
|
-
const errorText = await response.text();
|
|
43
|
-
console.error(`[GeminiAdapter] 错误详情: ${errorText}`);
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
const resJson = (await response.json());
|
|
47
|
-
const rawContent = resJson.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
48
|
-
if (!rawContent) {
|
|
49
|
-
console.error("[GeminiAdapter] AI 返回内容为空");
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return String(rawContent).trim();
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
console.error("[GeminiAdapter] AI API 调用异常:", error);
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
exports.GeminiAdapter = GeminiAdapter;
|
|
61
|
-
//# sourceMappingURL=gemini.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/reviewer/adapters/gemini.ts"],"names":[],"mappings":";;;AAgBA,MAAa,aAAa;IAIxB,YAAY,QAAgB,EAAE,MAAc;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,YAAoB,EACpB,UAAkB;QAElB,IAAI,CAAC;YACH,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;YAExB,8BAA8B;YAC9B,gCAAgC;YAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBAChD,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/C,CAAC;YAED,sBAAsB;YACtB,MAAM,OAAO,GAAG;gBACd,QAAQ,EAAE;oBACR;wBACE,KAAK,EAAE;4BACL;gCACE,IAAI,EAAE,GAAG,YAAY,OAAO,UAAU,EAAE,EAAE,wCAAwC;6BACnF;yBACF;qBACF;iBACF;gBACD,gBAAgB,EAAE;oBAChB,kBAAkB,EAAE,kBAAkB,EAAE,oCAAoC;iBAC7E;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,sCAAsC,QAAQ,CAAC,MAAM,EAAE,CACxD,CAAC;gBACF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;YAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YAEtE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAvED,sCAuEC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI 兼容模型适配器
|
|
3
|
-
* 支持 OpenAI、DeepSeek、Qwen 等使用 OpenAI 兼容接口的模型
|
|
4
|
-
*/
|
|
5
|
-
import { ModelAdapter } from "./base";
|
|
6
|
-
export declare class OpenAIAdapter implements ModelAdapter {
|
|
7
|
-
private endpoint;
|
|
8
|
-
private apiKey;
|
|
9
|
-
constructor(endpoint: string, apiKey: string);
|
|
10
|
-
call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/reviewer/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAWtC,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKtC,IAAI,CACR,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAmD1B"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpenAIAdapter = void 0;
|
|
4
|
-
class OpenAIAdapter {
|
|
5
|
-
constructor(endpoint, apiKey) {
|
|
6
|
-
this.endpoint = endpoint;
|
|
7
|
-
this.apiKey = apiKey;
|
|
8
|
-
}
|
|
9
|
-
async call(model, systemPrompt, userPrompt) {
|
|
10
|
-
try {
|
|
11
|
-
let url = this.endpoint;
|
|
12
|
-
// 如果 endpoint 不以 /chat/completions 结尾,自动补全
|
|
13
|
-
if (!url.endsWith("/chat/completions")) {
|
|
14
|
-
url = url.replace(/\/+$/, ""); // 移除末尾斜杠
|
|
15
|
-
url += "/chat/completions";
|
|
16
|
-
}
|
|
17
|
-
const payload = {
|
|
18
|
-
model,
|
|
19
|
-
messages: [
|
|
20
|
-
{ role: "system", content: systemPrompt },
|
|
21
|
-
{ role: "user", content: userPrompt },
|
|
22
|
-
],
|
|
23
|
-
stream: false,
|
|
24
|
-
};
|
|
25
|
-
const response = await fetch(url, {
|
|
26
|
-
method: "POST",
|
|
27
|
-
headers: {
|
|
28
|
-
"Content-Type": "application/json",
|
|
29
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
30
|
-
},
|
|
31
|
-
body: JSON.stringify(payload),
|
|
32
|
-
});
|
|
33
|
-
if (!response.ok) {
|
|
34
|
-
console.error(`[OpenAIAdapter] AI API 调用失败,status=${response.status}`);
|
|
35
|
-
const errorText = await response.text();
|
|
36
|
-
console.error(`[OpenAIAdapter] 错误详情: ${errorText}`);
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
const resJson = (await response.json());
|
|
40
|
-
const rawContent = resJson.choices?.[0]?.message?.content;
|
|
41
|
-
if (!rawContent) {
|
|
42
|
-
console.error("[OpenAIAdapter] AI 返回内容为空");
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
return String(rawContent).trim();
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
console.error("[OpenAIAdapter] AI API 调用异常:", error);
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
exports.OpenAIAdapter = OpenAIAdapter;
|
|
54
|
-
//# sourceMappingURL=openai.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/reviewer/adapters/openai.ts"],"names":[],"mappings":";;;AAeA,MAAa,aAAa;IAIxB,YAAY,QAAgB,EAAE,MAAc;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,YAAoB,EACpB,UAAkB;QAElB,IAAI,CAAC;YACH,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;YAExB,2CAA2C;YAC3C,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACvC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;gBACxC,GAAG,IAAI,mBAAmB,CAAC;YAC7B,CAAC;YAED,MAAM,OAAO,GAAG;gBACd,KAAK;gBACL,QAAQ,EAAE;oBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;oBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;iBACtC;gBACD,MAAM,EAAE,KAAK;aACd,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,sCAAsC,QAAQ,CAAC,MAAM,EAAE,CACxD,CAAC;gBACF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;YAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;YAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAhED,sCAgEC"}
|
package/dist/reviewer.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Code Reviewer 核心逻辑
|
|
3
|
-
*/
|
|
4
|
-
import { AIResponse, CodeReviewConfig } from "./types";
|
|
5
|
-
/**
|
|
6
|
-
* 执行 AI Code Review
|
|
7
|
-
*/
|
|
8
|
-
export declare const reviewCode: (diff: string, config: CodeReviewConfig) => Promise<AIResponse | null>;
|
|
9
|
-
//# sourceMappingURL=reviewer.d.ts.map
|
package/dist/reviewer.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../src/reviewer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA2EvD;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EACZ,QAAQ,gBAAgB,KACvB,OAAO,CAAC,UAAU,GAAG,IAAI,CA8D3B,CAAC"}
|
package/dist/reviewer.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* AI Code Reviewer 核心逻辑
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.reviewCode = void 0;
|
|
7
|
-
const utils_1 = require("./utils");
|
|
8
|
-
const factory_1 = require("./adapters/factory");
|
|
9
|
-
/**
|
|
10
|
-
* 通用代码质量规则(始终启用)
|
|
11
|
-
*/
|
|
12
|
-
const commonRules = [
|
|
13
|
-
"重点关注潜在 bug、性能问题、可读性与安全性(如 XSS、注入、敏感信息泄露)",
|
|
14
|
-
"代码要有适当的错误处理",
|
|
15
|
-
"避免代码重复,注意抽离复用逻辑",
|
|
16
|
-
"函数和变量命名要语义化,见名知意",
|
|
17
|
-
"复杂逻辑要添加注释说明",
|
|
18
|
-
];
|
|
19
|
-
/**
|
|
20
|
-
* 构建系统 Prompt
|
|
21
|
-
*/
|
|
22
|
-
const buildSystemPrompt = () => {
|
|
23
|
-
return "你是一个资深的代码审查助手,需要根据给定的 Git diff 和项目规范,对改动的代码进行严格的 Code Review。";
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* 构建用户 Prompt
|
|
27
|
-
*/
|
|
28
|
-
const buildUserPrompt = (diff, rules) => {
|
|
29
|
-
const rulesBrief = rules.join("\n");
|
|
30
|
-
return [
|
|
31
|
-
"请你只针对 diff 中【新增或修改】的代码行给出审查意见。",
|
|
32
|
-
"输出格式要求:必须返回严格的 JSON,形如:",
|
|
33
|
-
"{",
|
|
34
|
-
' "comments": [',
|
|
35
|
-
" {",
|
|
36
|
-
' "file": "src/xxx.tsx",',
|
|
37
|
-
' "line": 123,',
|
|
38
|
-
' "severity": "info" | "warning" | "error",',
|
|
39
|
-
' "message": "问题描述(中文,简洁具体)",',
|
|
40
|
-
' "suggestion": "可选的修复建议或更佳写法(中文)"',
|
|
41
|
-
" }",
|
|
42
|
-
" ]",
|
|
43
|
-
"}",
|
|
44
|
-
"注意:",
|
|
45
|
-
"1. 一定要保证输出是合法的 JSON,不能包含注释或多余文本;",
|
|
46
|
-
'2. 如果没有任何问题,也请返回 {"comments": []};',
|
|
47
|
-
"3. 请根据 diff 中的路径和行号填写 file 与 line 字段。",
|
|
48
|
-
"",
|
|
49
|
-
"项目规范(摘要):",
|
|
50
|
-
rulesBrief,
|
|
51
|
-
"",
|
|
52
|
-
"下面是 Git diff:",
|
|
53
|
-
diff,
|
|
54
|
-
].join("\n");
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* 解析 AI 返回的 JSON(兼容代码块包裹)
|
|
58
|
-
*/
|
|
59
|
-
const parseAIResponse = (content) => {
|
|
60
|
-
// 兼容 ```json ... ``` 代码块的情况
|
|
61
|
-
const contentText = content
|
|
62
|
-
.replace(/^```(?:json)?\s*/i, "")
|
|
63
|
-
.replace(/```$/i, "")
|
|
64
|
-
.trim();
|
|
65
|
-
try {
|
|
66
|
-
return JSON.parse(contentText);
|
|
67
|
-
}
|
|
68
|
-
catch (parseError) {
|
|
69
|
-
console.error("[reviewer] AI 返回内容 JSON 解析失败");
|
|
70
|
-
console.error("[reviewer] 原始内容:", content);
|
|
71
|
-
console.error(parseError);
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* 执行 AI Code Review
|
|
77
|
-
*/
|
|
78
|
-
const reviewCode = async (diff, config) => {
|
|
79
|
-
// 先根据 ignore 规则过滤掉不需要审查的文件 diff
|
|
80
|
-
const effectiveDiff = (0, utils_1.filterDiffByIgnore)(diff, config.review?.ignore);
|
|
81
|
-
if (!effectiveDiff || !effectiveDiff.trim()) {
|
|
82
|
-
console.error("[reviewer] diff 为空,跳过审查");
|
|
83
|
-
return { comments: [] };
|
|
84
|
-
}
|
|
85
|
-
if (!config.ai.apiKey || !config.ai.endpoint) {
|
|
86
|
-
console.error("[reviewer] 缺少 API 配置");
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
// 获取规则:仅使用通用规则 + 自定义规则(不再支持内置 extends)
|
|
90
|
-
const rules = [...commonRules, ...(config.rules?.custom || [])];
|
|
91
|
-
// 构建 prompt
|
|
92
|
-
const systemPrompt = buildSystemPrompt();
|
|
93
|
-
const userPrompt = buildUserPrompt(effectiveDiff, rules);
|
|
94
|
-
// 创建适配器并调用 AI API
|
|
95
|
-
const adapter = (0, factory_1.createAdapter)(config.ai.endpoint, config.ai.apiKey);
|
|
96
|
-
const rawContent = await adapter.call(config.ai.model, systemPrompt, userPrompt);
|
|
97
|
-
if (!rawContent) {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
// 解析响应
|
|
101
|
-
const result = parseAIResponse(rawContent);
|
|
102
|
-
if (!result) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
// 应用过滤和限制
|
|
106
|
-
let comments = result.comments || [];
|
|
107
|
-
// 过滤 severity
|
|
108
|
-
if (config.review?.severity) {
|
|
109
|
-
const severityOrder = { info: 0, warning: 1, error: 2 };
|
|
110
|
-
const minLevel = severityOrder[config.review.severity];
|
|
111
|
-
comments = comments.filter((c) => severityOrder[c.severity] >= minLevel);
|
|
112
|
-
}
|
|
113
|
-
// 限制评论数量
|
|
114
|
-
if (config.review?.maxComments &&
|
|
115
|
-
comments.length > config.review.maxComments) {
|
|
116
|
-
comments = comments.slice(0, config.review.maxComments);
|
|
117
|
-
console.warn(`[reviewer] 评论数量超过限制,仅保留前 ${config.review.maxComments} 条`);
|
|
118
|
-
}
|
|
119
|
-
return { comments };
|
|
120
|
-
};
|
|
121
|
-
exports.reviewCode = reviewCode;
|
|
122
|
-
//# sourceMappingURL=reviewer.js.map
|
package/dist/reviewer.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../src/reviewer.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 规则库索引
|
|
3
|
-
*/
|
|
4
|
-
export declare const builtinRules: Record<string, string[]>;
|
|
5
|
-
/**
|
|
6
|
-
* 通用代码质量规则
|
|
7
|
-
*/
|
|
8
|
-
export declare const commonRules: string[];
|
|
9
|
-
/**
|
|
10
|
-
* 根据配置获取合并后的规则
|
|
11
|
-
*/
|
|
12
|
-
export declare const getRules: (extends_?: string[], custom?: string[]) => string[];
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAIjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,UAMvB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,WAAU,MAAM,EAAO,EAAE,SAAQ,MAAM,EAAO,KAAG,MAAM,EAmB/E,CAAC"}
|
package/dist/rules/index.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 规则库索引
|
|
4
|
-
*/
|
|
5
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.getRules = exports.commonRules = exports.builtinRules = void 0;
|
|
10
|
-
const react_1 = __importDefault(require("./react"));
|
|
11
|
-
const typescript_1 = __importDefault(require("./typescript"));
|
|
12
|
-
const vue_1 = __importDefault(require("./vue"));
|
|
13
|
-
exports.builtinRules = {
|
|
14
|
-
typescript: typescript_1.default,
|
|
15
|
-
react: react_1.default,
|
|
16
|
-
vue: vue_1.default,
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* 通用代码质量规则
|
|
20
|
-
*/
|
|
21
|
-
exports.commonRules = [
|
|
22
|
-
'重点关注潜在 bug、性能问题、可读性与安全性(如 XSS、注入、敏感信息泄露)',
|
|
23
|
-
'代码要有适当的错误处理',
|
|
24
|
-
'避免代码重复,注意抽离复用逻辑',
|
|
25
|
-
'函数和变量命名要语义化,见名知意',
|
|
26
|
-
'复杂逻辑要添加注释说明',
|
|
27
|
-
];
|
|
28
|
-
/**
|
|
29
|
-
* 根据配置获取合并后的规则
|
|
30
|
-
*/
|
|
31
|
-
const getRules = (extends_ = [], custom = []) => {
|
|
32
|
-
const rules = [...exports.commonRules];
|
|
33
|
-
// 加载内置规则
|
|
34
|
-
for (const ruleName of extends_) {
|
|
35
|
-
const builtinRule = exports.builtinRules[ruleName];
|
|
36
|
-
if (builtinRule) {
|
|
37
|
-
rules.push(...builtinRule);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
console.warn(`[rules] 未找到内置规则: ${ruleName}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// 加载自定义规则
|
|
44
|
-
if (custom.length > 0) {
|
|
45
|
-
rules.push(...custom);
|
|
46
|
-
}
|
|
47
|
-
return rules;
|
|
48
|
-
};
|
|
49
|
-
exports.getRules = getRules;
|
|
50
|
-
//# sourceMappingURL=index.js.map
|
package/dist/rules/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;AAEH,oDAAiC;AACjC,8DAA2C;AAC3C,gDAA6B;AAEhB,QAAA,YAAY,GAA6B;IACpD,UAAU,EAAE,oBAAe;IAC3B,KAAK,EAAE,eAAU;IACjB,GAAG,EAAE,aAAQ;CACd,CAAC;AAEF;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,0CAA0C;IAC1C,aAAa;IACb,iBAAiB;IACjB,kBAAkB;IAClB,aAAa;CACd,CAAC;AAEF;;GAEG;AACI,MAAM,QAAQ,GAAG,CAAC,WAAqB,EAAE,EAAE,SAAmB,EAAE,EAAY,EAAE;IACnF,MAAM,KAAK,GAAa,CAAC,GAAG,mBAAW,CAAC,CAAC;IAEzC,SAAS;IACT,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,oBAAY,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,UAAU;IACV,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAnBW,QAAA,QAAQ,YAmBnB"}
|
package/dist/rules/react.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,UAAU,UAQtB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
package/dist/rules/react.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* React 代码规范规则
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.reactRules = void 0;
|
|
7
|
-
exports.reactRules = [
|
|
8
|
-
'使用函数组件和 Hooks,避免使用 class 组件',
|
|
9
|
-
'组件使用 PascalCase 命名,函数和变量使用 camelCase 命名',
|
|
10
|
-
'合理使用 useMemo 和 useCallback 优化性能,避免过度优化',
|
|
11
|
-
'useEffect 的依赖项数组要完整准确',
|
|
12
|
-
'避免在循环中使用数组索引作为 key',
|
|
13
|
-
'组件职责单一,复杂组件要拆分',
|
|
14
|
-
'Props 要有明确的 TypeScript 类型定义',
|
|
15
|
-
];
|
|
16
|
-
exports.default = exports.reactRules;
|
|
17
|
-
//# sourceMappingURL=react.js.map
|
package/dist/rules/react.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,UAAU,GAAG;IACxB,6BAA6B;IAC7B,yCAAyC;IACzC,wCAAwC;IACxC,uBAAuB;IACvB,oBAAoB;IACpB,gBAAgB;IAChB,6BAA6B;CAC9B,CAAC;AAEF,kBAAe,kBAAU,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/rules/typescript.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,eAAe,UAO3B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
package/dist/rules/typescript.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* TypeScript 代码规范规则
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.typescriptRules = void 0;
|
|
7
|
-
exports.typescriptRules = [
|
|
8
|
-
'使用 TypeScript 进行类型检查,确保代码健壮性',
|
|
9
|
-
'优先使用 interface 而非 type 来定义对象类型',
|
|
10
|
-
'避免使用 any 类型,尽可能使用具体类型或泛型',
|
|
11
|
-
'使用箭头函数声明函数,不要用 function 声明',
|
|
12
|
-
'合理使用可选链操作符(?.)和空值合并操作符(??)',
|
|
13
|
-
'避免使用魔法数字和魔法字符串,定义为常量',
|
|
14
|
-
];
|
|
15
|
-
exports.default = exports.typescriptRules;
|
|
16
|
-
//# sourceMappingURL=typescript.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/rules/typescript.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,eAAe,GAAG;IAC7B,8BAA8B;IAC9B,gCAAgC;IAChC,0BAA0B;IAC1B,4BAA4B;IAC5B,4BAA4B;IAC5B,sBAAsB;CACvB,CAAC;AAEF,kBAAe,uBAAe,CAAC"}
|
package/dist/rules/vue.d.ts
DELETED
package/dist/rules/vue.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/rules/vue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,QAAQ,UAOpB,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/dist/rules/vue.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Vue 代码规范规则
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.vueRules = void 0;
|
|
7
|
-
exports.vueRules = [
|
|
8
|
-
'使用 Composition API (setup) 而非 Options API',
|
|
9
|
-
'组件使用 PascalCase 命名',
|
|
10
|
-
'Props 要有明确的类型定义和默认值',
|
|
11
|
-
'合理使用 computed 和 watch,避免在 template 中写复杂逻辑',
|
|
12
|
-
'避免直接修改 props',
|
|
13
|
-
'组件职责单一,复杂组件要拆分',
|
|
14
|
-
];
|
|
15
|
-
exports.default = exports.vueRules;
|
|
16
|
-
//# sourceMappingURL=vue.js.map
|
package/dist/rules/vue.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../../src/rules/vue.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,QAAQ,GAAG;IACtB,2CAA2C;IAC3C,oBAAoB;IACpB,qBAAqB;IACrB,2CAA2C;IAC3C,cAAc;IACd,gBAAgB;CACjB,CAAC;AAEF,kBAAe,gBAAQ,CAAC"}
|