@wuyanbin/ai-code-review-cli-remote 1.0.3 → 1.0.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/client.d.ts.map +1 -1
- package/dist/client.js +1 -45
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +147 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/diff.d.ts +6 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +127 -0
- package/dist/diff.js.map +1 -0
- package/dist/formatters.d.ts +4 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +30 -0
- package/dist/formatters.js.map +1 -0
- package/dist/gitlab.d.ts +7 -0
- package/dist/gitlab.d.ts.map +1 -0
- package/dist/gitlab.js +55 -0
- package/dist/gitlab.js.map +1 -0
- package/dist/index.js +15 -69
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +5 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +80 -0
- package/dist/model.js.map +1 -0
- package/dist/report.d.ts +9 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +30 -0
- package/dist/report.js.map +1 -0
- package/dist/reviewer.d.ts +3 -0
- package/dist/reviewer.d.ts.map +1 -0
- package/dist/reviewer.js +77 -0
- package/dist/reviewer.js.map +1 -0
- package/dist/runner.d.ts +5 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +102 -0
- package/dist/runner.js.map +1 -0
- package/dist/summarizer.d.ts +3 -0
- package/dist/summarizer.d.ts.map +1 -0
- package/dist/summarizer.js +75 -0
- package/dist/summarizer.js.map +1 -0
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -2
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,aAAa,CAAC,CA0CxB;AAED,wBAAgB,yBAAyB,CACvC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAER"}
|
package/dist/client.js
CHANGED
|
@@ -10,21 +10,6 @@ function getPlatformUrlFromEnv(env = process.env) {
|
|
|
10
10
|
}
|
|
11
11
|
return platformUrl;
|
|
12
12
|
}
|
|
13
|
-
function isLoopbackHost(hostname) {
|
|
14
|
-
return (hostname === "localhost" ||
|
|
15
|
-
hostname === "127.0.0.1" ||
|
|
16
|
-
hostname === "::1" ||
|
|
17
|
-
hostname === "[::1]" ||
|
|
18
|
-
hostname === "0.0.0.0");
|
|
19
|
-
}
|
|
20
|
-
function isLoopbackUrl(url) {
|
|
21
|
-
try {
|
|
22
|
-
return isLoopbackHost(new URL(url).hostname);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
13
|
function getProjectToken() {
|
|
29
14
|
const token = process.env[constants_1.ENV_PROJECT_TOKEN];
|
|
30
15
|
if (!token) {
|
|
@@ -32,26 +17,9 @@ function getProjectToken() {
|
|
|
32
17
|
}
|
|
33
18
|
return token;
|
|
34
19
|
}
|
|
35
|
-
function hasErrorCode(error, code) {
|
|
36
|
-
if (!error || typeof error !== "object")
|
|
37
|
-
return false;
|
|
38
|
-
const err = error;
|
|
39
|
-
if (err.code === code)
|
|
40
|
-
return true;
|
|
41
|
-
if (err.cause && hasErrorCode(err.cause, code))
|
|
42
|
-
return true;
|
|
43
|
-
if (Array.isArray(err.errors)) {
|
|
44
|
-
for (const sub of err.errors) {
|
|
45
|
-
if (hasErrorCode(sub, code))
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
20
|
async function analyzeWithCi(diff, ci) {
|
|
52
21
|
const token = getProjectToken();
|
|
53
|
-
const
|
|
54
|
-
const url = `${platformUrl}${constants_1.API_REVIEW_PATH}`;
|
|
22
|
+
const url = `${getPlatformUrlFromEnv()}${constants_1.API_REVIEW_PATH}`;
|
|
55
23
|
console.error(`[remote] POST ${url} (mrIid=${ci.mrIid})`);
|
|
56
24
|
const controller = new AbortController();
|
|
57
25
|
const timeout = setTimeout(() => controller.abort(), constants_1.REQUEST_TIMEOUT_MS);
|
|
@@ -82,18 +50,6 @@ async function analyzeWithCi(diff, ci) {
|
|
|
82
50
|
if (error instanceof Error && error.name === "AbortError") {
|
|
83
51
|
throw new Error(`平台请求超时(${constants_1.REQUEST_TIMEOUT_MS / 1000}s),请检查 ${constants_1.ENV_PLATFORM_URL} 是否正确或平台是否可用`);
|
|
84
52
|
}
|
|
85
|
-
if (isLoopbackUrl(platformUrl) && hasErrorCode(error, "ECONNREFUSED")) {
|
|
86
|
-
throw new Error(`${constants_1.ENV_PLATFORM_URL}=${platformUrl} 指向了 loopback 地址,Runner 内访问的是自己而不是平台,所以连不上。\n` +
|
|
87
|
-
`请在平台服务器 .env 中把 MICO_PLATFORM_URL 改成 Runner 可达的地址(内网 IP 或域名),重启 platform 容器,` +
|
|
88
|
-
`然后在管理台打开该项目 → 接入状态 → 点击"修复配置",即可把新的地址同步到 GitLab CI 变量。`);
|
|
89
|
-
}
|
|
90
|
-
if (hasErrorCode(error, "ECONNREFUSED")) {
|
|
91
|
-
throw new Error(`无法连接到平台 ${platformUrl}(ECONNREFUSED)。` +
|
|
92
|
-
`请确认平台服务在该地址上已启动并对外暴露端口,且 Runner 所在网络可访问该地址。`);
|
|
93
|
-
}
|
|
94
|
-
if (hasErrorCode(error, "UND_ERR_CONNECT_TIMEOUT")) {
|
|
95
|
-
throw new Error(`连接平台 ${platformUrl} 超时。请确认 Runner 所在网络能访问该地址,防火墙/安全组已放行对应端口。`);
|
|
96
|
-
}
|
|
97
53
|
throw error;
|
|
98
54
|
}
|
|
99
55
|
finally {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;AA4CA,sCA6CC;AAED,8DAIC;AA/FD,2CAKqB;AAmBrB,SAAS,qBAAqB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,MAAM,WAAW,GAAG,GAAG,CAAC,4BAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,GAAG,4BAAgB,8BAA8B,CAClD,CAAC;IACJ,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,6BAAiB,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,GAAG,6BAAiB,oCAAoC,CACzD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,EAAa;IAEb,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,GAAG,qBAAqB,EAAE,GAAG,2BAAe,EAAE,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG,WAAW,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,8BAAkB,CAAC,CAAC;IAEzE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YAClC,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,IAAmB,CAAC;QACxB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CACb,UAAU,8BAAkB,GAAG,IAAI,UAAU,4BAAgB,cAAc,CAC5E,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAgB,yBAAyB,CACvC,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CodeReviewConfig } from "./types";
|
|
2
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
export interface LoadReviewConfigOptions {
|
|
4
|
+
cwd?: string;
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
fetchImpl?: FetchLike;
|
|
7
|
+
}
|
|
8
|
+
export declare function loadReviewConfig(options?: LoadReviewConfigOptions): Promise<CodeReviewConfig>;
|
|
9
|
+
export declare function sanitizeConfigForLog(config: CodeReviewConfig): CodeReviewConfig;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAY,MAAM,SAAS,CAAC;AAE1D,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE1E,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAoJD,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAM/E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadReviewConfig = loadReviewConfig;
|
|
4
|
+
exports.sanitizeConfigForLog = sanitizeConfigForLog;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const node_module_1 = require("node:module");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
const LOCAL_CONFIG_FILES = [
|
|
11
|
+
".aicr.config.js",
|
|
12
|
+
"aicr.config.js",
|
|
13
|
+
".aicr.config.cjs",
|
|
14
|
+
"aicr.config.cjs",
|
|
15
|
+
];
|
|
16
|
+
const requireConfig = (0, node_module_1.createRequire)(__filename);
|
|
17
|
+
function normalizePlatformUrl(env) {
|
|
18
|
+
const raw = env[constants_1.ENV_PLATFORM_URL]?.replace(/\/+$/, "");
|
|
19
|
+
return raw || null;
|
|
20
|
+
}
|
|
21
|
+
function asStringArray(value) {
|
|
22
|
+
return Array.isArray(value)
|
|
23
|
+
? value.filter((item) => typeof item === "string")
|
|
24
|
+
: [];
|
|
25
|
+
}
|
|
26
|
+
function normalizeSeverity(value) {
|
|
27
|
+
return value === "info" || value === "warning" || value === "error"
|
|
28
|
+
? value
|
|
29
|
+
: "warning";
|
|
30
|
+
}
|
|
31
|
+
function normalizeMaxComments(value) {
|
|
32
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0
|
|
33
|
+
? Math.floor(value)
|
|
34
|
+
: 100;
|
|
35
|
+
}
|
|
36
|
+
function normalizeConfig(raw, source, env) {
|
|
37
|
+
return {
|
|
38
|
+
source,
|
|
39
|
+
ai: {
|
|
40
|
+
name: raw.ai?.name,
|
|
41
|
+
provider: raw.ai?.provider,
|
|
42
|
+
model: raw.ai?.model || "deepseek-chat",
|
|
43
|
+
endpoint: raw.ai?.endpoint || "https://api.deepseek.com/chat/completions",
|
|
44
|
+
apiKey: env.MODEL_API_KEY || raw.ai?.apiKey || "",
|
|
45
|
+
},
|
|
46
|
+
rules: {
|
|
47
|
+
custom: asStringArray(raw.rules?.custom),
|
|
48
|
+
},
|
|
49
|
+
review: {
|
|
50
|
+
severity: normalizeSeverity(raw.review?.severity),
|
|
51
|
+
ignore: asStringArray(raw.review?.ignore),
|
|
52
|
+
maxComments: normalizeMaxComments(raw.review?.maxComments),
|
|
53
|
+
},
|
|
54
|
+
summary: {
|
|
55
|
+
enabled: raw.summary?.enabled ?? true,
|
|
56
|
+
},
|
|
57
|
+
gitlab: raw.gitlab?.token ? { token: raw.gitlab.token } : undefined,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async function loadDevhubConfig(env, fetchImpl) {
|
|
61
|
+
const platformUrl = normalizePlatformUrl(env);
|
|
62
|
+
const token = env[constants_1.ENV_PROJECT_TOKEN];
|
|
63
|
+
if (!platformUrl || !token)
|
|
64
|
+
return null;
|
|
65
|
+
const url = `${platformUrl}${constants_1.API_CONFIG_PATH}`;
|
|
66
|
+
try {
|
|
67
|
+
console.error("[config] fetching Devhub config");
|
|
68
|
+
const resp = await fetchImpl(url, {
|
|
69
|
+
method: "GET",
|
|
70
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
71
|
+
});
|
|
72
|
+
if (!resp.ok) {
|
|
73
|
+
console.error(`[config] Devhub 配置获取失败 status=${resp.status}`);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const raw = (await resp.json());
|
|
77
|
+
const config = normalizeConfig(raw, "devhub", {});
|
|
78
|
+
if (!config.ai.apiKey || !config.ai.endpoint) {
|
|
79
|
+
console.error("[config] Devhub 配置缺少模型密钥或 endpoint,回退本地配置");
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return config;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error("[config] Devhub 配置获取异常,回退本地配置:", error instanceof Error ? error.message : String(error));
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function loadCachedConfig(env) {
|
|
90
|
+
const cachePath = env.AICR_CONFIG_CACHE;
|
|
91
|
+
if (!cachePath || !(0, node_fs_1.existsSync)(cachePath))
|
|
92
|
+
return null;
|
|
93
|
+
try {
|
|
94
|
+
const raw = JSON.parse(await (0, promises_1.readFile)(cachePath, "utf8"));
|
|
95
|
+
if (raw.source === "devhub" && raw.ai?.apiKey && raw.ai?.endpoint) {
|
|
96
|
+
console.error("[config] Loaded config from Devhub cache");
|
|
97
|
+
return raw;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error("[config] Devhub 配置缓存读取失败:", error instanceof Error ? error.message : String(error));
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
async function writeCachedConfig(env, config) {
|
|
106
|
+
const cachePath = env.AICR_CONFIG_CACHE;
|
|
107
|
+
if (!cachePath || config.source !== "devhub")
|
|
108
|
+
return;
|
|
109
|
+
await (0, promises_1.writeFile)(cachePath, JSON.stringify(config), { mode: 0o600 });
|
|
110
|
+
console.error("[config] Devhub config cached");
|
|
111
|
+
}
|
|
112
|
+
async function loadLocalConfig(cwd, env) {
|
|
113
|
+
for (const filename of LOCAL_CONFIG_FILES) {
|
|
114
|
+
const file = (0, node_path_1.resolve)(cwd, filename);
|
|
115
|
+
if (!(0, node_fs_1.existsSync)(file))
|
|
116
|
+
continue;
|
|
117
|
+
delete requireConfig.cache[requireConfig.resolve(file)];
|
|
118
|
+
const imported = requireConfig(file);
|
|
119
|
+
const raw = imported.default ?? imported;
|
|
120
|
+
console.error(`[config] Loaded local config from: ${file}`);
|
|
121
|
+
return normalizeConfig(raw, "local", env);
|
|
122
|
+
}
|
|
123
|
+
console.error("[config] No local config file found, using defaults.");
|
|
124
|
+
return normalizeConfig({}, "local", env);
|
|
125
|
+
}
|
|
126
|
+
async function loadReviewConfig(options = {}) {
|
|
127
|
+
const env = options.env ?? process.env;
|
|
128
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
129
|
+
const cached = await loadCachedConfig(env);
|
|
130
|
+
if (cached)
|
|
131
|
+
return cached;
|
|
132
|
+
const devhubConfig = await loadDevhubConfig(env, fetchImpl);
|
|
133
|
+
if (devhubConfig) {
|
|
134
|
+
await writeCachedConfig(env, devhubConfig);
|
|
135
|
+
console.error("[config] Loaded config from Devhub");
|
|
136
|
+
return devhubConfig;
|
|
137
|
+
}
|
|
138
|
+
return loadLocalConfig(options.cwd ?? process.cwd(), env);
|
|
139
|
+
}
|
|
140
|
+
function sanitizeConfigForLog(config) {
|
|
141
|
+
return {
|
|
142
|
+
...config,
|
|
143
|
+
ai: { ...config.ai, apiKey: config.ai.apiKey ? "***" : "" },
|
|
144
|
+
gitlab: config.gitlab?.token ? { token: "***" } : config.gitlab,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAiKA,4CAcC;AAED,oDAMC;AAvLD,qCAAqC;AACrC,+CAAuD;AACvD,yCAAoC;AACpC,6CAA4C;AAC5C,2CAAmF;AAWnF,MAAM,kBAAkB,GAAG;IACzB,iBAAiB;IACjB,gBAAgB;IAChB,kBAAkB;IAClB,iBAAiB;CAClB,CAAC;AACF,MAAM,aAAa,GAAG,IAAA,2BAAa,EAAC,UAAU,CAAC,CAAC;AAEhD,SAAS,oBAAoB,CAAC,GAAsB;IAClD,MAAM,GAAG,GAAG,GAAG,CAAC,4BAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;QAClE,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO;QACjE,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QACrE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACnB,CAAC,CAAC,GAAG,CAAC;AACV,CAAC;AAED,SAAS,eAAe,CACtB,GAA8B,EAC9B,MAA0B,EAC1B,GAAsB;IAEtB,OAAO;QACL,MAAM;QACN,EAAE,EAAE;YACF,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI;YAClB,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ;YAC1B,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,IAAI,eAAe;YACvC,QAAQ,EACN,GAAG,CAAC,EAAE,EAAE,QAAQ,IAAI,2CAA2C;YACjE,MAAM,EAAE,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE;SAClD;QACD,KAAK,EAAE;YACL,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;SACzC;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;YACjD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;YACzC,WAAW,EAAE,oBAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;SAC3D;QACD,OAAO,EAAE;YACP,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI;SACtC;QACD,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;KACpE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,GAAsB,EACtB,SAAoB;IAEpB,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,6BAAiB,CAAC,CAAC;IACrC,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,GAAG,GAAG,GAAG,WAAW,GAAG,2BAAe,EAAE,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;SAC9C,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA8B,CAAC;QAC7D,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC3D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,gCAAgC,EAChC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,GAAsB;IAEtB,MAAM,SAAS,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACxC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAA,oBAAU,EAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAA,mBAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,CAAqB,CAAC;QAC9E,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;YAClE,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,2BAA2B,EAC3B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAsB,EACtB,MAAwB;IAExB,MAAM,SAAS,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACxC,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO;IACrD,MAAM,IAAA,oBAAS,EAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,GAAW,EACX,GAAsB;IAEtB,KAAK,MAAM,QAAQ,IAAI,kBAAkB,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAA,mBAAO,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAI,CAAC;YAAE,SAAS;QAChC,OAAO,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAEN,CAAC;QAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACtE,OAAO,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,UAAmC,EAAE;IAErC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5D,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,iBAAiB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,oBAAoB,CAAC,MAAwB;IAC3D,OAAO;QACL,GAAG,MAAM;QACT,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;KAChE,CAAC;AACJ,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -3,4 +3,6 @@ export declare const REQUEST_TIMEOUT_MS = 120000;
|
|
|
3
3
|
export declare const ENV_PLATFORM_URL = "AICR_PLATFORM_URL";
|
|
4
4
|
export declare const ENV_PROJECT_TOKEN = "AICR_PROJECT_TOKEN";
|
|
5
5
|
export declare const API_REVIEW_PATH = "/api/modules/code-review/analyze";
|
|
6
|
+
export declare const API_CONFIG_PATH = "/api/modules/code-review/ci/config";
|
|
7
|
+
export declare const API_RUNS_PATH = "/api/modules/code-review/ci/runs";
|
|
6
8
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAE1C,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AACpD,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAEtD,eAAO,MAAM,eAAe,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAE1C,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AACpD,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAEtD,eAAO,MAAM,eAAe,qCAAqC,CAAC;AAClE,eAAO,MAAM,eAAe,uCAAuC,CAAC;AACpE,eAAO,MAAM,aAAa,qCAAqC,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.API_REVIEW_PATH = exports.ENV_PROJECT_TOKEN = exports.ENV_PLATFORM_URL = exports.REQUEST_TIMEOUT_MS = exports.TOOL_NAME = void 0;
|
|
3
|
+
exports.API_RUNS_PATH = exports.API_CONFIG_PATH = exports.API_REVIEW_PATH = exports.ENV_PROJECT_TOKEN = exports.ENV_PLATFORM_URL = exports.REQUEST_TIMEOUT_MS = exports.TOOL_NAME = void 0;
|
|
4
4
|
exports.TOOL_NAME = "ai-code-review";
|
|
5
5
|
exports.REQUEST_TIMEOUT_MS = 120000;
|
|
6
6
|
exports.ENV_PLATFORM_URL = "AICR_PLATFORM_URL";
|
|
7
7
|
exports.ENV_PROJECT_TOKEN = "AICR_PROJECT_TOKEN";
|
|
8
8
|
exports.API_REVIEW_PATH = "/api/modules/code-review/analyze";
|
|
9
|
+
exports.API_CONFIG_PATH = "/api/modules/code-review/ci/config";
|
|
10
|
+
exports.API_RUNS_PATH = "/api/modules/code-review/ci/runs";
|
|
9
11
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,gBAAgB,CAAC;AAC7B,QAAA,kBAAkB,GAAG,MAAO,CAAC;AAE7B,QAAA,gBAAgB,GAAG,mBAAmB,CAAC;AACvC,QAAA,iBAAiB,GAAG,oBAAoB,CAAC;AAEzC,QAAA,eAAe,GAAG,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,gBAAgB,CAAC;AAC7B,QAAA,kBAAkB,GAAG,MAAO,CAAC;AAE7B,QAAA,gBAAgB,GAAG,mBAAmB,CAAC;AACvC,QAAA,iBAAiB,GAAG,oBAAoB,CAAC;AAEzC,QAAA,eAAe,GAAG,kCAAkC,CAAC;AACrD,QAAA,eAAe,GAAG,oCAAoC,CAAC;AACvD,QAAA,aAAa,GAAG,kCAAkC,CAAC"}
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AIComment } from "./types";
|
|
2
|
+
export declare function globToRegExp(pattern: string): RegExp;
|
|
3
|
+
export declare function filterDiffByIgnore(diff: string, ignorePatterns?: string[]): string;
|
|
4
|
+
export declare function buildAddedLinesIndexText(diff: string, maxLines?: number): string;
|
|
5
|
+
export declare function alignCommentsToDiffAddedLines(diff: string, comments: AIComment[]): AIComment[];
|
|
6
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgBpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBlF;AA4DD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAO,GAAG,MAAM,CAU9E;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,EAAE,GACpB,SAAS,EAAE,CAqBb"}
|
package/dist/diff.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.globToRegExp = globToRegExp;
|
|
4
|
+
exports.filterDiffByIgnore = filterDiffByIgnore;
|
|
5
|
+
exports.buildAddedLinesIndexText = buildAddedLinesIndexText;
|
|
6
|
+
exports.alignCommentsToDiffAddedLines = alignCommentsToDiffAddedLines;
|
|
7
|
+
function globToRegExp(pattern) {
|
|
8
|
+
if (pattern.endsWith("/**")) {
|
|
9
|
+
const prefix = pattern.slice(0, -3).replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
10
|
+
return new RegExp(`^${prefix}/.*$`);
|
|
11
|
+
}
|
|
12
|
+
if (pattern.startsWith("**/")) {
|
|
13
|
+
const rest = pattern
|
|
14
|
+
.slice(3)
|
|
15
|
+
.replace(/[.+?^${}()|[\]\\]/g, "\\$&")
|
|
16
|
+
.replace(/\*/g, "[^/]*");
|
|
17
|
+
return new RegExp(`^(?:.*/)?${rest}$`);
|
|
18
|
+
}
|
|
19
|
+
const escaped = pattern
|
|
20
|
+
.replace(/[.+?^${}()|[\]\\]/g, "\\$&")
|
|
21
|
+
.replace(/\*/g, "[^/]*");
|
|
22
|
+
return new RegExp(`^${escaped}$`);
|
|
23
|
+
}
|
|
24
|
+
function filterDiffByIgnore(diff, ignorePatterns) {
|
|
25
|
+
if (!ignorePatterns?.length || !diff.trim())
|
|
26
|
+
return diff;
|
|
27
|
+
const lines = diff.split("\n");
|
|
28
|
+
const kept = [];
|
|
29
|
+
let ignoreCurrent = false;
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
if (line.startsWith("diff --git ")) {
|
|
32
|
+
ignoreCurrent = false;
|
|
33
|
+
const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
|
|
34
|
+
if (match) {
|
|
35
|
+
ignoreCurrent = ignorePatterns.some((pattern) => globToRegExp(pattern).test(match[2]));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!ignoreCurrent)
|
|
39
|
+
kept.push(line);
|
|
40
|
+
}
|
|
41
|
+
return kept.join("\n");
|
|
42
|
+
}
|
|
43
|
+
function normalizePath(path) {
|
|
44
|
+
return path.trim().replace(/^[ab]\//, "").replace(/^\.\//, "");
|
|
45
|
+
}
|
|
46
|
+
function collectAddedLines(diff) {
|
|
47
|
+
const files = new Map();
|
|
48
|
+
let currentFile = null;
|
|
49
|
+
let inHunk = false;
|
|
50
|
+
let newLine = 0;
|
|
51
|
+
let oldLine = 0;
|
|
52
|
+
for (const raw of diff.split("\n")) {
|
|
53
|
+
if (raw.startsWith("diff --git ")) {
|
|
54
|
+
inHunk = false;
|
|
55
|
+
currentFile = null;
|
|
56
|
+
const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(raw);
|
|
57
|
+
if (match) {
|
|
58
|
+
currentFile = normalizePath(match[2]);
|
|
59
|
+
files.set(currentFile, files.get(currentFile) ?? []);
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (raw.startsWith("+++ b/")) {
|
|
64
|
+
currentFile = normalizePath(raw.slice("+++ b/".length));
|
|
65
|
+
files.set(currentFile, files.get(currentFile) ?? []);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (raw.startsWith("@@")) {
|
|
69
|
+
const match = /^@@\s+\-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/.exec(raw);
|
|
70
|
+
inHunk = !!match;
|
|
71
|
+
oldLine = Number(match?.[1] ?? 0);
|
|
72
|
+
newLine = Number(match?.[2] ?? 0);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!inHunk || !currentFile)
|
|
76
|
+
continue;
|
|
77
|
+
if (raw.startsWith("+") && !raw.startsWith("+++")) {
|
|
78
|
+
files.get(currentFile)?.push({
|
|
79
|
+
file: currentFile,
|
|
80
|
+
line: newLine,
|
|
81
|
+
content: raw.slice(1),
|
|
82
|
+
});
|
|
83
|
+
newLine += 1;
|
|
84
|
+
}
|
|
85
|
+
else if (raw.startsWith("-") && !raw.startsWith("---")) {
|
|
86
|
+
oldLine += 1;
|
|
87
|
+
}
|
|
88
|
+
else if (raw.startsWith(" ")) {
|
|
89
|
+
oldLine += 1;
|
|
90
|
+
newLine += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return files;
|
|
94
|
+
}
|
|
95
|
+
function buildAddedLinesIndexText(diff, maxLines = 5000) {
|
|
96
|
+
const rows = [];
|
|
97
|
+
for (const [file, lines] of collectAddedLines(diff)) {
|
|
98
|
+
for (const item of lines) {
|
|
99
|
+
if (rows.length >= maxLines)
|
|
100
|
+
break;
|
|
101
|
+
rows.push(`[${file}:${item.line}] ${item.content}`);
|
|
102
|
+
}
|
|
103
|
+
if (rows.length >= maxLines)
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
return rows.length ? rows.join("\n") : "(diff 中未检测到可评论的新增行)";
|
|
107
|
+
}
|
|
108
|
+
function alignCommentsToDiffAddedLines(diff, comments) {
|
|
109
|
+
const added = collectAddedLines(diff);
|
|
110
|
+
return comments.flatMap((comment) => {
|
|
111
|
+
const file = normalizePath(comment.file);
|
|
112
|
+
const candidates = added.get(file);
|
|
113
|
+
if (!candidates?.length)
|
|
114
|
+
return [];
|
|
115
|
+
const exact = candidates.find((item) => item.line === comment.line);
|
|
116
|
+
const byCode = typeof comment.code === "string"
|
|
117
|
+
? candidates.find((item) => item.content.trim() === comment.code?.trim())
|
|
118
|
+
: undefined;
|
|
119
|
+
const chosen = exact ??
|
|
120
|
+
byCode ??
|
|
121
|
+
candidates.reduce((best, item) => Math.abs(item.line - comment.line) < Math.abs(best.line - comment.line)
|
|
122
|
+
? item
|
|
123
|
+
: best);
|
|
124
|
+
return [{ ...comment, file, line: chosen.line }];
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=diff.js.map
|
package/dist/diff.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AAQjE,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,CAgB/D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildEmptyRdjson = buildEmptyRdjson;
|
|
4
|
+
exports.buildRdjson = buildRdjson;
|
|
5
|
+
function toRdjsonSeverity(severity) {
|
|
6
|
+
if (severity === "error")
|
|
7
|
+
return "ERROR";
|
|
8
|
+
if (severity === "info")
|
|
9
|
+
return "INFO";
|
|
10
|
+
return "WARNING";
|
|
11
|
+
}
|
|
12
|
+
function buildEmptyRdjson() {
|
|
13
|
+
return { source: { name: "ai_code_review" }, diagnostics: [] };
|
|
14
|
+
}
|
|
15
|
+
function buildRdjson(comments) {
|
|
16
|
+
return {
|
|
17
|
+
source: { name: "ai_code_review" },
|
|
18
|
+
diagnostics: comments
|
|
19
|
+
.filter((comment) => comment.file && comment.line)
|
|
20
|
+
.map((comment) => ({
|
|
21
|
+
message: `${comment.message || "AI Code Review 提示"}${comment.suggestion ? `\n建议:${comment.suggestion}` : ""}`,
|
|
22
|
+
location: {
|
|
23
|
+
path: comment.file,
|
|
24
|
+
range: { start: { line: Number(comment.line) || 1, column: 1 } },
|
|
25
|
+
},
|
|
26
|
+
severity: toRdjsonSeverity(comment.severity),
|
|
27
|
+
})),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":";;AAQA,4CAEC;AAED,kCAgBC;AA1BD,SAAS,gBAAgB,CAAC,QAAkB;IAC1C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACvC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;AACjE,CAAC;AAED,SAAgB,WAAW,CAAC,QAAqB;IAC/C,OAAO;QACL,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;QAClC,WAAW,EAAE,QAAQ;aAClB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;aACjD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACjB,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,GAChD,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EACtD,EAAE;YACF,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;aACjE;YACD,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC;SAC7C,CAAC,CAAC;KACN,CAAC;AACJ,CAAC"}
|
package/dist/gitlab.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab.d.ts","sourceRoot":"","sources":["../src/gitlab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA8BzC,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CnB"}
|
package/dist/gitlab.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postGitlabDiagnosticsNote = postGitlabDiagnosticsNote;
|
|
4
|
+
function directCommentEnabled(env) {
|
|
5
|
+
return env.AICR_DIRECT_GITLAB_COMMENT !== "false";
|
|
6
|
+
}
|
|
7
|
+
function formatDiagnosticsNote(comments) {
|
|
8
|
+
const lines = [
|
|
9
|
+
"## AI Code Review",
|
|
10
|
+
"",
|
|
11
|
+
`发现 ${comments.length} 条审查意见:`,
|
|
12
|
+
"",
|
|
13
|
+
];
|
|
14
|
+
for (const comment of comments) {
|
|
15
|
+
lines.push(`- **${comment.file}:${comment.line}** [${comment.severity}] ${comment.message}${comment.suggestion ? `\n 建议:${comment.suggestion}` : ""}`);
|
|
16
|
+
}
|
|
17
|
+
return lines.join("\n");
|
|
18
|
+
}
|
|
19
|
+
async function postGitlabDiagnosticsNote(options) {
|
|
20
|
+
const env = options.env ?? process.env;
|
|
21
|
+
if (!directCommentEnabled(env)) {
|
|
22
|
+
console.error("[gitlab] direct MR note skipped: disabled");
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (options.comments.length === 0) {
|
|
26
|
+
console.error("[gitlab] direct MR note skipped: no diagnostics");
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (!options.token ||
|
|
30
|
+
!env.CI_API_V4_URL ||
|
|
31
|
+
!env.CI_PROJECT_ID ||
|
|
32
|
+
!env.CI_MERGE_REQUEST_IID) {
|
|
33
|
+
console.error("[gitlab] direct MR note skipped: missing GitLab CI context");
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const projectId = encodeURIComponent(env.CI_PROJECT_ID);
|
|
37
|
+
const mrIid = encodeURIComponent(env.CI_MERGE_REQUEST_IID);
|
|
38
|
+
const url = `${env.CI_API_V4_URL.replace(/\/+$/, "")}/projects/${projectId}/merge_requests/${mrIid}/notes`;
|
|
39
|
+
console.error(`[gitlab] posting direct MR note comments=${options.comments.length}`);
|
|
40
|
+
const resp = await fetch(url, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
Authorization: `Bearer ${options.token}`,
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({ body: formatDiagnosticsNote(options.comments) }),
|
|
47
|
+
});
|
|
48
|
+
if (!resp.ok) {
|
|
49
|
+
console.error(`[gitlab] direct MR note failed status=${resp.status}`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
console.error("[gitlab] direct MR note posted");
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=gitlab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../src/gitlab.ts"],"names":[],"mappings":";;AA8BA,8DA8CC;AAnED,SAAS,oBAAoB,CAAC,GAAgB;IAC5C,OAAO,GAAG,CAAC,0BAA0B,KAAK,OAAO,CAAC;AACpD,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAqB;IAClD,MAAM,KAAK,GAAG;QACZ,mBAAmB;QACnB,EAAE;QACF,MAAM,QAAQ,CAAC,MAAM,SAAS;QAC9B,EAAE;KACH,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CACR,OAAO,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,OAAO,GAC5E,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EACxD,EAAE,CACH,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,yBAAyB,CAAC,OAI/C;IACC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,CAAC,OAAO,CAAC,KAAK;QACd,CAAC,GAAG,CAAC,aAAa;QAClB,CAAC,GAAG,CAAC,aAAa;QAClB,CAAC,GAAG,CAAC,oBAAoB,EACzB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CACtC,MAAM,EACN,EAAE,CACH,aAAa,SAAS,mBAAmB,KAAK,QAAQ,CAAC;IAExD,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;SACzC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;KACxE,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yCAAyC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC"}
|