@spaceflow/review 0.59.0 → 0.61.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 +50 -0
- package/dist/index.js +11 -9
- package/package.json +2 -2
- package/src/issue-verify.service.ts +2 -2
- package/src/review.service.ts +23 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.60.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.59.0...@spaceflow/review@0.60.0) (2026-03-02)
|
|
4
|
+
|
|
5
|
+
### 代码重构
|
|
6
|
+
|
|
7
|
+
* **review:** 优化问题验证逻辑,将 resolved 状态纳入有效性判断 ([1e2302d](https://github.com/Lydanne/spaceflow/commit/1e2302d81cd0f653d606483ef6c9138143ca6d60))
|
|
8
|
+
|
|
9
|
+
### 代码格式
|
|
10
|
+
|
|
11
|
+
* 格式化代码并更新 Prettier 忽略规则 ([baed10e](https://github.com/Lydanne/spaceflow/commit/baed10e7cd91fda1285d7e2e0019d291cb563055))
|
|
12
|
+
|
|
13
|
+
### 其他修改
|
|
14
|
+
|
|
15
|
+
* **core:** released version 0.23.0 [no ci] ([07a2d7d](https://github.com/Lydanne/spaceflow/commit/07a2d7d51223aeb98161f91fa931b4cb63b03cda))
|
|
16
|
+
* **publish:** released version 0.47.0 [no ci] ([3f59345](https://github.com/Lydanne/spaceflow/commit/3f593450066c9138adac5b101edb8057a5de1ff6))
|
|
17
|
+
* **review-summary:** released version 0.27.0 [no ci] ([90ac2a4](https://github.com/Lydanne/spaceflow/commit/90ac2a44706ddb2dd231ea57d3734c7445565ee9))
|
|
18
|
+
* **scripts:** released version 0.24.0 [no ci] ([717de65](https://github.com/Lydanne/spaceflow/commit/717de6571faa2cb24f04b7493e7fd6d8404f2bd5))
|
|
19
|
+
* **shell:** released version 0.24.0 [no ci] ([5694d19](https://github.com/Lydanne/spaceflow/commit/5694d193f9207e41e840d9ebaa5a43e3527e6af8))
|
|
20
|
+
|
|
21
|
+
## [0.59.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.58.0...@spaceflow/review@0.59.0) (2026-03-02)
|
|
22
|
+
|
|
23
|
+
### 新特性
|
|
24
|
+
|
|
25
|
+
* **review-summary:** 实现 review-summary 命令核心功能 ([5964eec](https://github.com/Lydanne/spaceflow/commit/5964eec0e2ee4ac46f74808466429b0edc0cbaa1))
|
|
26
|
+
* **review-summary:** 新增文件过滤功能并优化缺陷率计算 ([9655f82](https://github.com/Lydanne/spaceflow/commit/9655f828cec77c4a7db29ae1cda59fd3ea10ceab))
|
|
27
|
+
|
|
28
|
+
### 修复BUG
|
|
29
|
+
|
|
30
|
+
* **actions:** 修正 GitHub Actions 路径并优化命令行选项 ([50a9946](https://github.com/Lydanne/spaceflow/commit/50a99464633afe234ef56d4a081c6d04686b3e57))
|
|
31
|
+
|
|
32
|
+
### 代码重构
|
|
33
|
+
|
|
34
|
+
* **core:** 统一插件配置中的 'extensions' 为 'skills' ([50646a0](https://github.com/Lydanne/spaceflow/commit/50646a061f66ec6935c66199d78915b9d7896bd3))
|
|
35
|
+
|
|
36
|
+
### 文档更新
|
|
37
|
+
|
|
38
|
+
* **docs:** 统一扩展类型命名:extension 改为 skill ([96db479](https://github.com/Lydanne/spaceflow/commit/96db47948981c0c2b5860c2835f86dec77736cf0))
|
|
39
|
+
* 更新 MCP 架构为 Meta-tool 代理模式并统一导出类型命名 ([f60c53b](https://github.com/Lydanne/spaceflow/commit/f60c53b103f24e8a4123e4c4ec850885cb40f7d7))
|
|
40
|
+
* 简化 MCP 工具声明方式并完善扩展系统文档 ([9cdcab9](https://github.com/Lydanne/spaceflow/commit/9cdcab986559bd34c75e48b6c380c74516adb05c))
|
|
41
|
+
|
|
42
|
+
### 其他修改
|
|
43
|
+
|
|
44
|
+
* **core:** released version 0.22.0 [no ci] ([68aa47d](https://github.com/Lydanne/spaceflow/commit/68aa47df425eb9d1ceac1237fee3cc1b29de668f))
|
|
45
|
+
* **publish:** released version 0.46.0 [no ci] ([68ebfc3](https://github.com/Lydanne/spaceflow/commit/68ebfc32bfb5b39354947f08b73306b5f8512fdf))
|
|
46
|
+
* **review-summary:** released version 0.23.0 [no ci] ([f6681ec](https://github.com/Lydanne/spaceflow/commit/f6681ecdcd8f8036da3c4ac7778e5cc75af59c9f))
|
|
47
|
+
* **review-summary:** released version 0.24.0 [no ci] ([690e9ed](https://github.com/Lydanne/spaceflow/commit/690e9ed64b197f50e201afe73dc55e866867a7fd))
|
|
48
|
+
* **review-summary:** released version 0.25.0 [no ci] ([4eaca03](https://github.com/Lydanne/spaceflow/commit/4eaca0397411585112697e6800b66484bd73ffde))
|
|
49
|
+
* **review-summary:** released version 0.26.0 [no ci] ([5e8dedf](https://github.com/Lydanne/spaceflow/commit/5e8dedf10cb7104dcc15550d7f5ba05f10cae7d3))
|
|
50
|
+
* **scripts:** released version 0.23.0 [no ci] ([2f18d22](https://github.com/Lydanne/spaceflow/commit/2f18d2274e83b65ce006dceed47a985942c8dd1d))
|
|
51
|
+
* **shell:** released version 0.23.0 [no ci] ([0668aa9](https://github.com/Lydanne/spaceflow/commit/0668aa97671ca235509bef547503c301237324f9))
|
|
52
|
+
|
|
3
53
|
## [0.58.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.57.0...@spaceflow/review@0.58.0) (2026-03-02)
|
|
4
54
|
|
|
5
55
|
### 新特性
|
package/dist/index.js
CHANGED
|
@@ -2242,6 +2242,8 @@ class ReviewService {
|
|
|
2242
2242
|
if (shouldLog(verbose, 1)) {
|
|
2243
2243
|
console.log(`📋 已有评论中存在 ${existingIssues.length} 个问题`);
|
|
2244
2244
|
}
|
|
2245
|
+
// 先同步最新的 resolved 状态,确保后续 invalidate/verify 能正确跳过已解决的问题
|
|
2246
|
+
await this.syncResolvedComments(owner, repo, prNumber, existingResult);
|
|
2245
2247
|
// 如果文件有变更,将该文件的历史问题标记为无效
|
|
2246
2248
|
// 简化策略:避免复杂的行号更新逻辑
|
|
2247
2249
|
const reviewConf = this.config.getPluginConfig("review");
|
|
@@ -2451,7 +2453,7 @@ class ReviewService {
|
|
|
2451
2453
|
const total = issues.length;
|
|
2452
2454
|
const fixed = issues.filter((i)=>i.fixed).length;
|
|
2453
2455
|
const resolved = issues.filter((i)=>i.resolved && !i.fixed).length;
|
|
2454
|
-
const invalid = issues.filter((i)=>i.valid === "false").length;
|
|
2456
|
+
const invalid = issues.filter((i)=>i.valid === "false" && !i.fixed && !i.resolved).length;
|
|
2455
2457
|
const pending = total - fixed - resolved - invalid;
|
|
2456
2458
|
const fixRate = total > 0 ? Math.round(fixed / total * 100 * 10) / 10 : 0;
|
|
2457
2459
|
const resolveRate = total > 0 ? Math.round((fixed + resolved) / total * 100 * 10) / 10 : 0;
|
|
@@ -3267,7 +3269,7 @@ ${fileChanges || "无"}`;
|
|
|
3267
3269
|
console.warn("⚠️ 更新 PR 标题失败:", error);
|
|
3268
3270
|
}
|
|
3269
3271
|
}
|
|
3270
|
-
// 获取已解决的评论,同步
|
|
3272
|
+
// 获取已解决的评论,同步 resolve 状态(在更新 review 之前)
|
|
3271
3273
|
await this.syncResolvedComments(owner, repo, prNumber, result);
|
|
3272
3274
|
// 获取评论的 reactions,同步 valid 状态(👎 标记为无效)
|
|
3273
3275
|
await this.syncReactionsToIssues(owner, repo, prNumber, result, verbose);
|
|
@@ -3724,7 +3726,7 @@ ${fileChanges || "无"}`;
|
|
|
3724
3726
|
if (prevIssues.length > 0) {
|
|
3725
3727
|
const prevFixed = prevIssues.filter((i)=>i.fixed).length;
|
|
3726
3728
|
const prevResolved = prevIssues.filter((i)=>i.resolved && !i.fixed).length;
|
|
3727
|
-
const prevInvalid = prevIssues.filter((i)=>i.valid === "false").length;
|
|
3729
|
+
const prevInvalid = prevIssues.filter((i)=>i.valid === "false" && !i.fixed && !i.resolved).length;
|
|
3728
3730
|
const prevPending = prevIssues.length - prevFixed - prevResolved - prevInvalid;
|
|
3729
3731
|
parts.push("");
|
|
3730
3732
|
parts.push(`<details><summary>📊 Round ${round - 1} 回顾 (${prevIssues.length} 个问题)</summary>\n`);
|
|
@@ -3822,8 +3824,8 @@ ${fileChanges || "无"}`;
|
|
|
3822
3824
|
// 将变更文件的历史 issue 标记为无效
|
|
3823
3825
|
let invalidatedCount = 0;
|
|
3824
3826
|
const updatedIssues = issues.map((issue)=>{
|
|
3825
|
-
// 如果 issue
|
|
3826
|
-
if (issue.fixed || issue.valid === "false") {
|
|
3827
|
+
// 如果 issue 已修复、已解决或已无效,不需要处理
|
|
3828
|
+
if (issue.fixed || issue.resolved || issue.valid === "false") {
|
|
3827
3829
|
return issue;
|
|
3828
3830
|
}
|
|
3829
3831
|
// 如果 issue 所在文件有变更,标记为无效
|
|
@@ -3863,8 +3865,8 @@ ${fileChanges || "无"}`;
|
|
|
3863
3865
|
let updatedCount = 0;
|
|
3864
3866
|
let invalidatedCount = 0;
|
|
3865
3867
|
const updatedIssues = issues.map((issue)=>{
|
|
3866
|
-
// 如果 issue
|
|
3867
|
-
if (issue.fixed || issue.valid === "false") {
|
|
3868
|
+
// 如果 issue 已修复、已解决或无效,不需要更新行号
|
|
3869
|
+
if (issue.fixed || issue.resolved || issue.valid === "false") {
|
|
3868
3870
|
return issue;
|
|
3869
3871
|
}
|
|
3870
3872
|
const patch = filePatchMap.get(issue.file);
|
|
@@ -4123,7 +4125,7 @@ class IssueVerifyService {
|
|
|
4123
4125
|
continue;
|
|
4124
4126
|
}
|
|
4125
4127
|
// valid === 'false' 的问题跳过复查(已确认无效的问题无需再次验证)
|
|
4126
|
-
if (issue.valid ===
|
|
4128
|
+
if (issue.valid === FALSE) {
|
|
4127
4129
|
if (shouldLog(verbose, 1)) {
|
|
4128
4130
|
console.log(` ⏭️ 跳过无效问题: ${issue.file}:${issue.line} (${issue.ruleId})`);
|
|
4129
4131
|
}
|
|
@@ -4213,7 +4215,7 @@ class IssueVerifyService {
|
|
|
4213
4215
|
if (result) {
|
|
4214
4216
|
const updatedIssue = {
|
|
4215
4217
|
...issue,
|
|
4216
|
-
valid: result.valid ? TRUE : FALSE
|
|
4218
|
+
valid: issue.fixed || issue.resolved ? TRUE : result.valid ? TRUE : FALSE
|
|
4217
4219
|
};
|
|
4218
4220
|
if (result.fixed) {
|
|
4219
4221
|
if (shouldLog(verbose, 1)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spaceflow/review",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0",
|
|
4
4
|
"description": "Spaceflow 代码审查插件,使用 LLM 对 PR 代码进行自动审查",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lydanne",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@spaceflow/cli": "0.38.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@spaceflow/core": "0.
|
|
31
|
+
"@spaceflow/core": "0.23.0"
|
|
32
32
|
},
|
|
33
33
|
"spaceflow": {
|
|
34
34
|
"type": "flow",
|
|
@@ -92,7 +92,7 @@ export class IssueVerifyService {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// valid === 'false' 的问题跳过复查(已确认无效的问题无需再次验证)
|
|
95
|
-
if (issue.valid ===
|
|
95
|
+
if (issue.valid === FALSE) {
|
|
96
96
|
if (shouldLog(verbose, 1)) {
|
|
97
97
|
console.log(` ⏭️ 跳过无效问题: ${issue.file}:${issue.line} (${issue.ruleId})`);
|
|
98
98
|
}
|
|
@@ -201,7 +201,7 @@ export class IssueVerifyService {
|
|
|
201
201
|
if (result) {
|
|
202
202
|
const updatedIssue: ReviewIssue = {
|
|
203
203
|
...issue,
|
|
204
|
-
valid: result.valid ? TRUE : FALSE,
|
|
204
|
+
valid: issue.fixed || issue.resolved ? TRUE : result.valid ? TRUE : FALSE,
|
|
205
205
|
};
|
|
206
206
|
|
|
207
207
|
if (result.fixed) {
|
package/src/review.service.ts
CHANGED
|
@@ -678,6 +678,9 @@ export class ReviewService {
|
|
|
678
678
|
console.log(`📋 已有评论中存在 ${existingIssues.length} 个问题`);
|
|
679
679
|
}
|
|
680
680
|
|
|
681
|
+
// 先同步最新的 resolved 状态,确保后续 invalidate/verify 能正确跳过已解决的问题
|
|
682
|
+
await this.syncResolvedComments(owner, repo, prNumber, existingResult);
|
|
683
|
+
|
|
681
684
|
// 如果文件有变更,将该文件的历史问题标记为无效
|
|
682
685
|
// 简化策略:避免复杂的行号更新逻辑
|
|
683
686
|
const reviewConf = this.config.getPluginConfig<ReviewConfig>("review");
|
|
@@ -696,12 +699,10 @@ export class ReviewService {
|
|
|
696
699
|
|
|
697
700
|
// 验证历史问题是否已修复
|
|
698
701
|
if (context.verifyFixes) {
|
|
699
|
-
existingIssues = await this.verifyAndUpdateIssues(
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
{ specs, fileContents },
|
|
704
|
-
);
|
|
702
|
+
existingIssues = await this.verifyAndUpdateIssues(context, existingIssues, commits, {
|
|
703
|
+
specs,
|
|
704
|
+
fileContents,
|
|
705
|
+
});
|
|
705
706
|
} else {
|
|
706
707
|
if (shouldLog(verbose, 1)) {
|
|
707
708
|
console.log(` ⏭️ 跳过历史问题验证 (verifyFixes=false)`);
|
|
@@ -917,9 +918,7 @@ export class ReviewService {
|
|
|
917
918
|
preloaded?: { specs: ReviewSpec[]; fileContents: FileContentsMap },
|
|
918
919
|
): Promise<ReviewIssue[]> {
|
|
919
920
|
const { owner, repo, prNumber, llmMode, specSources, verbose } = context;
|
|
920
|
-
const unfixedIssues = issues.filter(
|
|
921
|
-
(i) => i.valid !== "false" && !i.fixed,
|
|
922
|
-
);
|
|
921
|
+
const unfixedIssues = issues.filter((i) => i.valid !== "false" && !i.fixed);
|
|
923
922
|
|
|
924
923
|
if (unfixedIssues.length === 0) {
|
|
925
924
|
return issues;
|
|
@@ -982,7 +981,7 @@ export class ReviewService {
|
|
|
982
981
|
const total = issues.length;
|
|
983
982
|
const fixed = issues.filter((i) => i.fixed).length;
|
|
984
983
|
const resolved = issues.filter((i) => i.resolved && !i.fixed).length;
|
|
985
|
-
const invalid = issues.filter((i) => i.valid === "false").length;
|
|
984
|
+
const invalid = issues.filter((i) => i.valid === "false" && !i.fixed && !i.resolved).length;
|
|
986
985
|
const pending = total - fixed - resolved - invalid;
|
|
987
986
|
const fixRate = total > 0 ? Math.round((fixed / total) * 100 * 10) / 10 : 0;
|
|
988
987
|
const resolveRate = total > 0 ? Math.round(((fixed + resolved) / total) * 100 * 10) / 10 : 0;
|
|
@@ -1957,7 +1956,7 @@ ${fileChanges || "无"}`;
|
|
|
1957
1956
|
}
|
|
1958
1957
|
}
|
|
1959
1958
|
|
|
1960
|
-
// 获取已解决的评论,同步
|
|
1959
|
+
// 获取已解决的评论,同步 resolve 状态(在更新 review 之前)
|
|
1961
1960
|
await this.syncResolvedComments(owner, repo, prNumber, result);
|
|
1962
1961
|
|
|
1963
1962
|
// 获取评论的 reactions,同步 valid 状态(👎 标记为无效)
|
|
@@ -2520,7 +2519,9 @@ ${fileChanges || "无"}`;
|
|
|
2520
2519
|
if (issues.length === 0) {
|
|
2521
2520
|
parts.push(`> ✅ 未发现新问题`);
|
|
2522
2521
|
} else {
|
|
2523
|
-
parts.push(
|
|
2522
|
+
parts.push(
|
|
2523
|
+
`> **${issues.length}** 个新问题 · **${fileCount}** 个文件${badges.length > 0 ? " · " + badges.join(" ") : ""}`,
|
|
2524
|
+
);
|
|
2524
2525
|
}
|
|
2525
2526
|
|
|
2526
2527
|
// 上轮回顾
|
|
@@ -2529,10 +2530,14 @@ ${fileChanges || "无"}`;
|
|
|
2529
2530
|
if (prevIssues.length > 0) {
|
|
2530
2531
|
const prevFixed = prevIssues.filter((i) => i.fixed).length;
|
|
2531
2532
|
const prevResolved = prevIssues.filter((i) => i.resolved && !i.fixed).length;
|
|
2532
|
-
const prevInvalid = prevIssues.filter(
|
|
2533
|
+
const prevInvalid = prevIssues.filter(
|
|
2534
|
+
(i) => i.valid === "false" && !i.fixed && !i.resolved,
|
|
2535
|
+
).length;
|
|
2533
2536
|
const prevPending = prevIssues.length - prevFixed - prevResolved - prevInvalid;
|
|
2534
2537
|
parts.push("");
|
|
2535
|
-
parts.push(
|
|
2538
|
+
parts.push(
|
|
2539
|
+
`<details><summary>📊 Round ${round - 1} 回顾 (${prevIssues.length} 个问题)</summary>\n`,
|
|
2540
|
+
);
|
|
2536
2541
|
parts.push(`| 状态 | 数量 |`);
|
|
2537
2542
|
parts.push(`|------|------|`);
|
|
2538
2543
|
if (prevFixed > 0) parts.push(`| ✅ 已修复 | ${prevFixed} |`);
|
|
@@ -2644,8 +2649,8 @@ ${fileChanges || "无"}`;
|
|
|
2644
2649
|
// 将变更文件的历史 issue 标记为无效
|
|
2645
2650
|
let invalidatedCount = 0;
|
|
2646
2651
|
const updatedIssues = issues.map((issue) => {
|
|
2647
|
-
// 如果 issue
|
|
2648
|
-
if (issue.fixed || issue.valid === "false") {
|
|
2652
|
+
// 如果 issue 已修复、已解决或已无效,不需要处理
|
|
2653
|
+
if (issue.fixed || issue.resolved || issue.valid === "false") {
|
|
2649
2654
|
return issue;
|
|
2650
2655
|
}
|
|
2651
2656
|
|
|
@@ -2691,8 +2696,8 @@ ${fileChanges || "无"}`;
|
|
|
2691
2696
|
let updatedCount = 0;
|
|
2692
2697
|
let invalidatedCount = 0;
|
|
2693
2698
|
const updatedIssues = issues.map((issue) => {
|
|
2694
|
-
// 如果 issue
|
|
2695
|
-
if (issue.fixed || issue.valid === "false") {
|
|
2699
|
+
// 如果 issue 已修复、已解决或无效,不需要更新行号
|
|
2700
|
+
if (issue.fixed || issue.resolved || issue.valid === "false") {
|
|
2696
2701
|
return issue;
|
|
2697
2702
|
}
|
|
2698
2703
|
|