@spaceflow/review 0.61.0 → 0.62.0
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.61.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.60.0...@spaceflow/review@0.61.0) (2026-03-03)
|
|
4
|
+
|
|
5
|
+
### 代码重构
|
|
6
|
+
|
|
7
|
+
* **review:** 优化无效问题统计逻辑,排除已修复和已解决的问题 ([1de7b2a](https://github.com/Lydanne/spaceflow/commit/1de7b2a23fcc3ff73f679fc219342e111d96acf7))
|
|
8
|
+
|
|
9
|
+
### 其他修改
|
|
10
|
+
|
|
11
|
+
* **review-summary:** released version 0.28.0 [no ci] ([e131ed8](https://github.com/Lydanne/spaceflow/commit/e131ed83528ef8b45b3e3edaac5dab3389812323))
|
|
12
|
+
* **scripts:** released version 0.25.0 [no ci] ([88292c0](https://github.com/Lydanne/spaceflow/commit/88292c07b7787bcd4492c8b88cfb516b3e81d9be))
|
|
13
|
+
* **shell:** released version 0.25.0 [no ci] ([fc78e10](https://github.com/Lydanne/spaceflow/commit/fc78e10a0bab04d575867732b922a2a1989a594e))
|
|
14
|
+
|
|
3
15
|
## [0.60.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.59.0...@spaceflow/review@0.60.0) (2026-03-02)
|
|
4
16
|
|
|
5
17
|
### 代码重构
|
package/dist/index.js
CHANGED
|
@@ -1169,34 +1169,69 @@ class MarkdownFormatter {
|
|
|
1169
1169
|
if (summaries.length === 0) {
|
|
1170
1170
|
return "没有需要审查的文件";
|
|
1171
1171
|
}
|
|
1172
|
+
// 🟢 已修复 | 🔴 待处理error | 🟡 待处理warn | ⚪ 已解决(非代码修复)
|
|
1172
1173
|
const issuesByFile = new Map();
|
|
1173
1174
|
for (const issue of issues){
|
|
1174
1175
|
if (issue.valid === "false") continue;
|
|
1175
1176
|
const stats = issuesByFile.get(issue.file) || {
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1177
|
+
fixed: 0,
|
|
1178
|
+
pendingErrors: 0,
|
|
1179
|
+
pendingWarns: 0,
|
|
1180
|
+
resolved: 0
|
|
1179
1181
|
};
|
|
1180
1182
|
if (issue.fixed) {
|
|
1183
|
+
stats.fixed++;
|
|
1184
|
+
} else if (issue.resolved) {
|
|
1181
1185
|
stats.resolved++;
|
|
1182
1186
|
} else if (issue.severity === "error") {
|
|
1183
|
-
stats.
|
|
1187
|
+
stats.pendingErrors++;
|
|
1184
1188
|
} else {
|
|
1185
|
-
stats.
|
|
1189
|
+
stats.pendingWarns++;
|
|
1186
1190
|
}
|
|
1187
1191
|
issuesByFile.set(issue.file, stats);
|
|
1188
1192
|
}
|
|
1189
1193
|
const lines = [];
|
|
1190
|
-
lines.push("| 文件 | 🟢 | 🔴 | 🟡 |
|
|
1191
|
-
lines.push("
|
|
1194
|
+
lines.push("| 文件 | 总数 | 🟢 | 🔴 | 🟡 | ⚪ |");
|
|
1195
|
+
lines.push("|------|------|----|----|----|-----|");
|
|
1196
|
+
// 汇总统计
|
|
1197
|
+
let totalAll = 0;
|
|
1198
|
+
let totalFixed = 0;
|
|
1199
|
+
let totalPendingErrors = 0;
|
|
1200
|
+
let totalPendingWarns = 0;
|
|
1201
|
+
let totalResolved = 0;
|
|
1202
|
+
const fileSummaryLines = [];
|
|
1192
1203
|
for (const fileSummary of summaries){
|
|
1193
1204
|
const stats = issuesByFile.get(fileSummary.file) || {
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1205
|
+
fixed: 0,
|
|
1206
|
+
pendingErrors: 0,
|
|
1207
|
+
pendingWarns: 0,
|
|
1208
|
+
resolved: 0
|
|
1197
1209
|
};
|
|
1198
|
-
const
|
|
1199
|
-
|
|
1210
|
+
const fileTotal = stats.fixed + stats.pendingErrors + stats.pendingWarns + stats.resolved;
|
|
1211
|
+
totalAll += fileTotal;
|
|
1212
|
+
totalFixed += stats.fixed;
|
|
1213
|
+
totalPendingErrors += stats.pendingErrors;
|
|
1214
|
+
totalPendingWarns += stats.pendingWarns;
|
|
1215
|
+
totalResolved += stats.resolved;
|
|
1216
|
+
lines.push(`| \`${fileSummary.file}\` | ${fileTotal} | ${stats.fixed} | ${stats.pendingErrors} | ${stats.pendingWarns} | ${stats.resolved} |`);
|
|
1217
|
+
// 收集问题总结用于折叠块展示
|
|
1218
|
+
if (fileSummary.summary.trim()) {
|
|
1219
|
+
fileSummaryLines.push(`### \`${fileSummary.file}\``);
|
|
1220
|
+
fileSummaryLines.push(`${fileSummary.summary.trim()}`);
|
|
1221
|
+
fileSummaryLines.push("");
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
// 添加汇总行
|
|
1225
|
+
if (summaries.length > 1) {
|
|
1226
|
+
lines.push(`| **总计** | **${totalAll}** | **${totalFixed}** | **${totalPendingErrors}** | **${totalPendingWarns}** | **${totalResolved}** |`);
|
|
1227
|
+
}
|
|
1228
|
+
// 问题总结放到折叠块中
|
|
1229
|
+
if (fileSummaryLines.length > 0) {
|
|
1230
|
+
lines.push("");
|
|
1231
|
+
lines.push("<details>");
|
|
1232
|
+
lines.push("<summary>📝 问题总结</summary>\n");
|
|
1233
|
+
lines.push(...fileSummaryLines);
|
|
1234
|
+
lines.push("</details>");
|
|
1200
1235
|
}
|
|
1201
1236
|
return lines.join("\n");
|
|
1202
1237
|
}
|
|
@@ -1310,8 +1345,8 @@ class MarkdownFormatter {
|
|
|
1310
1345
|
`|------|------|`
|
|
1311
1346
|
];
|
|
1312
1347
|
lines.push(`| 总问题数 | ${stats.total} |`);
|
|
1313
|
-
lines.push(`|
|
|
1314
|
-
lines.push(`|
|
|
1348
|
+
lines.push(`| 🟢 已修复 | ${stats.fixed} |`);
|
|
1349
|
+
lines.push(`| ⚪ 已解决 | ${stats.resolved} |`);
|
|
1315
1350
|
lines.push(`| ❌ 无效 | ${stats.invalid} |`);
|
|
1316
1351
|
lines.push(`| ⚠️ 待处理 | ${stats.pending} |`);
|
|
1317
1352
|
lines.push(`| 修复率 | ${stats.fixRate}% |`);
|
|
@@ -1346,36 +1381,58 @@ class TerminalFormatter {
|
|
|
1346
1381
|
if (summaries.length === 0) {
|
|
1347
1382
|
return "没有需要审查的文件";
|
|
1348
1383
|
}
|
|
1384
|
+
// 🟢 已修复 | 🔴 待处理error | 🟡 待处理warn | ⚪ 已解决(非代码修复)
|
|
1349
1385
|
const issuesByFile = new Map();
|
|
1350
1386
|
for (const issue of issues){
|
|
1387
|
+
if (issue.valid === "false") continue;
|
|
1351
1388
|
const stats = issuesByFile.get(issue.file) || {
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1389
|
+
fixed: 0,
|
|
1390
|
+
pendingErrors: 0,
|
|
1391
|
+
pendingWarns: 0,
|
|
1392
|
+
resolved: 0
|
|
1355
1393
|
};
|
|
1356
1394
|
if (issue.fixed) {
|
|
1395
|
+
stats.fixed++;
|
|
1396
|
+
} else if (issue.resolved) {
|
|
1357
1397
|
stats.resolved++;
|
|
1358
1398
|
} else if (issue.severity === "error") {
|
|
1359
|
-
stats.
|
|
1399
|
+
stats.pendingErrors++;
|
|
1360
1400
|
} else {
|
|
1361
|
-
stats.
|
|
1401
|
+
stats.pendingWarns++;
|
|
1362
1402
|
}
|
|
1363
1403
|
issuesByFile.set(issue.file, stats);
|
|
1364
1404
|
}
|
|
1405
|
+
// 汇总统计
|
|
1406
|
+
let totalAll = 0;
|
|
1407
|
+
let totalFixed = 0;
|
|
1408
|
+
let totalPendingErrors = 0;
|
|
1409
|
+
let totalPendingWarns = 0;
|
|
1410
|
+
let totalResolved = 0;
|
|
1365
1411
|
const lines = [];
|
|
1366
1412
|
for (const fileSummary of summaries){
|
|
1367
1413
|
const stats = issuesByFile.get(fileSummary.file) || {
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1414
|
+
fixed: 0,
|
|
1415
|
+
pendingErrors: 0,
|
|
1416
|
+
pendingWarns: 0,
|
|
1417
|
+
resolved: 0
|
|
1371
1418
|
};
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
|
|
1419
|
+
const fileTotal = stats.fixed + stats.pendingErrors + stats.pendingWarns + stats.resolved;
|
|
1420
|
+
totalAll += fileTotal;
|
|
1421
|
+
totalFixed += stats.fixed;
|
|
1422
|
+
totalPendingErrors += stats.pendingErrors;
|
|
1423
|
+
totalPendingWarns += stats.pendingWarns;
|
|
1424
|
+
totalResolved += stats.resolved;
|
|
1425
|
+
const totalText = fileTotal > 0 ? `${BOLD}${fileTotal} 问题${RESET}` : "";
|
|
1426
|
+
const fixedText = stats.fixed > 0 ? `${GREEN}🟢 ${stats.fixed} 已修复${RESET}` : "";
|
|
1427
|
+
const errorText = stats.pendingErrors > 0 ? `${RED}🔴 ${stats.pendingErrors} error${RESET}` : "";
|
|
1428
|
+
const warnText = stats.pendingWarns > 0 ? `${YELLOW}🟡 ${stats.pendingWarns} warn${RESET}` : "";
|
|
1429
|
+
const resolvedText = stats.resolved > 0 ? `⚪ ${stats.resolved} 已解决` : "";
|
|
1375
1430
|
const statsText = [
|
|
1376
|
-
|
|
1431
|
+
totalText,
|
|
1432
|
+
fixedText,
|
|
1377
1433
|
errorText,
|
|
1378
|
-
warnText
|
|
1434
|
+
warnText,
|
|
1435
|
+
resolvedText
|
|
1379
1436
|
].filter(Boolean).join(" / ");
|
|
1380
1437
|
if (statsText) {
|
|
1381
1438
|
lines.push(`${BOLD}${fileSummary.file}${RESET} (${statsText}): ${fileSummary.summary}`);
|
|
@@ -1383,6 +1440,18 @@ class TerminalFormatter {
|
|
|
1383
1440
|
lines.push(`${BOLD}${fileSummary.file}${RESET}: ${fileSummary.summary}`);
|
|
1384
1441
|
}
|
|
1385
1442
|
}
|
|
1443
|
+
// 添加汇总行
|
|
1444
|
+
if (summaries.length > 1) {
|
|
1445
|
+
lines.push("");
|
|
1446
|
+
const summaryParts = [
|
|
1447
|
+
`${BOLD}总计: ${totalAll} 问题${RESET}`
|
|
1448
|
+
];
|
|
1449
|
+
if (totalFixed > 0) summaryParts.push(`${GREEN}🟢 ${totalFixed} 已修复${RESET}`);
|
|
1450
|
+
if (totalPendingErrors > 0) summaryParts.push(`${RED}🔴 ${totalPendingErrors} error${RESET}`);
|
|
1451
|
+
if (totalPendingWarns > 0) summaryParts.push(`${YELLOW}🟡 ${totalPendingWarns} warn${RESET}`);
|
|
1452
|
+
if (totalResolved > 0) summaryParts.push(`⚪ ${totalResolved} 已解决`);
|
|
1453
|
+
lines.push(summaryParts.join(" / "));
|
|
1454
|
+
}
|
|
1386
1455
|
return lines.join("\n");
|
|
1387
1456
|
}
|
|
1388
1457
|
format(result, _options = {}) {
|
|
@@ -1437,8 +1506,8 @@ class TerminalFormatter {
|
|
|
1437
1506
|
`\n${BOLD}${CYAN}📊 ${title}:${RESET}`
|
|
1438
1507
|
];
|
|
1439
1508
|
lines.push(` 总问题数: ${stats.total}`);
|
|
1440
|
-
lines.push(` ${GREEN}
|
|
1441
|
-
lines.push(`
|
|
1509
|
+
lines.push(` ${GREEN}🟢 已修复: ${stats.fixed}${RESET}`);
|
|
1510
|
+
lines.push(` ⚪ 已解决: ${stats.resolved}`);
|
|
1442
1511
|
lines.push(` ${RED}❌ 无效: ${stats.invalid}${RESET}`);
|
|
1443
1512
|
lines.push(` ${YELLOW}⚠️ 待处理: ${stats.pending}${RESET}`);
|
|
1444
1513
|
lines.push(` 修复率: ${stats.fixRate}%`);
|
|
@@ -3705,12 +3774,16 @@ ${fileChanges || "无"}`;
|
|
|
3705
3774
|
/**
|
|
3706
3775
|
* 构建行级评论 Review 的 body(marker + 本轮统计 + 上轮回顾)
|
|
3707
3776
|
*/ buildLineReviewBody(issues, round, allIssues) {
|
|
3708
|
-
|
|
3709
|
-
const
|
|
3777
|
+
// 只统计待处理的问题(未修复且未解决)
|
|
3778
|
+
const pendingIssues = issues.filter((i)=>!i.fixed && !i.resolved && i.valid !== "false");
|
|
3779
|
+
const pendingErrors = pendingIssues.filter((i)=>i.severity === "error").length;
|
|
3780
|
+
const pendingWarns = pendingIssues.filter((i)=>i.severity === "warn").length;
|
|
3710
3781
|
const fileCount = new Set(issues.map((i)=>i.file)).size;
|
|
3782
|
+
const totalPending = pendingErrors + pendingWarns;
|
|
3711
3783
|
const badges = [];
|
|
3712
|
-
if (
|
|
3713
|
-
if (
|
|
3784
|
+
if (totalPending > 0) badges.push(`⚠️ ${totalPending}`);
|
|
3785
|
+
if (pendingErrors > 0) badges.push(`🔴 ${pendingErrors}`);
|
|
3786
|
+
if (pendingWarns > 0) badges.push(`🟡 ${pendingWarns}`);
|
|
3714
3787
|
const parts = [
|
|
3715
3788
|
REVIEW_LINE_COMMENTS_MARKER
|
|
3716
3789
|
];
|
|
@@ -3732,8 +3805,8 @@ ${fileChanges || "无"}`;
|
|
|
3732
3805
|
parts.push(`<details><summary>📊 Round ${round - 1} 回顾 (${prevIssues.length} 个问题)</summary>\n`);
|
|
3733
3806
|
parts.push(`| 状态 | 数量 |`);
|
|
3734
3807
|
parts.push(`|------|------|`);
|
|
3735
|
-
if (prevFixed > 0) parts.push(`|
|
|
3736
|
-
if (prevResolved > 0) parts.push(`|
|
|
3808
|
+
if (prevFixed > 0) parts.push(`| 🟢 已修复 | ${prevFixed} |`);
|
|
3809
|
+
if (prevResolved > 0) parts.push(`| ⚪ 已解决 | ${prevResolved} |`);
|
|
3737
3810
|
if (prevInvalid > 0) parts.push(`| ❌ 无效 | ${prevInvalid} |`);
|
|
3738
3811
|
if (prevPending > 0) parts.push(`| ⚠️ 待处理 | ${prevPending} |`);
|
|
3739
3812
|
parts.push(`\n</details>`);
|
package/package.json
CHANGED
|
@@ -130,35 +130,85 @@ export class MarkdownFormatter implements ReviewReportFormatter, ReviewReportPar
|
|
|
130
130
|
return "没有需要审查的文件";
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
// 🟢 已修复 | 🔴 待处理error | 🟡 待处理warn | ⚪ 已解决(非代码修复)
|
|
134
|
+
const issuesByFile = new Map<
|
|
135
|
+
string,
|
|
136
|
+
{ fixed: number; pendingErrors: number; pendingWarns: number; resolved: number }
|
|
137
|
+
>();
|
|
134
138
|
for (const issue of issues) {
|
|
135
139
|
if (issue.valid === "false") continue;
|
|
136
|
-
const stats = issuesByFile.get(issue.file) || {
|
|
140
|
+
const stats = issuesByFile.get(issue.file) || {
|
|
141
|
+
fixed: 0,
|
|
142
|
+
pendingErrors: 0,
|
|
143
|
+
pendingWarns: 0,
|
|
144
|
+
resolved: 0,
|
|
145
|
+
};
|
|
137
146
|
if (issue.fixed) {
|
|
147
|
+
stats.fixed++;
|
|
148
|
+
} else if (issue.resolved) {
|
|
138
149
|
stats.resolved++;
|
|
139
150
|
} else if (issue.severity === "error") {
|
|
140
|
-
stats.
|
|
151
|
+
stats.pendingErrors++;
|
|
141
152
|
} else {
|
|
142
|
-
stats.
|
|
153
|
+
stats.pendingWarns++;
|
|
143
154
|
}
|
|
144
155
|
issuesByFile.set(issue.file, stats);
|
|
145
156
|
}
|
|
146
157
|
|
|
147
158
|
const lines: string[] = [];
|
|
148
|
-
lines.push("| 文件 | 🟢 | 🔴 | 🟡 |
|
|
149
|
-
lines.push("
|
|
159
|
+
lines.push("| 文件 | 总数 | 🟢 | 🔴 | 🟡 | ⚪ |");
|
|
160
|
+
lines.push("|------|------|----|----|----|-----|");
|
|
161
|
+
|
|
162
|
+
// 汇总统计
|
|
163
|
+
let totalAll = 0;
|
|
164
|
+
let totalFixed = 0;
|
|
165
|
+
let totalPendingErrors = 0;
|
|
166
|
+
let totalPendingWarns = 0;
|
|
167
|
+
let totalResolved = 0;
|
|
150
168
|
|
|
169
|
+
const fileSummaryLines: string[] = [];
|
|
151
170
|
for (const fileSummary of summaries) {
|
|
152
|
-
const stats = issuesByFile.get(fileSummary.file) || {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
171
|
+
const stats = issuesByFile.get(fileSummary.file) || {
|
|
172
|
+
fixed: 0,
|
|
173
|
+
pendingErrors: 0,
|
|
174
|
+
pendingWarns: 0,
|
|
175
|
+
resolved: 0,
|
|
176
|
+
};
|
|
177
|
+
const fileTotal = stats.fixed + stats.pendingErrors + stats.pendingWarns + stats.resolved;
|
|
178
|
+
totalAll += fileTotal;
|
|
179
|
+
totalFixed += stats.fixed;
|
|
180
|
+
totalPendingErrors += stats.pendingErrors;
|
|
181
|
+
totalPendingWarns += stats.pendingWarns;
|
|
182
|
+
totalResolved += stats.resolved;
|
|
183
|
+
|
|
184
|
+
lines.push(
|
|
185
|
+
`| \`${fileSummary.file}\` | ${fileTotal} | ${stats.fixed} | ${stats.pendingErrors} | ${stats.pendingWarns} | ${stats.resolved} |`,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// 收集问题总结用于折叠块展示
|
|
189
|
+
if (fileSummary.summary.trim()) {
|
|
190
|
+
fileSummaryLines.push(`### \`${fileSummary.file}\``);
|
|
191
|
+
fileSummaryLines.push(`${fileSummary.summary.trim()}`);
|
|
192
|
+
fileSummaryLines.push("");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 添加汇总行
|
|
197
|
+
if (summaries.length > 1) {
|
|
157
198
|
lines.push(
|
|
158
|
-
`|
|
|
199
|
+
`| **总计** | **${totalAll}** | **${totalFixed}** | **${totalPendingErrors}** | **${totalPendingWarns}** | **${totalResolved}** |`,
|
|
159
200
|
);
|
|
160
201
|
}
|
|
161
202
|
|
|
203
|
+
// 问题总结放到折叠块中
|
|
204
|
+
if (fileSummaryLines.length > 0) {
|
|
205
|
+
lines.push("");
|
|
206
|
+
lines.push("<details>");
|
|
207
|
+
lines.push("<summary>📝 问题总结</summary>\n");
|
|
208
|
+
lines.push(...fileSummaryLines);
|
|
209
|
+
lines.push("</details>");
|
|
210
|
+
}
|
|
211
|
+
|
|
162
212
|
return lines.join("\n");
|
|
163
213
|
}
|
|
164
214
|
|
|
@@ -289,8 +339,8 @@ export class MarkdownFormatter implements ReviewReportFormatter, ReviewReportPar
|
|
|
289
339
|
const title = prNumber ? `PR #${prNumber} Review 状态统计` : "Review 状态统计";
|
|
290
340
|
const lines = [`## 📊 ${title}\n`, `| 指标 | 数量 |`, `|------|------|`];
|
|
291
341
|
lines.push(`| 总问题数 | ${stats.total} |`);
|
|
292
|
-
lines.push(`|
|
|
293
|
-
lines.push(`|
|
|
342
|
+
lines.push(`| 🟢 已修复 | ${stats.fixed} |`);
|
|
343
|
+
lines.push(`| ⚪ 已解决 | ${stats.resolved} |`);
|
|
294
344
|
lines.push(`| ❌ 无效 | ${stats.invalid} |`);
|
|
295
345
|
lines.push(`| ⚠️ 待处理 | ${stats.pending} |`);
|
|
296
346
|
lines.push(`| 修复率 | ${stats.fixRate}% |`);
|
|
@@ -28,26 +28,63 @@ export class TerminalFormatter implements ReviewReportFormatter {
|
|
|
28
28
|
return "没有需要审查的文件";
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// 🟢 已修复 | 🔴 待处理error | 🟡 待处理warn | ⚪ 已解决(非代码修复)
|
|
32
|
+
const issuesByFile = new Map<
|
|
33
|
+
string,
|
|
34
|
+
{ fixed: number; pendingErrors: number; pendingWarns: number; resolved: number }
|
|
35
|
+
>();
|
|
32
36
|
for (const issue of issues) {
|
|
33
|
-
|
|
37
|
+
if (issue.valid === "false") continue;
|
|
38
|
+
const stats = issuesByFile.get(issue.file) || {
|
|
39
|
+
fixed: 0,
|
|
40
|
+
pendingErrors: 0,
|
|
41
|
+
pendingWarns: 0,
|
|
42
|
+
resolved: 0,
|
|
43
|
+
};
|
|
34
44
|
if (issue.fixed) {
|
|
45
|
+
stats.fixed++;
|
|
46
|
+
} else if (issue.resolved) {
|
|
35
47
|
stats.resolved++;
|
|
36
48
|
} else if (issue.severity === "error") {
|
|
37
|
-
stats.
|
|
49
|
+
stats.pendingErrors++;
|
|
38
50
|
} else {
|
|
39
|
-
stats.
|
|
51
|
+
stats.pendingWarns++;
|
|
40
52
|
}
|
|
41
53
|
issuesByFile.set(issue.file, stats);
|
|
42
54
|
}
|
|
43
55
|
|
|
56
|
+
// 汇总统计
|
|
57
|
+
let totalAll = 0;
|
|
58
|
+
let totalFixed = 0;
|
|
59
|
+
let totalPendingErrors = 0;
|
|
60
|
+
let totalPendingWarns = 0;
|
|
61
|
+
let totalResolved = 0;
|
|
62
|
+
|
|
44
63
|
const lines: string[] = [];
|
|
45
64
|
for (const fileSummary of summaries) {
|
|
46
|
-
const stats = issuesByFile.get(fileSummary.file) || {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
const stats = issuesByFile.get(fileSummary.file) || {
|
|
66
|
+
fixed: 0,
|
|
67
|
+
pendingErrors: 0,
|
|
68
|
+
pendingWarns: 0,
|
|
69
|
+
resolved: 0,
|
|
70
|
+
};
|
|
71
|
+
const fileTotal = stats.fixed + stats.pendingErrors + stats.pendingWarns + stats.resolved;
|
|
72
|
+
totalAll += fileTotal;
|
|
73
|
+
totalFixed += stats.fixed;
|
|
74
|
+
totalPendingErrors += stats.pendingErrors;
|
|
75
|
+
totalPendingWarns += stats.pendingWarns;
|
|
76
|
+
totalResolved += stats.resolved;
|
|
77
|
+
|
|
78
|
+
const totalText = fileTotal > 0 ? `${BOLD}${fileTotal} 问题${RESET}` : "";
|
|
79
|
+
const fixedText = stats.fixed > 0 ? `${GREEN}🟢 ${stats.fixed} 已修复${RESET}` : "";
|
|
80
|
+
const errorText =
|
|
81
|
+
stats.pendingErrors > 0 ? `${RED}🔴 ${stats.pendingErrors} error${RESET}` : "";
|
|
82
|
+
const warnText =
|
|
83
|
+
stats.pendingWarns > 0 ? `${YELLOW}🟡 ${stats.pendingWarns} warn${RESET}` : "";
|
|
84
|
+
const resolvedText = stats.resolved > 0 ? `⚪ ${stats.resolved} 已解决` : "";
|
|
85
|
+
const statsText = [totalText, fixedText, errorText, warnText, resolvedText]
|
|
86
|
+
.filter(Boolean)
|
|
87
|
+
.join(" / ");
|
|
51
88
|
|
|
52
89
|
if (statsText) {
|
|
53
90
|
lines.push(`${BOLD}${fileSummary.file}${RESET} (${statsText}): ${fileSummary.summary}`);
|
|
@@ -56,6 +93,17 @@ export class TerminalFormatter implements ReviewReportFormatter {
|
|
|
56
93
|
}
|
|
57
94
|
}
|
|
58
95
|
|
|
96
|
+
// 添加汇总行
|
|
97
|
+
if (summaries.length > 1) {
|
|
98
|
+
lines.push("");
|
|
99
|
+
const summaryParts = [`${BOLD}总计: ${totalAll} 问题${RESET}`];
|
|
100
|
+
if (totalFixed > 0) summaryParts.push(`${GREEN}🟢 ${totalFixed} 已修复${RESET}`);
|
|
101
|
+
if (totalPendingErrors > 0) summaryParts.push(`${RED}🔴 ${totalPendingErrors} error${RESET}`);
|
|
102
|
+
if (totalPendingWarns > 0) summaryParts.push(`${YELLOW}🟡 ${totalPendingWarns} warn${RESET}`);
|
|
103
|
+
if (totalResolved > 0) summaryParts.push(`⚪ ${totalResolved} 已解决`);
|
|
104
|
+
lines.push(summaryParts.join(" / "));
|
|
105
|
+
}
|
|
106
|
+
|
|
59
107
|
return lines.join("\n");
|
|
60
108
|
}
|
|
61
109
|
|
|
@@ -123,8 +171,8 @@ export class TerminalFormatter implements ReviewReportFormatter {
|
|
|
123
171
|
const title = prNumber ? `PR #${prNumber} Review 状态统计` : "Review 状态统计";
|
|
124
172
|
const lines = [`\n${BOLD}${CYAN}📊 ${title}:${RESET}`];
|
|
125
173
|
lines.push(` 总问题数: ${stats.total}`);
|
|
126
|
-
lines.push(` ${GREEN}
|
|
127
|
-
lines.push(`
|
|
174
|
+
lines.push(` ${GREEN}🟢 已修复: ${stats.fixed}${RESET}`);
|
|
175
|
+
lines.push(` ⚪ 已解决: ${stats.resolved}`);
|
|
128
176
|
lines.push(` ${RED}❌ 无效: ${stats.invalid}${RESET}`);
|
|
129
177
|
lines.push(` ${YELLOW}⚠️ 待处理: ${stats.pending}${RESET}`);
|
|
130
178
|
lines.push(` 修复率: ${stats.fixRate}%`);
|
package/src/review.service.ts
CHANGED
|
@@ -2506,13 +2506,17 @@ ${fileChanges || "无"}`;
|
|
|
2506
2506
|
round: number,
|
|
2507
2507
|
allIssues: ReviewIssue[],
|
|
2508
2508
|
): string {
|
|
2509
|
-
|
|
2510
|
-
const
|
|
2509
|
+
// 只统计待处理的问题(未修复且未解决)
|
|
2510
|
+
const pendingIssues = issues.filter((i) => !i.fixed && !i.resolved && i.valid !== "false");
|
|
2511
|
+
const pendingErrors = pendingIssues.filter((i) => i.severity === "error").length;
|
|
2512
|
+
const pendingWarns = pendingIssues.filter((i) => i.severity === "warn").length;
|
|
2511
2513
|
const fileCount = new Set(issues.map((i) => i.file)).size;
|
|
2512
2514
|
|
|
2515
|
+
const totalPending = pendingErrors + pendingWarns;
|
|
2513
2516
|
const badges: string[] = [];
|
|
2514
|
-
if (
|
|
2515
|
-
if (
|
|
2517
|
+
if (totalPending > 0) badges.push(`⚠️ ${totalPending}`);
|
|
2518
|
+
if (pendingErrors > 0) badges.push(`🔴 ${pendingErrors}`);
|
|
2519
|
+
if (pendingWarns > 0) badges.push(`🟡 ${pendingWarns}`);
|
|
2516
2520
|
|
|
2517
2521
|
const parts: string[] = [REVIEW_LINE_COMMENTS_MARKER];
|
|
2518
2522
|
parts.push(`### 🚀 Spaceflow Review · Round ${round}`);
|
|
@@ -2540,8 +2544,8 @@ ${fileChanges || "无"}`;
|
|
|
2540
2544
|
);
|
|
2541
2545
|
parts.push(`| 状态 | 数量 |`);
|
|
2542
2546
|
parts.push(`|------|------|`);
|
|
2543
|
-
if (prevFixed > 0) parts.push(`|
|
|
2544
|
-
if (prevResolved > 0) parts.push(`|
|
|
2547
|
+
if (prevFixed > 0) parts.push(`| 🟢 已修复 | ${prevFixed} |`);
|
|
2548
|
+
if (prevResolved > 0) parts.push(`| ⚪ 已解决 | ${prevResolved} |`);
|
|
2545
2549
|
if (prevInvalid > 0) parts.push(`| ❌ 无效 | ${prevInvalid} |`);
|
|
2546
2550
|
if (prevPending > 0) parts.push(`| ⚠️ 待处理 | ${prevPending} |`);
|
|
2547
2551
|
parts.push(`\n</details>`);
|