@spaceflow/review 0.76.0 → 0.78.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 +47 -0
- package/dist/index.js +3830 -2469
- package/package.json +2 -2
- package/src/deletion-impact.service.ts +17 -130
- package/src/index.ts +34 -2
- package/src/issue-verify.service.ts +18 -82
- package/src/locales/en/review.json +2 -1
- package/src/locales/zh-cn/review.json +2 -1
- package/src/mcp/index.ts +4 -1
- package/src/prompt/code-review.ts +95 -0
- package/src/prompt/deletion-impact.ts +105 -0
- package/src/prompt/index.ts +37 -0
- package/src/prompt/issue-verify.ts +86 -0
- package/src/prompt/pr-description.ts +149 -0
- package/src/prompt/schemas.ts +106 -0
- package/src/prompt/types.ts +53 -0
- package/src/pull-request-model.ts +236 -0
- package/src/review-context.ts +433 -0
- package/src/review-includes-filter.spec.ts +284 -0
- package/src/review-includes-filter.ts +196 -0
- package/src/review-issue-filter.ts +523 -0
- package/src/review-llm.ts +543 -0
- package/src/review-result-model.spec.ts +657 -0
- package/src/review-result-model.ts +1046 -0
- package/src/review-spec/review-spec.service.ts +26 -5
- package/src/review-spec/types.ts +2 -0
- package/src/review.config.ts +40 -5
- package/src/review.service.spec.ts +102 -1625
- package/src/review.service.ts +608 -2742
- package/src/system-rules/index.ts +48 -0
- package/src/system-rules/max-lines-per-file.ts +57 -0
- package/src/types/review-llm.ts +21 -0
- package/src/utils/review-llm.spec.ts +277 -0
- package/src/utils/review-llm.ts +177 -0
- package/src/utils/review-pr-comment.spec.ts +340 -0
- package/src/utils/review-pr-comment.ts +186 -0
- package/tsconfig.json +1 -1
|
@@ -13,6 +13,7 @@ import { homedir } from "os";
|
|
|
13
13
|
import { execSync } from "child_process";
|
|
14
14
|
import micromatch from "micromatch";
|
|
15
15
|
import { ReviewSpec, ReviewRule, RuleExample, Severity } from "./types";
|
|
16
|
+
import { extractGlobsFromIncludes } from "../review-includes-filter";
|
|
16
17
|
|
|
17
18
|
/** 远程规则缓存 TTL(毫秒),默认 5 分钟 */
|
|
18
19
|
const REMOTE_SPEC_CACHE_TTL = 5 * 60 * 1000;
|
|
@@ -69,7 +70,23 @@ export class ReviewSpecService {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
console.log(
|
|
74
|
+
`[filterApplicableSpecs] changedExtensions=${JSON.stringify([...changedExtensions])}, specs count=${specs.length}`,
|
|
75
|
+
);
|
|
76
|
+
const result = specs.filter((spec) => {
|
|
77
|
+
const matches = spec.extensions.some((ext) => changedExtensions.has(ext));
|
|
78
|
+
if (!matches) {
|
|
79
|
+
console.log(
|
|
80
|
+
`[filterApplicableSpecs] spec ${spec.filename} (ext: ${JSON.stringify(spec.extensions)}) NOT matched`,
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
console.log(
|
|
84
|
+
`[filterApplicableSpecs] spec ${spec.filename} (ext: ${JSON.stringify(spec.extensions)}) MATCHED`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
return matches;
|
|
88
|
+
});
|
|
89
|
+
return result;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
async loadReviewSpecs(specDir: string): Promise<ReviewSpec[]> {
|
|
@@ -524,8 +541,10 @@ export class ReviewSpecService {
|
|
|
524
541
|
return true;
|
|
525
542
|
}
|
|
526
543
|
|
|
527
|
-
// 检查文件是否匹配 includes
|
|
528
|
-
const
|
|
544
|
+
// 检查文件是否匹配 includes 模式(转换为纯 glob,避免 status| 前缀和 code-* 空串传入 micromatch)
|
|
545
|
+
const globs = extractGlobsFromIncludes(includes);
|
|
546
|
+
if (globs.length === 0) return true;
|
|
547
|
+
const matches = micromatch.isMatch(issue.file, globs, { matchBase: true });
|
|
529
548
|
if (!matches) {
|
|
530
549
|
// console.log(` Issue [${issue.ruleId}] 在文件 ${issue.file} 不匹配 includes 模式,跳过`);
|
|
531
550
|
}
|
|
@@ -638,8 +657,10 @@ export class ReviewSpecService {
|
|
|
638
657
|
if (scoped.includes.length === 0) {
|
|
639
658
|
return true;
|
|
640
659
|
}
|
|
641
|
-
// 使用 micromatch 检查文件是否匹配 includes
|
|
642
|
-
|
|
660
|
+
// 使用 micromatch 检查文件是否匹配 includes 模式(转换为纯 glob)
|
|
661
|
+
const globs = extractGlobsFromIncludes(scoped.includes);
|
|
662
|
+
if (globs.length === 0) return true;
|
|
663
|
+
return issueFile && micromatch.isMatch(issueFile, globs, { matchBase: true });
|
|
643
664
|
});
|
|
644
665
|
|
|
645
666
|
if (matched) {
|
package/src/review-spec/types.ts
CHANGED
package/src/review.config.ts
CHANGED
|
@@ -27,6 +27,15 @@ export type AnalyzeDeletionsMode = z.infer<typeof analyzeDeletionsModeSchema>;
|
|
|
27
27
|
/** 审查规则严重级别 */
|
|
28
28
|
export type Severity = z.infer<typeof severitySchema>;
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* 系统规则配置,不依赖 LLM,在构建 prompt 前直接检查并生成系统问题。
|
|
32
|
+
* 格式为 [阈值, severity]
|
|
33
|
+
*/
|
|
34
|
+
export interface SystemRules {
|
|
35
|
+
/** 单文件最大审查行数,超过时跳过 LLM 并生成系统问题。格式: [maxLine, severity] */
|
|
36
|
+
maxLinesPerFile?: [number, Severity];
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
/**
|
|
31
40
|
* 变更文件处理策略
|
|
32
41
|
* - 'invalidate': 将变更文件的历史问题标记为无效(默认)
|
|
@@ -47,6 +56,11 @@ export interface ReviewOptions {
|
|
|
47
56
|
references?: string[];
|
|
48
57
|
verbose?: VerboseLevel;
|
|
49
58
|
includes?: string[];
|
|
59
|
+
/**
|
|
60
|
+
* 代码结构过滤配置,指定在代码审查时要关注的代码结构类型
|
|
61
|
+
* 支持格式:"function"、"class"、"interface"、"type"、"method"
|
|
62
|
+
*/
|
|
63
|
+
whenModifiedCode?: string[];
|
|
50
64
|
llmMode?: LLMMode;
|
|
51
65
|
files?: string[];
|
|
52
66
|
commits?: string[];
|
|
@@ -80,17 +94,28 @@ export interface ReviewOptions {
|
|
|
80
94
|
*/
|
|
81
95
|
local?: LocalReviewMode;
|
|
82
96
|
/**
|
|
83
|
-
*
|
|
84
|
-
* -
|
|
85
|
-
* -
|
|
97
|
+
* 处理重复 workflow 的策略
|
|
98
|
+
* - 'off': 禁用检查
|
|
99
|
+
* - 'skip': 检测到同名 workflow 正在运行时跳过审查
|
|
100
|
+
* - 'delete': 检测到同名 workflow 时删除旧的 AI Review 评论和 PR Review(默认)
|
|
86
101
|
*/
|
|
87
|
-
|
|
102
|
+
duplicateWorkflowResolved?: "off" | "skip" | "delete";
|
|
88
103
|
/**
|
|
89
104
|
* 自动批准合并
|
|
90
105
|
* - true: 当所有问题都已解决时,自动提交 APPROVE review
|
|
91
106
|
* - false: 不自动批准(默认)
|
|
92
107
|
*/
|
|
93
108
|
autoApprove?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* 存在未解决问题时以非零退出码退出(工作流抛出异常)
|
|
111
|
+
* - 'off': 禁用(默认),即使有问题也正常退出
|
|
112
|
+
* - 'warn': 有未解决的 warn 级别问题时抛出异常
|
|
113
|
+
* - 'error': 有未解决的 error 级别问题时抛出异常
|
|
114
|
+
* - 'warn+error': 有未解决的 warn 或 error 级别问题时抛出异常
|
|
115
|
+
*/
|
|
116
|
+
failOnIssues?: "off" | "warn" | "error" | "warn+error";
|
|
117
|
+
/** 系统规则配置,不依赖 LLM,直接在检查阶段生成系统问题 */
|
|
118
|
+
systemRules?: SystemRules;
|
|
94
119
|
}
|
|
95
120
|
|
|
96
121
|
/** review 命令配置 schema(LLM 敏感配置由系统 llm.config.ts 管理) */
|
|
@@ -99,6 +124,7 @@ export const reviewSchema = () =>
|
|
|
99
124
|
references: z.array(z.string()).optional(),
|
|
100
125
|
llmMode: llmModeSchema.default("openai").optional(),
|
|
101
126
|
includes: z.array(z.string()).optional(),
|
|
127
|
+
whenModifiedCode: z.array(z.string()).optional(),
|
|
102
128
|
rules: z.record(z.string(), severitySchema).optional(),
|
|
103
129
|
verifyFixes: z.boolean().default(false),
|
|
104
130
|
verifyFixesConcurrency: z.number().default(10).optional(),
|
|
@@ -112,8 +138,17 @@ export const reviewSchema = () =>
|
|
|
112
138
|
retries: z.number().default(0).optional(),
|
|
113
139
|
retryDelay: z.number().default(1000).optional(),
|
|
114
140
|
invalidateChangedFiles: invalidateChangedFilesSchema.default("invalidate").optional(),
|
|
115
|
-
|
|
141
|
+
duplicateWorkflowResolved: z.enum(["off", "skip", "delete"]).default("delete").optional(),
|
|
116
142
|
autoApprove: z.boolean().default(false).optional(),
|
|
143
|
+
failOnIssues: z.enum(["off", "warn", "error", "warn+error"]).default("off").optional(),
|
|
144
|
+
systemRules: z
|
|
145
|
+
.object({
|
|
146
|
+
maxLinesPerFile: z
|
|
147
|
+
.tuple([z.number(), severitySchema])
|
|
148
|
+
.transform((v): [number, Severity] => [v[0], v[1]])
|
|
149
|
+
.optional(),
|
|
150
|
+
})
|
|
151
|
+
.optional(),
|
|
117
152
|
});
|
|
118
153
|
|
|
119
154
|
/** review 配置类型(从 schema 推导) */
|