@wuyanbin/ai-code-review-cli-remote 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/core/context.d.ts +6 -0
  2. package/dist/core/context.d.ts.map +1 -0
  3. package/dist/core/context.js +154 -0
  4. package/dist/core/context.js.map +1 -0
  5. package/dist/core/diff.d.ts +14 -0
  6. package/dist/core/diff.d.ts.map +1 -0
  7. package/dist/core/diff.js +179 -0
  8. package/dist/core/diff.js.map +1 -0
  9. package/dist/core/model.d.ts +6 -0
  10. package/dist/core/model.d.ts.map +1 -0
  11. package/dist/core/model.js +120 -0
  12. package/dist/core/model.js.map +1 -0
  13. package/dist/core/output.d.ts +4 -0
  14. package/dist/core/output.d.ts.map +1 -0
  15. package/dist/core/output.js +31 -0
  16. package/dist/core/output.js.map +1 -0
  17. package/dist/core/prompt.d.ts +17 -0
  18. package/dist/core/prompt.d.ts.map +1 -0
  19. package/dist/core/prompt.js +92 -0
  20. package/dist/core/prompt.js.map +1 -0
  21. package/dist/core/reviewer.d.ts +6 -0
  22. package/dist/core/reviewer.d.ts.map +1 -0
  23. package/dist/core/reviewer.js +123 -0
  24. package/dist/core/reviewer.js.map +1 -0
  25. package/dist/core/summarizer.d.ts +3 -0
  26. package/dist/core/summarizer.d.ts.map +1 -0
  27. package/dist/core/summarizer.js +48 -0
  28. package/dist/core/summarizer.js.map +1 -0
  29. package/dist/gitlab/api.d.ts +13 -0
  30. package/dist/gitlab/api.d.ts.map +1 -0
  31. package/dist/gitlab/api.js +317 -0
  32. package/dist/gitlab/api.js.map +1 -0
  33. package/dist/gitlab.d.ts.map +1 -1
  34. package/dist/gitlab.js +25 -21
  35. package/dist/gitlab.js.map +1 -1
  36. package/dist/http.d.ts +1 -0
  37. package/dist/http.d.ts.map +1 -1
  38. package/dist/http.js +13 -0
  39. package/dist/http.js.map +1 -1
  40. package/dist/platform/config.d.ts +10 -0
  41. package/dist/platform/config.d.ts.map +1 -0
  42. package/dist/platform/config.js +156 -0
  43. package/dist/platform/config.js.map +1 -0
  44. package/dist/platform/report.d.ts +9 -0
  45. package/dist/platform/report.d.ts.map +1 -0
  46. package/dist/platform/report.js +32 -0
  47. package/dist/platform/report.js.map +1 -0
  48. package/dist/shared/http.d.ts +3 -0
  49. package/dist/shared/http.d.ts.map +1 -0
  50. package/dist/shared/http.js +18 -0
  51. package/dist/shared/http.js.map +1 -0
  52. package/dist/shared/identity.d.ts +18 -0
  53. package/dist/shared/identity.d.ts.map +1 -0
  54. package/dist/shared/identity.js +51 -0
  55. package/dist/shared/identity.js.map +1 -0
  56. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ export interface ReviewContextOptions {
2
+ cwd?: string;
3
+ env?: NodeJS.ProcessEnv;
4
+ }
5
+ export declare function collectReviewContext(diff: string, options?: ReviewContextOptions): Promise<string>;
6
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAsID,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAUjB"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectReviewContext = collectReviewContext;
4
+ const node_fs_1 = require("node:fs");
5
+ const promises_1 = require("node:fs/promises");
6
+ const node_path_1 = require("node:path");
7
+ const diff_1 = require("./diff");
8
+ const RULE_FILES = [
9
+ "CONTRIBUTING.md",
10
+ "README.md",
11
+ ".aicr.rules.md",
12
+ ".cursor/rules",
13
+ ".cursor/rules.md",
14
+ "docs/architecture.md",
15
+ ];
16
+ const MAX_RULE_BYTES = 16000;
17
+ const MAX_SOURCE_BYTES = 36000;
18
+ const SOURCE_WINDOW_RADIUS = 12;
19
+ const MAX_CONTEXT_FILES = 8;
20
+ function truncateByBytes(value, maxBytes) {
21
+ if (Buffer.byteLength(value) <= maxBytes)
22
+ return value;
23
+ const buf = Buffer.from(value);
24
+ const truncated = buf.subarray(0, maxBytes).toString("utf8");
25
+ const safeEnd = truncated.lastIndexOf("\n");
26
+ const result = safeEnd > 0 ? truncated.slice(0, safeEnd) : truncated;
27
+ return `${result}\n...(已截断)`;
28
+ }
29
+ function buildMrContext(env) {
30
+ const rows = [
31
+ ["MR 标题", env.CI_MERGE_REQUEST_TITLE],
32
+ ["MR 描述", env.CI_MERGE_REQUEST_DESCRIPTION],
33
+ ["MR 标签", env.CI_MERGE_REQUEST_LABELS],
34
+ ["源分支", env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME],
35
+ ["目标分支", env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME],
36
+ ["提交 SHA", env.CI_COMMIT_SHA],
37
+ ].filter(([, value]) => value && String(value).trim());
38
+ if (rows.length === 0)
39
+ return [];
40
+ return [
41
+ "## MR 元信息",
42
+ ...rows.map(([label, value]) => `- ${label}: ${String(value).trim()}`),
43
+ ];
44
+ }
45
+ function expandRulePaths(cwd) {
46
+ const results = [];
47
+ for (const file of RULE_FILES) {
48
+ const full = (0, node_path_1.resolve)(cwd, file);
49
+ if (!(0, node_fs_1.existsSync)(full))
50
+ continue;
51
+ try {
52
+ const info = (0, node_fs_1.statSync)(full);
53
+ if (info.isDirectory()) {
54
+ const entries = (0, node_fs_1.readdirSync)(full).filter((e) => e.endsWith(".md"));
55
+ for (const entry of entries.slice(0, 5)) {
56
+ results.push({
57
+ label: `${file}/${entry}`,
58
+ path: (0, node_path_1.resolve)(full, entry),
59
+ });
60
+ }
61
+ }
62
+ else {
63
+ results.push({ label: file, path: full });
64
+ }
65
+ }
66
+ catch {
67
+ // Skip inaccessible paths.
68
+ }
69
+ }
70
+ return results;
71
+ }
72
+ async function readRuleContext(cwd) {
73
+ const sections = [];
74
+ let usedBytes = 0;
75
+ for (const { label, path } of expandRulePaths(cwd)) {
76
+ if (usedBytes >= MAX_RULE_BYTES)
77
+ break;
78
+ try {
79
+ const content = await (0, promises_1.readFile)(path, "utf8");
80
+ const remaining = MAX_RULE_BYTES - usedBytes;
81
+ const body = truncateByBytes(content.trim(), remaining);
82
+ usedBytes += Buffer.byteLength(body);
83
+ sections.push(`### ${label}\n${body}`);
84
+ }
85
+ catch {
86
+ // Ignore unreadable optional context files.
87
+ }
88
+ }
89
+ return sections.length ? ["## 项目规则文档", ...sections] : [];
90
+ }
91
+ function buildLineWindow(file, content, changedLines) {
92
+ const lines = content.split("\n");
93
+ const windows = [];
94
+ for (const line of changedLines.slice(0, 12)) {
95
+ const start = Math.max(1, line - SOURCE_WINDOW_RADIUS);
96
+ const end = Math.min(lines.length, line + SOURCE_WINDOW_RADIUS);
97
+ const last = windows[windows.length - 1];
98
+ if (last && start <= last.end + 3) {
99
+ last.end = Math.max(last.end, end);
100
+ }
101
+ else {
102
+ windows.push({ start, end });
103
+ }
104
+ }
105
+ if (windows.length === 0)
106
+ return null;
107
+ const chunks = windows.map(({ start, end }) => {
108
+ const numbered = lines
109
+ .slice(start - 1, end)
110
+ .map((line, index) => `${String(start + index).padStart(4, " ")} | ${line}`)
111
+ .join("\n");
112
+ return `lines ${start}-${end}\n${numbered}`;
113
+ });
114
+ return `### ${file}\n${chunks.join("\n---\n")}`;
115
+ }
116
+ async function readSourceContext(cwd, diff) {
117
+ const added = (0, diff_1.collectAddedLines)(diff);
118
+ const changedFiles = (0, diff_1.getChangedFiles)(diff).slice(0, MAX_CONTEXT_FILES);
119
+ const sections = [];
120
+ let usedBytes = 0;
121
+ for (const file of changedFiles) {
122
+ const path = (0, node_path_1.resolve)(cwd, file);
123
+ const changedLines = (added.get(file) ?? []).map((item) => item.line);
124
+ if (changedLines.length === 0 || !(0, node_fs_1.existsSync)(path))
125
+ continue;
126
+ try {
127
+ const content = await (0, promises_1.readFile)(path, "utf8");
128
+ const section = buildLineWindow(file, content, changedLines);
129
+ if (!section)
130
+ continue;
131
+ const remaining = MAX_SOURCE_BYTES - usedBytes;
132
+ if (remaining <= 0)
133
+ break;
134
+ const body = truncateByBytes(section, remaining);
135
+ usedBytes += Buffer.byteLength(body);
136
+ sections.push(body);
137
+ }
138
+ catch {
139
+ // Ignore files that are not readable as text in the checkout.
140
+ }
141
+ }
142
+ return sections.length ? ["## 变更附近源码", ...sections] : [];
143
+ }
144
+ async function collectReviewContext(diff, options = {}) {
145
+ const cwd = options.cwd ?? process.cwd();
146
+ const env = options.env ?? process.env;
147
+ const sections = [
148
+ ...buildMrContext(env),
149
+ ...(await readRuleContext(cwd)),
150
+ ...(await readSourceContext(cwd, diff)),
151
+ ];
152
+ return sections.length ? sections.join("\n\n") : "(无额外上下文)";
153
+ }
154
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AIComment } from "../types";
2
+ export declare function filterDiffByIgnore(diff: string, ignorePatterns?: string[]): string;
3
+ export interface AddedLine {
4
+ file: string;
5
+ line: number;
6
+ content: string;
7
+ }
8
+ export declare function normalizePath(path: string): string;
9
+ export declare function collectAddedLines(diff: string): Map<string, AddedLine[]>;
10
+ export declare function getChangedFiles(diff: string): string[];
11
+ export declare function splitDiffByMaxBytes(diff: string, maxBytes: number): string[];
12
+ export declare function buildAddedLinesIndexText(diff: string, maxLines?: number): string;
13
+ export declare function alignCommentsToDiffAddedLines(diff: string, comments: AIComment[]): AIComment[];
14
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAoB1C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBlF;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CA8CxE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAatD;AAoBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB5E;AAED,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"}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterDiffByIgnore = filterDiffByIgnore;
4
+ exports.normalizePath = normalizePath;
5
+ exports.collectAddedLines = collectAddedLines;
6
+ exports.getChangedFiles = getChangedFiles;
7
+ exports.splitDiffByMaxBytes = splitDiffByMaxBytes;
8
+ exports.buildAddedLinesIndexText = buildAddedLinesIndexText;
9
+ exports.alignCommentsToDiffAddedLines = alignCommentsToDiffAddedLines;
10
+ function globToRegExp(pattern) {
11
+ if (pattern.endsWith("/**")) {
12
+ const prefix = pattern.slice(0, -3).replace(/[.+?^${}()|[\]\\]/g, "\\$&");
13
+ return new RegExp(`^${prefix}/.*$`);
14
+ }
15
+ if (pattern.startsWith("**/")) {
16
+ const rest = pattern
17
+ .slice(3)
18
+ .replace(/[.+?^${}()|[\]\\]/g, "\\$&")
19
+ .replace(/\*/g, "[^/]*");
20
+ return new RegExp(`^(?:.*/)?${rest}$`);
21
+ }
22
+ const escaped = pattern
23
+ .replace(/[.+?^${}()|[\]\\]/g, "\\$&")
24
+ .replace(/\*/g, "[^/]*");
25
+ return new RegExp(`^${escaped}$`);
26
+ }
27
+ function filterDiffByIgnore(diff, ignorePatterns) {
28
+ if (!ignorePatterns?.length || !diff.trim())
29
+ return diff;
30
+ const lines = diff.split("\n");
31
+ const kept = [];
32
+ let ignoreCurrent = false;
33
+ for (const line of lines) {
34
+ if (line.startsWith("diff --git ")) {
35
+ ignoreCurrent = false;
36
+ const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
37
+ if (match) {
38
+ ignoreCurrent = ignorePatterns.some((pattern) => globToRegExp(pattern).test(match[2]));
39
+ }
40
+ }
41
+ if (!ignoreCurrent)
42
+ kept.push(line);
43
+ }
44
+ return kept.join("\n");
45
+ }
46
+ function normalizePath(path) {
47
+ return path.trim().replace(/^[ab]\//, "").replace(/^\.\//, "");
48
+ }
49
+ function collectAddedLines(diff) {
50
+ const files = new Map();
51
+ let currentFile = null;
52
+ let inHunk = false;
53
+ let newLine = 0;
54
+ let oldLine = 0;
55
+ for (const raw of diff.split("\n")) {
56
+ if (raw.startsWith("diff --git ")) {
57
+ inHunk = false;
58
+ currentFile = null;
59
+ const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(raw);
60
+ if (match) {
61
+ currentFile = normalizePath(match[2]);
62
+ files.set(currentFile, files.get(currentFile) ?? []);
63
+ }
64
+ continue;
65
+ }
66
+ if (raw.startsWith("+++ b/")) {
67
+ currentFile = normalizePath(raw.slice("+++ b/".length));
68
+ files.set(currentFile, files.get(currentFile) ?? []);
69
+ continue;
70
+ }
71
+ if (raw.startsWith("@@")) {
72
+ const match = /^@@\s+\-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/.exec(raw);
73
+ inHunk = !!match;
74
+ oldLine = Number(match?.[1] ?? 0);
75
+ newLine = Number(match?.[2] ?? 0);
76
+ continue;
77
+ }
78
+ if (!inHunk || !currentFile)
79
+ continue;
80
+ if (raw.startsWith("+") && !raw.startsWith("+++")) {
81
+ files.get(currentFile)?.push({
82
+ file: currentFile,
83
+ line: newLine,
84
+ content: raw.slice(1),
85
+ });
86
+ newLine += 1;
87
+ }
88
+ else if (raw.startsWith("-") && !raw.startsWith("---")) {
89
+ oldLine += 1;
90
+ }
91
+ else if (raw.startsWith(" ")) {
92
+ oldLine += 1;
93
+ newLine += 1;
94
+ }
95
+ }
96
+ return files;
97
+ }
98
+ function getChangedFiles(diff) {
99
+ const files = new Set();
100
+ for (const raw of diff.split("\n")) {
101
+ if (raw.startsWith("diff --git ")) {
102
+ const match = /^diff --git a\/(.+?) b\/(.+)$/.exec(raw);
103
+ if (match)
104
+ files.add(normalizePath(match[2]));
105
+ continue;
106
+ }
107
+ if (raw.startsWith("+++ b/")) {
108
+ files.add(normalizePath(raw.slice("+++ b/".length)));
109
+ }
110
+ }
111
+ return [...files];
112
+ }
113
+ function splitDiffByFile(diff) {
114
+ const sections = [];
115
+ let current = [];
116
+ for (const line of diff.split("\n")) {
117
+ if (line.startsWith("diff --git ") && current.length > 0) {
118
+ sections.push(current.join("\n"));
119
+ current = [];
120
+ }
121
+ current.push(line);
122
+ }
123
+ if (current.some((line) => line.trim())) {
124
+ sections.push(current.join("\n"));
125
+ }
126
+ return sections.length ? sections : [diff];
127
+ }
128
+ function splitDiffByMaxBytes(diff, maxBytes) {
129
+ const files = splitDiffByFile(diff);
130
+ const shards = [];
131
+ let current = [];
132
+ let currentBytes = 0;
133
+ for (const fileDiff of files) {
134
+ const fileBytes = Buffer.byteLength(fileDiff);
135
+ if (current.length > 0 && currentBytes + fileBytes > maxBytes) {
136
+ shards.push(current.join("\n"));
137
+ current = [];
138
+ currentBytes = 0;
139
+ }
140
+ current.push(fileDiff);
141
+ currentBytes += fileBytes;
142
+ }
143
+ if (current.length > 0)
144
+ shards.push(current.join("\n"));
145
+ return shards;
146
+ }
147
+ function buildAddedLinesIndexText(diff, maxLines = 5000) {
148
+ const rows = [];
149
+ for (const [file, lines] of collectAddedLines(diff)) {
150
+ for (const item of lines) {
151
+ if (rows.length >= maxLines)
152
+ break;
153
+ rows.push(`[${file}:${item.line}] ${item.content}`);
154
+ }
155
+ if (rows.length >= maxLines)
156
+ break;
157
+ }
158
+ return rows.length ? rows.join("\n") : "(diff 中未检测到可评论的新增行)";
159
+ }
160
+ function alignCommentsToDiffAddedLines(diff, comments) {
161
+ const added = collectAddedLines(diff);
162
+ return comments.flatMap((comment) => {
163
+ const file = normalizePath(comment.file);
164
+ const candidates = added.get(file);
165
+ if (!candidates?.length)
166
+ return [];
167
+ const exact = candidates.find((item) => item.line === comment.line);
168
+ const byCode = typeof comment.code === "string"
169
+ ? candidates.find((item) => item.content.trim() === comment.code?.trim())
170
+ : undefined;
171
+ const chosen = exact ??
172
+ byCode ??
173
+ candidates.reduce((best, item) => Math.abs(item.line - comment.line) < Math.abs(best.line - comment.line)
174
+ ? item
175
+ : best);
176
+ return [{ ...comment, file, line: chosen.line }];
177
+ });
178
+ }
179
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { AIModelApiFormat } from "../types";
2
+ export interface ModelAdapter {
3
+ call(model: string, systemPrompt: string, userPrompt: string): Promise<string | null>;
4
+ }
5
+ export declare function createModelAdapter(endpoint: string, apiKey: string, apiFormat?: AIModelApiFormat): ModelAdapter;
6
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/core/model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,IAAI,CACF,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3B;AAuJD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,gBAAgB,GAC3B,YAAY,CAWd"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModelAdapter = createModelAdapter;
4
+ const constants_1 = require("../constants");
5
+ const http_1 = require("../shared/http");
6
+ async function readErrorBody(resp) {
7
+ const text = await resp.text().catch(() => "");
8
+ return text.trim().slice(0, 1000);
9
+ }
10
+ class BaseModelAdapter {
11
+ constructor(endpoint, apiKey) {
12
+ this.endpoint = endpoint;
13
+ this.apiKey = apiKey;
14
+ }
15
+ async call(model, systemPrompt, userPrompt) {
16
+ const tag = this.providerName;
17
+ console.error(`[model] ${tag} request start model=${model}`);
18
+ let resp;
19
+ try {
20
+ resp = await (0, http_1.fetchWithTimeout)(this.buildRequestUrl(), {
21
+ method: "POST",
22
+ headers: {
23
+ "Content-Type": "application/json",
24
+ ...this.buildHeaders(),
25
+ },
26
+ body: JSON.stringify(this.buildBody(model, systemPrompt, userPrompt)),
27
+ }, constants_1.REQUEST_TIMEOUT_MS);
28
+ }
29
+ catch (err) {
30
+ const reason = err instanceof Error && err.name === "AbortError"
31
+ ? "timeout"
32
+ : "network error";
33
+ console.error(`[model] ${tag} request ${reason}: ${err}`);
34
+ return null;
35
+ }
36
+ if (!resp.ok) {
37
+ const body = await readErrorBody(resp);
38
+ console.error(body
39
+ ? `[model] ${tag} API failed status=${resp.status} body=${body}`
40
+ : `[model] ${tag} API failed status=${resp.status}`);
41
+ return null;
42
+ }
43
+ const json = await (0, http_1.parseJsonSafe)(resp);
44
+ if (!json) {
45
+ console.error(`[model] ${tag} response body parse failed`);
46
+ return null;
47
+ }
48
+ const content = this.extractContent(json);
49
+ console.error(content
50
+ ? `[model] ${tag} request complete bytes=${Buffer.byteLength(content)}`
51
+ : `[model] ${tag} response empty`);
52
+ return content;
53
+ }
54
+ }
55
+ class OpenAIAdapter extends BaseModelAdapter {
56
+ get providerName() {
57
+ return "openai-compatible";
58
+ }
59
+ buildRequestUrl() {
60
+ const url = this.endpoint.replace(/\/+$/, "");
61
+ return url.endsWith("/chat/completions") ? url : `${url}/chat/completions`;
62
+ }
63
+ buildHeaders() {
64
+ return { Authorization: `Bearer ${this.apiKey}` };
65
+ }
66
+ buildBody(model, systemPrompt, userPrompt) {
67
+ return {
68
+ model,
69
+ messages: [
70
+ { role: "system", content: systemPrompt },
71
+ { role: "user", content: userPrompt },
72
+ ],
73
+ stream: false,
74
+ };
75
+ }
76
+ extractContent(json) {
77
+ const data = json;
78
+ return data.choices?.[0]?.message?.content?.trim() || null;
79
+ }
80
+ }
81
+ class ClaudeAdapter extends BaseModelAdapter {
82
+ get providerName() {
83
+ return "claude";
84
+ }
85
+ buildRequestUrl() {
86
+ const url = this.endpoint.replace(/\/+$/, "");
87
+ return url.endsWith("/v1/messages") ? url : `${url}/v1/messages`;
88
+ }
89
+ buildHeaders() {
90
+ return {
91
+ "x-api-key": this.apiKey,
92
+ "anthropic-version": "2023-06-01",
93
+ };
94
+ }
95
+ buildBody(model, systemPrompt, userPrompt) {
96
+ return {
97
+ model,
98
+ max_tokens: 32768,
99
+ system: systemPrompt,
100
+ messages: [{ role: "user", content: userPrompt }],
101
+ };
102
+ }
103
+ extractContent(json) {
104
+ const data = json;
105
+ return data.content?.find((b) => b.type === "text")?.text?.trim() || null;
106
+ }
107
+ }
108
+ function createModelAdapter(endpoint, apiKey, apiFormat) {
109
+ if (apiFormat === "claude") {
110
+ return new ClaudeAdapter(endpoint, apiKey);
111
+ }
112
+ if (apiFormat === "openai") {
113
+ return new OpenAIAdapter(endpoint, apiKey);
114
+ }
115
+ if (endpoint.includes("anthropic.com") || endpoint.includes("/v1/messages")) {
116
+ return new ClaudeAdapter(endpoint, apiKey);
117
+ }
118
+ return new OpenAIAdapter(endpoint, apiKey);
119
+ }
120
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/core/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AIComment, RdjsonOutput } from "../types";
2
+ export declare function buildEmptyRdjson(): RdjsonOutput;
3
+ export declare function buildRdjson(comments: AIComment[]): RdjsonOutput;
4
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAY,MAAM,UAAU,CAAC;AASlE,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,CAgB/D"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildEmptyRdjson = buildEmptyRdjson;
4
+ exports.buildRdjson = buildRdjson;
5
+ const constants_1 = require("../constants");
6
+ function toRdjsonSeverity(severity) {
7
+ if (severity === "error")
8
+ return "ERROR";
9
+ if (severity === "info")
10
+ return "INFO";
11
+ return "WARNING";
12
+ }
13
+ function buildEmptyRdjson() {
14
+ return { source: { name: "ai_code_review" }, diagnostics: [] };
15
+ }
16
+ function buildRdjson(comments) {
17
+ return {
18
+ source: { name: "ai_code_review" },
19
+ diagnostics: comments
20
+ .filter((comment) => comment.file && comment.line)
21
+ .map((comment) => ({
22
+ message: `${comment.message || constants_1.DEFAULT_COMMENT_MESSAGE}${comment.suggestion ? `\n建议:${comment.suggestion}` : ""}`,
23
+ location: {
24
+ path: comment.file,
25
+ range: { start: { line: Number(comment.line) || 1, column: 1 } },
26
+ },
27
+ severity: toRdjsonSeverity(comment.severity),
28
+ })),
29
+ };
30
+ }
31
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":";;AASA,4CAEC;AAED,kCAgBC;AA5BD,4CAAuD;AAEvD,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,mCAAuB,GACpD,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"}
@@ -0,0 +1,17 @@
1
+ export declare class PromptBuilder {
2
+ private diff;
3
+ private rules;
4
+ private context;
5
+ setDiff(diff: string): this;
6
+ setRules(custom: string[]): this;
7
+ setContext(context: string): this;
8
+ buildSystem(): string;
9
+ buildUser(): string;
10
+ }
11
+ export declare class SummaryPromptBuilder {
12
+ private diff;
13
+ setDiff(diff: string): this;
14
+ buildSystem(): string;
15
+ buildUser(): string;
16
+ }
17
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/core/prompt.ts"],"names":[],"mappings":"AAUA,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAM;IAErB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKhC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC,WAAW,IAAI,MAAM;IAIrB,SAAS,IAAI,MAAM;CAoBpB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAM;IAElB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B,WAAW,IAAI,MAAM;IAQrB,SAAS,IAAI,MAAM;CAoBpB"}