review-mark 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -18
- package/dist/cli/review.cjs +89 -51
- package/dist/cli/review.cjs.map +1 -1
- package/dist/cli/review.js +97 -53
- package/dist/cli/review.js.map +1 -1
- package/dist/index.cjs +86 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/cli/review.ts +3 -3
- package/src/core/BeLinkReview.ts +17 -16
- package/src/core/feishu.ts +10 -8
- package/src/core/git.ts +30 -23
- package/src/utils/checkCli.ts +58 -17
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# review-mark
|
|
2
2
|
|
|
3
3
|
A powerful CLI tool for AI-powered code review using Git diffs.
|
|
4
4
|
|
|
5
5
|
## 目标
|
|
6
6
|
|
|
7
|
-
`
|
|
7
|
+
`review-mark` 旨在提供一个自动化 AI 代码审查解决方案。用户可以在自己的项目中初始化该工具后,通过简单的 CLI 命令自动获取 `git diff`,并将其发送给 AI 进行代码审查,从而帮助开发者发现潜在的 bug、逻辑问题、性能问题和代码风格问题,并获得优化建议。
|
|
8
8
|
|
|
9
9
|
## 特性
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ A powerful CLI tool for AI-powered code review using Git diffs.
|
|
|
20
20
|
## 项目结构
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
|
|
23
|
+
review-mark
|
|
24
24
|
│
|
|
25
25
|
├─ src
|
|
26
26
|
│ ├─ core
|
|
@@ -52,14 +52,10 @@ be-link-review
|
|
|
52
52
|
|
|
53
53
|
## 安装
|
|
54
54
|
|
|
55
|
-
首先,在你的项目根目录安装 `
|
|
55
|
+
首先,在你的项目根目录安装 `review-mark` 作为开发依赖:
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
pnpm add -D
|
|
59
|
-
# 或者
|
|
60
|
-
yarn add -D be-link-review
|
|
61
|
-
# 或者
|
|
62
|
-
npm install -D be-link-review
|
|
58
|
+
pnpm add -D review-mark
|
|
63
59
|
```
|
|
64
60
|
|
|
65
61
|
## 使用
|
|
@@ -70,7 +66,7 @@ npm install -D be-link-review
|
|
|
70
66
|
|
|
71
67
|
```typescript
|
|
72
68
|
// src/main.ts (或你的项目入口文件)
|
|
73
|
-
import { BeLinkReview } from "
|
|
69
|
+
import { BeLinkReview } from "review-mark";
|
|
74
70
|
|
|
75
71
|
BeLinkReview.init({
|
|
76
72
|
apiKey: process.env.CURSOR_API_KEY || "YOUR_CURSOR_API_KEY", // 建议从环境变量获取
|
|
@@ -79,13 +75,13 @@ BeLinkReview.init({
|
|
|
79
75
|
// 你可以在这里继续你的应用逻辑
|
|
80
76
|
```
|
|
81
77
|
|
|
82
|
-
`BeLinkReview.init()` 会自动检测并向你的 `package.json` 文件中添加一个 `review` 脚本:
|
|
78
|
+
`BeLinkReview.init()` 会自动检测并向你的 `package.json` 文件中添加一个 `review-mark` 脚本:
|
|
83
79
|
|
|
84
80
|
```json
|
|
85
81
|
// package.json
|
|
86
82
|
{
|
|
87
83
|
"scripts": {
|
|
88
|
-
"review": "
|
|
84
|
+
"review-mark": "review-mark"
|
|
89
85
|
}
|
|
90
86
|
}
|
|
91
87
|
```
|
|
@@ -97,7 +93,7 @@ BeLinkReview.init({
|
|
|
97
93
|
初始化完成后,你可以在项目根目录执行以下命令来运行 AI 代码审查:
|
|
98
94
|
|
|
99
95
|
```bash
|
|
100
|
-
pnpm run review
|
|
96
|
+
pnpm run review-mark
|
|
101
97
|
```
|
|
102
98
|
|
|
103
99
|
CLI 将会执行以下步骤:
|
|
@@ -111,8 +107,8 @@ CLI 将会执行以下步骤:
|
|
|
111
107
|
#### CLI 输出示例
|
|
112
108
|
|
|
113
109
|
```
|
|
114
|
-
[
|
|
115
|
-
[
|
|
110
|
+
[review-mark] Getting git diff...
|
|
111
|
+
[review-mark] Sending to AI...
|
|
116
112
|
===== AI Review =====
|
|
117
113
|
(这里是 AI 返回结果)
|
|
118
114
|
```
|
|
@@ -120,7 +116,7 @@ CLI 将会执行以下步骤:
|
|
|
120
116
|
如果检测到没有代码变更,则会输出:
|
|
121
117
|
|
|
122
118
|
```
|
|
123
|
-
[
|
|
119
|
+
[review-mark] No code changes detected
|
|
124
120
|
```
|
|
125
121
|
|
|
126
122
|
## 配置
|
|
@@ -142,11 +138,12 @@ interface BeLinkReviewOptions {
|
|
|
142
138
|
|
|
143
139
|
### 飞书机器人集成
|
|
144
140
|
|
|
145
|
-
`
|
|
141
|
+
`review-mark` 已**完全内置**飞书机器人功能,所有飞书配置已写死在代码中,**无需任何配置即可使用**!
|
|
146
142
|
|
|
147
143
|
#### 1. 开箱即用
|
|
148
144
|
|
|
149
145
|
✅ 飞书配置已完全内置,包括:
|
|
146
|
+
|
|
150
147
|
- App ID 和 App Secret
|
|
151
148
|
- 接收者 ID (群聊/用户)
|
|
152
149
|
- 消息类型和标题
|
|
@@ -209,6 +206,7 @@ A: 修改 `src/constants.ts` 中的 `receiveId` 为新的群聊 chat_id,然后
|
|
|
209
206
|
|
|
210
207
|
**Q: 支持哪些消息格式?**
|
|
211
208
|
A: 支持三种格式:
|
|
209
|
+
|
|
212
210
|
- `interactive` (默认): 美观的消息卡片,支持 Markdown
|
|
213
211
|
- `post`: 富文本格式
|
|
214
212
|
- `text`: 纯文本格式
|
|
@@ -221,7 +219,7 @@ A: 使用 `--no-feishu` 参数或设置 `FEISHU_ENABLED=false` 环境变量。
|
|
|
221
219
|
### 构建项目
|
|
222
220
|
|
|
223
221
|
```bash
|
|
224
|
-
cd
|
|
222
|
+
cd review-mark
|
|
225
223
|
pnpm install
|
|
226
224
|
pnpm run build
|
|
227
225
|
```
|
package/dist/cli/review.cjs
CHANGED
|
@@ -38,13 +38,42 @@ var import_node_fs = require("fs");
|
|
|
38
38
|
var import_node_os = require("os");
|
|
39
39
|
var import_node_path = require("path");
|
|
40
40
|
var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
41
|
+
var LOCAL_BIN = (0, import_node_path.join)((0, import_node_os.homedir)(), ".local", "bin");
|
|
41
42
|
var COMMON_AGENT_PATHS = [
|
|
43
|
+
(0, import_node_path.join)(LOCAL_BIN, "agent"),
|
|
44
|
+
// Cursor 官方安装脚本默认路径
|
|
42
45
|
(0, import_node_path.join)((0, import_node_os.homedir)(), ".cursor", "agent"),
|
|
43
46
|
"/usr/local/bin/agent",
|
|
44
|
-
// macOS Homebrew 或手动安装的常见路径
|
|
45
47
|
"/opt/homebrew/bin/agent"
|
|
46
|
-
// macOS Apple Silicon Homebrew 路径
|
|
47
48
|
];
|
|
49
|
+
function setupLocalBinPath(silent) {
|
|
50
|
+
if (!process.env.PATH?.includes(LOCAL_BIN)) {
|
|
51
|
+
process.env.PATH = `${LOCAL_BIN}:${process.env.PATH}`;
|
|
52
|
+
}
|
|
53
|
+
const exportLine = `
|
|
54
|
+
export PATH="$HOME/.local/bin:$PATH"`;
|
|
55
|
+
const shell = process.env.SHELL ?? "";
|
|
56
|
+
const rcFiles = [];
|
|
57
|
+
if (shell.includes("zsh")) {
|
|
58
|
+
rcFiles.push((0, import_node_path.join)((0, import_node_os.homedir)(), ".zshrc"));
|
|
59
|
+
} else if (shell.includes("bash")) {
|
|
60
|
+
rcFiles.push((0, import_node_path.join)((0, import_node_os.homedir)(), ".bashrc"));
|
|
61
|
+
} else {
|
|
62
|
+
rcFiles.push((0, import_node_path.join)((0, import_node_os.homedir)(), ".zshrc"), (0, import_node_path.join)((0, import_node_os.homedir)(), ".bashrc"));
|
|
63
|
+
}
|
|
64
|
+
for (const rc of rcFiles) {
|
|
65
|
+
try {
|
|
66
|
+
const content = (0, import_node_fs.existsSync)(rc) ? require("fs").readFileSync(rc, "utf-8") : "";
|
|
67
|
+
if (!content.includes(".local/bin")) {
|
|
68
|
+
(0, import_node_fs.appendFileSync)(rc, exportLine);
|
|
69
|
+
if (!silent) {
|
|
70
|
+
console.log(`[review-mark] \u5DF2\u5C06 ~/.local/bin \u5199\u5165 ${rc}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
48
77
|
async function findAgentExecutable(userAgentPath) {
|
|
49
78
|
if (userAgentPath && (0, import_node_fs.existsSync)(userAgentPath)) {
|
|
50
79
|
return userAgentPath;
|
|
@@ -70,15 +99,15 @@ async function isCheckCliInstall(options) {
|
|
|
70
99
|
if (actualAgentPath) {
|
|
71
100
|
if (!silent) {
|
|
72
101
|
console.log(
|
|
73
|
-
`[
|
|
102
|
+
`[review-mark] Cursor CLI (agent) \u5DF2\u5728 ${actualAgentPath} \u627E\u5230\u3002`
|
|
74
103
|
);
|
|
75
104
|
}
|
|
76
105
|
return { isInstalled: true, message: "Cursor CLI \u5DF2\u5B89\u88C5", actualAgentPath };
|
|
77
106
|
}
|
|
78
107
|
if (!silent) {
|
|
79
|
-
console.log("[
|
|
108
|
+
console.log("[review-mark] Cursor CLI (agent) \u672A\u627E\u5230\uFF0C\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5...");
|
|
80
109
|
console.log(
|
|
81
|
-
"[
|
|
110
|
+
"[review-mark] \u6267\u884C\u5B89\u88C5\u547D\u4EE4: curl https://cursor.com/install -fsS | bash"
|
|
82
111
|
);
|
|
83
112
|
}
|
|
84
113
|
return new Promise((resolve, reject) => {
|
|
@@ -92,10 +121,11 @@ async function isCheckCliInstall(options) {
|
|
|
92
121
|
);
|
|
93
122
|
installProcess.on("close", async (code) => {
|
|
94
123
|
if (code === 0) {
|
|
124
|
+
setupLocalBinPath(silent);
|
|
95
125
|
actualAgentPath = await findAgentExecutable(userAgentPath);
|
|
96
126
|
if (actualAgentPath) {
|
|
97
127
|
if (!silent) {
|
|
98
|
-
console.log("[
|
|
128
|
+
console.log("[review-mark] Cursor CLI \u5B89\u88C5\u6210\u529F\u3002");
|
|
99
129
|
}
|
|
100
130
|
resolve({
|
|
101
131
|
isInstalled: true,
|
|
@@ -105,14 +135,14 @@ async function isCheckCliInstall(options) {
|
|
|
105
135
|
} else {
|
|
106
136
|
reject(
|
|
107
137
|
new Error(
|
|
108
|
-
`[
|
|
138
|
+
`[review-mark] Cursor CLI \u5B89\u88C5\u547D\u4EE4\u6267\u884C\u6210\u529F\uFF0C\u4F46\u672A\u627E\u5230 agent \u53EF\u6267\u884C\u6587\u4EF6\u3002\u8BF7\u624B\u52A8\u68C0\u67E5\u5B89\u88C5\uFF1Acurl https://cursor.com/install -fsS | bash\u3002`
|
|
109
139
|
)
|
|
110
140
|
);
|
|
111
141
|
}
|
|
112
142
|
} else {
|
|
113
143
|
reject(
|
|
114
144
|
new Error(
|
|
115
|
-
`[
|
|
145
|
+
`[review-mark] Cursor CLI \u5B89\u88C5\u5931\u8D25\uFF0C\u9000\u51FA\u7801 ${code}\u3002\u8BF7\u624B\u52A8\u5B89\u88C5\uFF1Acurl https://cursor.com/install -fsS | bash\u3002`
|
|
116
146
|
)
|
|
117
147
|
);
|
|
118
148
|
}
|
|
@@ -120,7 +150,7 @@ async function isCheckCliInstall(options) {
|
|
|
120
150
|
installProcess.on("error", (err) => {
|
|
121
151
|
reject(
|
|
122
152
|
new Error(
|
|
123
|
-
`[
|
|
153
|
+
`[review-mark] \u65E0\u6CD5\u542F\u52A8\u5B89\u88C5\u8FDB\u7A0B\uFF1A${err.message}\u3002\u8BF7\u624B\u52A8\u5B89\u88C5\uFF1Acurl https://cursor.com/install -fsS | bash`
|
|
124
154
|
)
|
|
125
155
|
);
|
|
126
156
|
});
|
|
@@ -130,44 +160,50 @@ async function isCheckCliInstall(options) {
|
|
|
130
160
|
// src/core/git.ts
|
|
131
161
|
var import_node_child_process2 = require("child_process");
|
|
132
162
|
var import_node_util2 = require("util");
|
|
133
|
-
var
|
|
163
|
+
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
164
|
+
var FIXED_IGNORE_PATTERNS = ["package.json"];
|
|
165
|
+
async function runGit(args, cwd) {
|
|
166
|
+
const { stdout } = await execFileAsync("git", args, { cwd });
|
|
167
|
+
return stdout.trim();
|
|
168
|
+
}
|
|
134
169
|
async function getGitDiff(userIgnorePatterns = [], cwd = process.cwd()) {
|
|
135
170
|
try {
|
|
136
|
-
await
|
|
171
|
+
await runGit(["rev-parse", "--git-dir"], cwd);
|
|
137
172
|
} catch (error) {
|
|
138
|
-
console.error(`[
|
|
173
|
+
console.error(`[review-mark] \u5F53\u524D\u76EE\u5F55\u4E0D\u662F git \u4ED3\u5E93: ${cwd}`);
|
|
139
174
|
return "";
|
|
140
175
|
}
|
|
141
|
-
const allIgnorePatterns = [
|
|
142
|
-
|
|
176
|
+
const allIgnorePatterns = [
|
|
177
|
+
.../* @__PURE__ */ new Set([...FIXED_IGNORE_PATTERNS, ...userIgnorePatterns])
|
|
178
|
+
];
|
|
179
|
+
const excludeArgs = allIgnorePatterns.map((p) => `:(exclude)${p}`);
|
|
143
180
|
let diff = "";
|
|
144
|
-
const baseCommand = `git diff --no-color --relative ${excludeArgs}`;
|
|
145
181
|
try {
|
|
146
|
-
|
|
182
|
+
diff = await runGit(
|
|
183
|
+
["diff", "--no-color", "--relative", "--cached", "--", ...excludeArgs],
|
|
147
184
|
cwd
|
|
148
|
-
|
|
149
|
-
diff = cachedDiff.trim();
|
|
185
|
+
);
|
|
150
186
|
if (diff) {
|
|
151
|
-
console.log("[
|
|
187
|
+
console.log("[review-mark] \u68C0\u6D4B\u5230\u6682\u5B58\u533A\u6539\u52A8");
|
|
152
188
|
}
|
|
153
189
|
} catch (error) {
|
|
154
|
-
console.warn(`[
|
|
190
|
+
console.warn(`[review-mark] \u83B7\u53D6\u6682\u5B58\u533A diff \u5931\u8D25: ${error.message}`);
|
|
155
191
|
}
|
|
156
192
|
if (!diff) {
|
|
157
193
|
try {
|
|
158
|
-
|
|
194
|
+
diff = await runGit(
|
|
195
|
+
["diff", "--no-color", "--relative", "HEAD", "--", ...excludeArgs],
|
|
159
196
|
cwd
|
|
160
|
-
|
|
161
|
-
diff = headDiff.trim();
|
|
197
|
+
);
|
|
162
198
|
if (diff) {
|
|
163
|
-
console.log("[
|
|
199
|
+
console.log("[review-mark] \u68C0\u6D4B\u5230\u5DE5\u4F5C\u533A\u6539\u52A8\uFF08\u76F8\u5BF9\u4E8E HEAD\uFF09");
|
|
164
200
|
}
|
|
165
201
|
} catch (error) {
|
|
166
|
-
console.warn(`[
|
|
202
|
+
console.warn(`[review-mark] \u83B7\u53D6\u5DE5\u4F5C\u533A diff \u5931\u8D25: ${error.message}`);
|
|
167
203
|
}
|
|
168
204
|
}
|
|
169
205
|
if (!diff) {
|
|
170
|
-
console.log("[
|
|
206
|
+
console.log("[review-mark] \u672A\u68C0\u6D4B\u5230\u4EE3\u7801\u6539\u52A8\uFF08\u5DF2\u68C0\u67E5\u6682\u5B58\u533A\u548C\u5DE5\u4F5C\u533A\uFF09");
|
|
171
207
|
}
|
|
172
208
|
return diff;
|
|
173
209
|
}
|
|
@@ -198,8 +234,8 @@ var messageTitle = "\u{1F50D} Code Review \u7ED3\u679C";
|
|
|
198
234
|
|
|
199
235
|
// src/core/feishu.ts
|
|
200
236
|
async function sendReviewToFeishu(reviewContent) {
|
|
201
|
-
console.log("[
|
|
202
|
-
console.log(`[
|
|
237
|
+
console.log("[review-mark] \u6B63\u5728\u53D1\u9001\u6D88\u606F\u5230\u98DE\u4E66...");
|
|
238
|
+
console.log(`[review-mark] \u6D88\u606F\u7C7B\u578B: ${messageType}`);
|
|
203
239
|
try {
|
|
204
240
|
const client = new lark.Client({
|
|
205
241
|
appId,
|
|
@@ -261,9 +297,9 @@ ${reviewContent}`
|
|
|
261
297
|
});
|
|
262
298
|
msgType = "text";
|
|
263
299
|
} else {
|
|
264
|
-
throw new Error(`[
|
|
300
|
+
throw new Error(`[review-mark] \u4E0D\u652F\u6301\u7684\u6D88\u606F\u7C7B\u578B: ${messageType}`);
|
|
265
301
|
}
|
|
266
|
-
console.log(`[
|
|
302
|
+
console.log(`[review-mark] \u53D1\u9001\u53C2\u6570:`);
|
|
267
303
|
console.log(` - receive_id_type: ${receiveIdType}`);
|
|
268
304
|
console.log(` - receive_id: ${receiveId}`);
|
|
269
305
|
console.log(` - msg_type: ${msgType}`);
|
|
@@ -279,13 +315,15 @@ ${reviewContent}`
|
|
|
279
315
|
});
|
|
280
316
|
if (response.code !== 0) {
|
|
281
317
|
throw new Error(
|
|
282
|
-
`[
|
|
318
|
+
`[review-mark] \u98DE\u4E66 API \u8FD4\u56DE\u9519\u8BEF: ${response.msg || "\u672A\u77E5\u9519\u8BEF"}`
|
|
283
319
|
);
|
|
284
320
|
}
|
|
285
|
-
console.log("[
|
|
286
|
-
console.log(
|
|
321
|
+
console.log("[review-mark] \u2705 \u98DE\u4E66\u6D88\u606F\u53D1\u9001\u6210\u529F");
|
|
322
|
+
console.log(
|
|
323
|
+
`[review-mark] \u6D88\u606F ID: ${response.data?.message_id || "\u672A\u77E5"}`
|
|
324
|
+
);
|
|
287
325
|
} catch (error) {
|
|
288
|
-
console.error(`[
|
|
326
|
+
console.error(`[review-mark] \u274C \u98DE\u4E66\u6D88\u606F\u53D1\u9001\u5931\u8D25: ${error.message}`);
|
|
289
327
|
throw error;
|
|
290
328
|
}
|
|
291
329
|
}
|
|
@@ -460,7 +498,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
460
498
|
const enableFeishu = cliEnableFeishu ?? process.env.FEISHU_ENABLED !== "false";
|
|
461
499
|
if (!apiKey) {
|
|
462
500
|
throw new Error(
|
|
463
|
-
'[
|
|
501
|
+
'[review-mark] \u8BF7\u5148\u8C03\u7528 BeLinkReview.init({ apiKey: "..." }) \u521D\u59CB\u5316\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF CURSOR_API_KEY\uFF0C\u6216\u901A\u8FC7\u547D\u4EE4\u884C\u53C2\u6570 --apiKey \u4F20\u5165\u3002'
|
|
464
502
|
);
|
|
465
503
|
}
|
|
466
504
|
_BeLinkReview.#instance = new _BeLinkReview(
|
|
@@ -489,7 +527,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
489
527
|
const apiKey = this.#apiKey || process.env.CURSOR_API_KEY;
|
|
490
528
|
if (!apiKey) {
|
|
491
529
|
throw new Error(
|
|
492
|
-
'[
|
|
530
|
+
'[review-mark] \u8BF7\u5148\u5728 init({ apiKey: "..." }) \u4E2D\u4F20\u5165 apiKey\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF CURSOR_API_KEY\uFF0C\u6216\u901A\u8FC7\u547D\u4EE4\u884C\u53C2\u6570 --apiKey \u4F20\u5165\u3002'
|
|
493
531
|
);
|
|
494
532
|
}
|
|
495
533
|
return apiKey;
|
|
@@ -514,17 +552,17 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
514
552
|
if (!packageJson.scripts) {
|
|
515
553
|
packageJson.scripts = {};
|
|
516
554
|
}
|
|
517
|
-
if (!packageJson.scripts
|
|
518
|
-
packageJson.scripts
|
|
555
|
+
if (!packageJson.scripts["review-mark"]) {
|
|
556
|
+
packageJson.scripts["review-mark"] = "review-mark";
|
|
519
557
|
(0, import_node_fs2.writeFileSync)(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
520
558
|
console.log(
|
|
521
|
-
"[
|
|
559
|
+
"[review-mark] \u5DF2\u5728 package.json \u4E2D\u6DFB\u52A0 'review-mark' \u811A\u672C\u3002"
|
|
522
560
|
);
|
|
523
561
|
} else {
|
|
524
|
-
console.log("[
|
|
562
|
+
console.log("[review-mark] 'review-mark' \u811A\u672C\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u6DFB\u52A0\u3002");
|
|
525
563
|
}
|
|
526
564
|
} catch (error) {
|
|
527
|
-
console.error("[
|
|
565
|
+
console.error("[review-mark] \u65E0\u6CD5\u66F4\u65B0 package.json: ", error);
|
|
528
566
|
}
|
|
529
567
|
}
|
|
530
568
|
/**
|
|
@@ -537,17 +575,17 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
537
575
|
const ensureResult = await this.ensureAgentInstalled(false, agentPath);
|
|
538
576
|
if (!ensureResult.isInstalled) {
|
|
539
577
|
throw new Error(
|
|
540
|
-
"[
|
|
578
|
+
"[review-mark] Cursor CLI \u672A\u5B89\u88C5\u4E14\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u5B89\u88C5\u3002"
|
|
541
579
|
);
|
|
542
580
|
}
|
|
543
|
-
console.log("[
|
|
581
|
+
console.log("[review-mark] Getting git diff...");
|
|
544
582
|
const diff = await getGitDiff(ignorePatterns, process.cwd());
|
|
545
583
|
if (!diff) {
|
|
546
|
-
console.log("[
|
|
584
|
+
console.log("[review-mark] No code changes detected");
|
|
547
585
|
return "No code changes detected";
|
|
548
586
|
}
|
|
549
587
|
const prompt = generateAIPrompt(diff);
|
|
550
|
-
console.log("[
|
|
588
|
+
console.log("[review-mark] Sending to AI...");
|
|
551
589
|
const response = await this.chat(prompt, {
|
|
552
590
|
agentPath: ensureResult.actualAgentPath,
|
|
553
591
|
force: true
|
|
@@ -559,7 +597,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
559
597
|
await sendReviewToFeishu(response);
|
|
560
598
|
} catch (error) {
|
|
561
599
|
console.error(
|
|
562
|
-
`[
|
|
600
|
+
`[review-mark] \u98DE\u4E66\u901A\u77E5\u53D1\u9001\u5931\u8D25\uFF0C\u4F46\u4E0D\u5F71\u54CD review \u7ED3\u679C: ${error.message}`
|
|
563
601
|
);
|
|
564
602
|
}
|
|
565
603
|
}
|
|
@@ -601,7 +639,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
601
639
|
proc.on("error", (err) => {
|
|
602
640
|
reject(
|
|
603
641
|
new Error(
|
|
604
|
-
`[
|
|
642
|
+
`[review-mark] \u65E0\u6CD5\u542F\u52A8 Cursor CLI (${actualAgentPath})\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Acurl https://cursor.com/install -fsS | bash\u3002\u539F\u59CB\u9519\u8BEF: ${err.message}`
|
|
605
643
|
)
|
|
606
644
|
);
|
|
607
645
|
});
|
|
@@ -609,7 +647,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
609
647
|
if (code !== 0) {
|
|
610
648
|
reject(
|
|
611
649
|
new Error(
|
|
612
|
-
`[
|
|
650
|
+
`[review-mark] agent \u9000\u51FA\u7801 ${code}${stderr ? `: ${stderr.trim()}` : ""}`
|
|
613
651
|
)
|
|
614
652
|
);
|
|
615
653
|
return;
|
|
@@ -622,7 +660,7 @@ var BeLinkReview = class _BeLinkReview {
|
|
|
622
660
|
|
|
623
661
|
// src/cli/review.ts
|
|
624
662
|
var program = new import_commander.Command();
|
|
625
|
-
program.name("
|
|
663
|
+
program.name("review-mark").description("AI-powered code review tool").version("1.0.0").option(
|
|
626
664
|
"--apiKey <key>",
|
|
627
665
|
"Cursor API Key (overrides CURSOR_API_KEY environment variable)"
|
|
628
666
|
).option(
|
|
@@ -660,7 +698,7 @@ program.name("belink-review").description("AI-powered code review tool").version
|
|
|
660
698
|
);
|
|
661
699
|
await instance.goCli();
|
|
662
700
|
} catch (error) {
|
|
663
|
-
console.error(`[
|
|
701
|
+
console.error(`[review-mark] Error: ${error.message}`);
|
|
664
702
|
process.exit(1);
|
|
665
703
|
}
|
|
666
704
|
});
|
|
@@ -702,7 +740,7 @@ program.command("review").description("Perform an AI code review on git diff").o
|
|
|
702
740
|
);
|
|
703
741
|
await instance.goCli();
|
|
704
742
|
} catch (error) {
|
|
705
|
-
console.error(`[
|
|
743
|
+
console.error(`[review-mark] Error: ${error.message}`);
|
|
706
744
|
process.exit(1);
|
|
707
745
|
}
|
|
708
746
|
});
|