@spaceflow/review 5.0.1 → 5.0.2

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,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.0.1](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@5.0.0...@spaceflow/review@5.0.1) (2026-04-14)
4
+
5
+ ### 修复BUG
6
+
7
+ * **review:** 修正已解决问题统计逻辑,避免与已修复问题重复计数 ([6d191bb](https://github.com/Lydanne/spaceflow/commit/6d191bbd71b8ce6194ce56a8d008dd966173541b))
8
+
9
+ ### 代码重构
10
+
11
+ * **shared:** 移除 Claude Code 相关配置和文档,统一使用 OpenAI/Gemini/OpenCode ([b0754d6](https://github.com/Lydanne/spaceflow/commit/b0754d64f8991a10708730c191cf0f335e8aa6ca))
12
+
13
+ ### 其他修改
14
+
15
+ * **cli:** released version 5.0.1 [no ci] ([f3009ea](https://github.com/Lydanne/spaceflow/commit/f3009eaaf26759d708541f54e707882b4927ebbd))
16
+ * **core:** released version 5.0.1 [no ci] ([7904b9b](https://github.com/Lydanne/spaceflow/commit/7904b9bbc619c91a3a4fa1c8ea04d9dc548495ad))
17
+ * **core:** 移除 @anthropic-ai/claude-agent-sdk 依赖及相关 sharp 图像处理包 ([7b50e06](https://github.com/Lydanne/spaceflow/commit/7b50e066df97d408eb63707eb27273592a28d34d))
18
+ * **publish:** released version 5.0.1 [no ci] ([b14849f](https://github.com/Lydanne/spaceflow/commit/b14849ffafd38f230a3e69c2d63c468cb1946388))
19
+ * **shared:** released version 5.0.1 [no ci] ([f70cd93](https://github.com/Lydanne/spaceflow/commit/f70cd930b01ffa09187f66522c8d6b18f835ec53))
20
+
3
21
  ## [4.0.1](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@4.0.0...@spaceflow/review@4.0.1) (2026-04-13)
4
22
 
5
23
  ### 新特性
package/dist/index.js CHANGED
@@ -2254,7 +2254,7 @@ function generateIssueKey(issue) {
2254
2254
  const fixed = validIssue.filter((i)=>i.fixed).length;
2255
2255
  const resolved = validIssue.filter((i)=>i.resolved).length;
2256
2256
  const invalid = total - validTotal;
2257
- const pending = validTotal - fixed - resolved;
2257
+ const pending = validTotal - validIssue.filter((i)=>i.fixed || i.resolved).length;
2258
2258
  const fixRate = validTotal > 0 ? Math.round(fixed / validTotal * 100 * 10) / 10 : 0;
2259
2259
  const resolveRate = validTotal > 0 ? Math.round(resolved / validTotal * 100 * 10) / 10 : 0;
2260
2260
  return {
@@ -3131,10 +3131,7 @@ function generateIssueKey(issue) {
3131
3131
  if (round > 1) {
3132
3132
  const prevIssues = allIssues.filter((i)=>i.round === round - 1);
3133
3133
  if (prevIssues.length > 0) {
3134
- const prevFixed = prevIssues.filter((i)=>i.fixed).length;
3135
- const prevResolved = prevIssues.filter((i)=>i.resolved && !i.fixed).length;
3136
- const prevInvalid = prevIssues.filter((i)=>i.valid === "false" && !i.fixed && !i.resolved).length;
3137
- const prevPending = prevIssues.length - prevFixed - prevResolved - prevInvalid;
3134
+ const { fixed: prevFixed, resolved: prevResolved, invalid: prevInvalid, pending: prevPending } = calculateIssueStats(prevIssues);
3138
3135
  parts.push("");
3139
3136
  parts.push(`<details><summary>📊 Round ${round - 1} 回顾 (${prevIssues.length} 个问题)</summary>\n`);
3140
3137
  parts.push(`| 状态 | 数量 |`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaceflow/review",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "Spaceflow 代码审查插件,使用 LLM 对 PR 代码进行自动审查",
5
5
  "license": "MIT",
6
6
  "author": "Lydanne",
@@ -1069,12 +1069,12 @@ export class ReviewResultModel {
1069
1069
  if (round > 1) {
1070
1070
  const prevIssues = allIssues.filter((i) => i.round === round - 1);
1071
1071
  if (prevIssues.length > 0) {
1072
- const prevFixed = prevIssues.filter((i) => i.fixed).length;
1073
- const prevResolved = prevIssues.filter((i) => i.resolved && !i.fixed).length;
1074
- const prevInvalid = prevIssues.filter(
1075
- (i) => i.valid === "false" && !i.fixed && !i.resolved,
1076
- ).length;
1077
- const prevPending = prevIssues.length - prevFixed - prevResolved - prevInvalid;
1072
+ const {
1073
+ fixed: prevFixed,
1074
+ resolved: prevResolved,
1075
+ invalid: prevInvalid,
1076
+ pending: prevPending,
1077
+ } = calculateIssueStats(prevIssues);
1078
1078
  parts.push("");
1079
1079
  parts.push(
1080
1080
  `<details><summary>📊 Round ${round - 1} 回顾 (${prevIssues.length} 个问题)</summary>\n`,
@@ -27,9 +27,7 @@ describe("utils/review-pr-comment", () => {
27
27
 
28
28
  describe("extractIssueKeyFromBody", () => {
29
29
  it("提取标准格式的 issue key", () => {
30
- expect(extractIssueKeyFromBody("<!-- issue-key: src/a.ts:10:R1 -->")).toBe(
31
- "src/a.ts:10:R1",
32
- );
30
+ expect(extractIssueKeyFromBody("<!-- issue-key: src/a.ts:10:R1 -->")).toBe("src/a.ts:10:R1");
33
31
  });
34
32
 
35
33
  it("body 不含 issue-key 时返回 null", () => {
@@ -69,9 +67,9 @@ describe("utils/review-pr-comment", () => {
69
67
 
70
68
  describe("generateIssueKey", () => {
71
69
  it("拼接 file:line:ruleId", () => {
72
- expect(
73
- generateIssueKey({ file: "src/a.ts", line: "10", ruleId: "R1" } as any),
74
- ).toBe("src/a.ts:10:R1");
70
+ expect(generateIssueKey({ file: "src/a.ts", line: "10", ruleId: "R1" } as any)).toBe(
71
+ "src/a.ts:10:R1",
72
+ );
75
73
  });
76
74
  });
77
75
 
@@ -129,21 +127,20 @@ describe("utils/review-pr-comment", () => {
129
127
  });
130
128
 
131
129
  it("resolved(非 fixed)计入 resolved,不计入 pending", () => {
132
- const issues = [
133
- { file: "a.ts", line: "1", ruleId: "R1", resolved: "2024-01-01" },
134
- ] as any[];
130
+ const issues = [{ file: "a.ts", line: "1", ruleId: "R1", resolved: "2024-01-01" }] as any[];
135
131
  const stats = calculateIssueStats(issues);
136
132
  expect(stats.resolved).toBe(1);
137
133
  expect(stats.pending).toBe(0);
138
134
  });
139
135
 
140
- it("fixed 同时有 resolved 时只计入 fixed", () => {
136
+ it("fixed resolved 同时存在时各自独立计数,pending 不重复减", () => {
141
137
  const issues = [
142
138
  { file: "a.ts", line: "1", ruleId: "R1", fixed: "2024-01-01", resolved: "2024-01-01" },
143
139
  ] as any[];
144
140
  const stats = calculateIssueStats(issues);
145
141
  expect(stats.fixed).toBe(1);
146
- expect(stats.resolved).toBe(0);
142
+ expect(stats.resolved).toBe(1);
143
+ expect(stats.pending).toBe(0);
147
144
  });
148
145
 
149
146
  it("fixRate 计算正确(2/4 = 50%)", () => {
@@ -179,7 +179,7 @@ export function calculateIssueStats(issues: ReviewIssue[]): ReviewStats {
179
179
  const fixed = validIssue.filter((i) => i.fixed).length;
180
180
  const resolved = validIssue.filter((i) => i.resolved).length;
181
181
  const invalid = total - validTotal;
182
- const pending = validTotal - fixed - resolved;
182
+ const pending = validTotal - validIssue.filter((i) => i.fixed || i.resolved).length;
183
183
  const fixRate = validTotal > 0 ? Math.round((fixed / validTotal) * 100 * 10) / 10 : 0;
184
184
  const resolveRate = validTotal > 0 ? Math.round((resolved / validTotal) * 100 * 10) / 10 : 0;
185
185
  return { total, validTotal, fixed, resolved, invalid, pending, fixRate, resolveRate };