@spaceflow/review 0.77.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaceflow/review",
3
- "version": "0.77.0",
3
+ "version": "0.78.0",
4
4
  "description": "Spaceflow 代码审查插件,使用 LLM 对 PR 代码进行自动审查",
5
5
  "license": "MIT",
6
6
  "author": "Lydanne",
@@ -5,7 +5,6 @@ import {
5
5
  type LLMMode,
6
6
  type VerboseLevel,
7
7
  shouldLog,
8
- type LlmJsonPutSchema,
9
8
  LlmJsonPut,
10
9
  GitProviderService,
11
10
  ChangedFile,
@@ -14,6 +13,11 @@ import micromatch from "micromatch";
14
13
  import type { DeletionImpactResult } from "./review-spec";
15
14
  import { extractGlobsFromIncludes } from "./review-includes-filter";
16
15
  import { spawn } from "child_process";
16
+ import {
17
+ DELETION_IMPACT_SCHEMA,
18
+ buildDeletionImpactPrompt,
19
+ buildDeletionImpactAgentPrompt,
20
+ } from "./prompt";
17
21
 
18
22
  export interface DeletedCodeBlock {
19
23
  file: string;
@@ -23,40 +27,6 @@ export interface DeletedCodeBlock {
23
27
  commit?: string;
24
28
  }
25
29
 
26
- const DELETION_IMPACT_SCHEMA: LlmJsonPutSchema = {
27
- type: "object",
28
- properties: {
29
- impacts: {
30
- type: "array",
31
- items: {
32
- type: "object",
33
- properties: {
34
- file: { type: "string", description: "被删除代码所在的文件路径" },
35
- deletedCode: { type: "string", description: "被删除的代码片段摘要(前50字符)" },
36
- riskLevel: {
37
- type: "string",
38
- enum: ["high", "medium", "low", "none"],
39
- description:
40
- "风险等级:high=可能导致功能异常,medium=可能影响部分功能,low=影响较小,none=无影响",
41
- },
42
- affectedFiles: {
43
- type: "array",
44
- items: { type: "string" },
45
- description: "可能受影响的文件列表",
46
- },
47
- reason: { type: "string", description: "影响分析的详细说明" },
48
- suggestion: { type: "string", description: "建议的处理方式" },
49
- },
50
- required: ["file", "deletedCode", "riskLevel", "affectedFiles", "reason"],
51
- additionalProperties: false,
52
- },
53
- },
54
- summary: { type: "string", description: "删除代码影响的整体总结" },
55
- },
56
- required: ["impacts", "summary"],
57
- additionalProperties: false,
58
- };
59
-
60
30
  export type DeletionDiffSource = "provider-api" | "git-diff";
61
31
 
62
32
  export interface DeletionAnalysisContext {
@@ -563,47 +533,10 @@ export class DeletionImpactService {
563
533
  ): Promise<DeletionImpactResult> {
564
534
  const llmJsonPut = new LlmJsonPut<DeletionImpactResult>(DELETION_IMPACT_SCHEMA);
565
535
 
566
- const systemPrompt = `你是一个代码审查专家,专门分析删除代码可能带来的影响。
567
-
568
- ## 任务
569
- 分析以下被删除的代码块,判断删除这些代码是否会影响到其他功能。
570
-
571
- ## 分析要点
572
- 1. **功能依赖**: 被删除的代码是否被其他模块调用或依赖
573
- 2. **接口变更**: 删除是否会导致 API 或接口不兼容
574
- 3. **副作用**: 删除是否会影响系统的其他行为
575
- 4. **数据流**: 删除是否会中断数据处理流程
576
-
577
- ## 风险等级判断标准
578
- - **high**: 删除的代码被其他文件直接调用,删除后会导致编译错误或运行时异常
579
- - **medium**: 删除的代码可能影响某些功能的行为,但不会导致直接错误
580
- - **low**: 删除的代码影响较小,可能只是清理无用代码
581
- - **none**: 删除的代码确实是无用代码,不会产生任何影响
582
-
583
- ## 输出要求
584
- - 对每个有风险的删除块给出详细分析
585
- - 如果删除是安全的,也要说明原因
586
- - 提供具体的建议`;
587
-
588
- const deletedCodeSection = deletedBlocks
589
- .map((block, index) => {
590
- const refs = references.get(`${block.file}:${block.startLine}-${block.endLine}`) || [];
591
- return `### 删除块 ${index + 1}: ${block.file}:${block.startLine}-${block.endLine}
592
-
593
- \`\`\`
594
- ${block.content}
595
- \`\`\`
596
-
597
- 可能引用此代码的文件: ${refs.length > 0 ? refs.join(", ") : "未发现直接引用"}
598
- `;
599
- })
600
- .join("\n");
601
-
602
- const userPrompt = `## 被删除的代码块
603
-
604
- ${deletedCodeSection}
605
-
606
- 请分析这些删除操作可能带来的影响。`;
536
+ const { systemPrompt, userPrompt } = buildDeletionImpactPrompt({
537
+ deletedBlocks,
538
+ references,
539
+ });
607
540
 
608
541
  if (shouldLog(verbose, 2)) {
609
542
  console.log(`\nsystemPrompt:\n----------------\n${systemPrompt}\n----------------`);
@@ -662,58 +595,10 @@ ${deletedCodeSection}
662
595
  ): Promise<DeletionImpactResult> {
663
596
  const llmJsonPut = new LlmJsonPut<DeletionImpactResult>(DELETION_IMPACT_SCHEMA);
664
597
 
665
- const systemPrompt = `你是一个资深代码架构师,擅长分析代码变更的影响范围和潜在风险。
666
-
667
- ## 任务
668
- 深入分析以下被删除的代码块,评估删除操作对代码库的影响。
669
-
670
- ## 你的能力
671
- 你可以使用以下工具来深入分析代码:
672
- - **Read**: 读取文件内容,查看被删除代码的完整上下文
673
- - **Grep**: 搜索代码库,查找对被删除代码的引用
674
- - **Glob**: 查找匹配模式的文件
675
-
676
- ## 分析流程
677
- 1. 首先阅读被删除代码的上下文,理解其功能
678
- 2. 使用 Grep 搜索代码库中对这些代码的引用
679
- 3. 分析引用处的代码,判断删除后的影响
680
- 4. 给出风险评估和建议
681
-
682
- ## 风险等级判断标准
683
- - **high**: 删除的代码被其他文件直接调用,删除后会导致编译错误或运行时异常
684
- - **medium**: 删除的代码可能影响某些功能的行为,但不会导致直接错误
685
- - **low**: 删除的代码影响较小,可能只是清理无用代码
686
- - **none**: 删除的代码确实是无用代码,不会产生任何影响
687
-
688
- ## 输出要求
689
- - 对每个有风险的删除块给出详细分析
690
- - 如果删除是安全的,也要说明原因
691
- - 提供具体的建议`;
692
-
693
- const deletedCodeSection = deletedBlocks
694
- .map((block, index) => {
695
- const refs = references.get(`${block.file}:${block.startLine}-${block.endLine}`) || [];
696
- return `### 删除块 ${index + 1}: ${block.file}:${block.startLine}-${block.endLine}
697
-
698
- \`\`\`
699
- ${block.content}
700
- \`\`\`
701
-
702
- 可能引用此代码的文件: ${refs.length > 0 ? refs.join(", ") : "未发现直接引用"}
703
- `;
704
- })
705
- .join("\n");
706
-
707
- const userPrompt = `## 被删除的代码块
708
-
709
- ${deletedCodeSection}
710
-
711
- ## 补充说明
712
-
713
- 请使用你的工具能力深入分析这些删除操作可能带来的影响。
714
- - 如果需要查看更多上下文,请读取相关文件
715
- - 如果需要确认引用关系,请搜索代码库
716
- - 分析完成后,给出结构化的影响评估`;
598
+ const { systemPrompt, userPrompt } = buildDeletionImpactAgentPrompt({
599
+ deletedBlocks,
600
+ references,
601
+ });
717
602
 
718
603
  if (shouldLog(verbose, 2)) {
719
604
  console.log(
@@ -3,7 +3,6 @@ import {
3
3
  type LLMMode,
4
4
  type VerboseLevel,
5
5
  shouldLog,
6
- type LlmJsonPutSchema,
7
6
  LlmJsonPut,
8
7
  parallel,
9
8
  } from "@spaceflow/core";
@@ -15,6 +14,7 @@ import {
15
14
  FileContentsMap,
16
15
  FileContentLine,
17
16
  } from "./review-spec";
17
+ import { VERIFY_SCHEMA, buildIssueVerifyPrompt } from "./prompt";
18
18
 
19
19
  interface VerifyResult {
20
20
  fixed: boolean;
@@ -25,26 +25,6 @@ interface VerifyResult {
25
25
  const TRUE = "true";
26
26
  const FALSE = "false";
27
27
 
28
- const VERIFY_SCHEMA: LlmJsonPutSchema = {
29
- type: "object",
30
- properties: {
31
- fixed: {
32
- type: "boolean",
33
- description: "问题是否已被修复",
34
- },
35
- valid: {
36
- type: "boolean",
37
- description: "问题是否有效,有效的条件就是你需要看看代码是否符合规范",
38
- },
39
- reason: {
40
- type: "string",
41
- description: "判断依据,说明为什么认为问题已修复或仍存在",
42
- },
43
- },
44
- required: ["fixed", "valid", "reason"],
45
- additionalProperties: false,
46
- };
47
-
48
28
  export class IssueVerifyService {
49
29
  constructor(
50
30
  protected readonly llmProxyService: LlmProxyService,
@@ -138,7 +118,7 @@ export class IssueVerifyService {
138
118
  toVerify,
139
119
  async ({ issue, fileContent, ruleInfo }) =>
140
120
  this.verifySingleIssue(issue, fileContent, ruleInfo, llmMode, llmJsonPut, verbose),
141
- ({ issue }) => `${issue.file}:${issue.line}`,
121
+ ({ issue }) => `${issue.file}:${issue.line}:${issue.ruleId}`,
142
122
  );
143
123
 
144
124
  for (const result of results) {
@@ -147,7 +127,7 @@ export class IssueVerifyService {
147
127
  } else {
148
128
  // 失败时保留原始 issue
149
129
  const originalItem = toVerify.find(
150
- (item) => `${item.issue.file}:${item.issue.line}` === result.id,
130
+ (item) => `${item.issue.file}:${item.issue.line}:${item.issue.ruleId}` === result.id,
151
131
  );
152
132
  if (originalItem) {
153
133
  verifiedIssues.push(originalItem.issue);
@@ -175,7 +155,13 @@ export class IssueVerifyService {
175
155
  llmJsonPut: LlmJsonPut<VerifyResult>,
176
156
  verbose?: VerboseLevel,
177
157
  ): Promise<ReviewIssue> {
178
- const verifyPrompt = this.buildVerifyPrompt(issue, fileContent, ruleInfo);
158
+ const specsSection = ruleInfo ? this.reviewSpecService.buildSpecsSection([ruleInfo.spec]) : "";
159
+ const verifyPrompt = buildIssueVerifyPrompt({
160
+ issue,
161
+ fileContent,
162
+ ruleInfo,
163
+ specsSection,
164
+ });
179
165
 
180
166
  try {
181
167
  const stream = this.llmProxyService.chatStream(
@@ -239,6 +225,7 @@ export class IssueVerifyService {
239
225
  }
240
226
 
241
227
  /**
228
+ * @deprecated 使用 prompt/issue-verify.ts 中的 buildIssueVerifyPrompt
242
229
  * 构建验证单个 issue 是否已修复的 prompt
243
230
  */
244
231
  protected buildVerifyPrompt(
@@ -246,64 +233,13 @@ export class IssueVerifyService {
246
233
  fileContent: FileContentLine[],
247
234
  ruleInfo: { rule: ReviewRule; spec: ReviewSpec } | null,
248
235
  ): { systemPrompt: string; userPrompt: string } {
249
- const padWidth = String(fileContent.length).length;
250
- const linesWithNumbers = fileContent
251
- .map(([, line], index) => `${String(index + 1).padStart(padWidth)}| ${line}`)
252
- .join("\n");
253
-
254
- const systemPrompt = `你是一个代码审查专家。你的任务是判断之前发现的一个代码问题:
255
- 1. 是否有效(是否真的违反了规则)
256
- 2. 是否已经被修复
257
-
258
- 请仔细分析当前的代码内容。
259
-
260
- ## 输出要求
261
- - valid: 布尔值,true 表示问题有效(代码确实违反了规则),false 表示问题无效(误报)
262
- - fixed: 布尔值,true 表示问题已经被修复,false 表示问题仍然存在
263
- - reason: 判断依据
236
+ const specsSection = ruleInfo ? this.reviewSpecService.buildSpecsSection([ruleInfo.spec]) : "";
264
237
 
265
- ## 判断标准
266
-
267
- ### valid 判断
268
- - 根据规则 ID 和问题描述,判断代码是否真的违反了该规则
269
- - 如果问题描述与实际代码不符,valid 为 false
270
- - 如果规则不适用于该代码场景,valid 为 false
271
-
272
- ### fixed 判断
273
- - 只有当问题所在的代码已被修改,且修改后的代码不再违反规则时,fixed 才为 true
274
- - 如果问题所在的代码仍然存在且仍违反规则,fixed 必须为 false
275
- - 如果代码行号发生变化但问题本质仍存在,fixed 必须为 false
276
-
277
- ## 重要提醒
278
- - valid=false 时,fixed 的值无意义(无效问题无需修复)
279
- - 请确保 valid 和 fixed 的值与 reason 的描述一致!`;
280
-
281
- // 构建规则定义部分
282
- let ruleSection = "";
283
- if (ruleInfo) {
284
- ruleSection = this.reviewSpecService.buildSpecsSection([ruleInfo.spec]);
285
- }
286
-
287
- const userPrompt = `## 规则定义
288
-
289
- ${ruleSection}
290
-
291
- ## 之前发现的问题
292
-
293
- - **文件**: ${issue.file}
294
- - **行号**: ${issue.line}
295
- - **规则**: ${issue.ruleId} (来自 ${issue.specFile})
296
- - **问题描述**: ${issue.reason}
297
- ${issue.suggestion ? `- **原建议**: ${issue.suggestion}` : ""}
298
-
299
- ## 当前文件内容
300
-
301
- \`\`\`
302
- ${linesWithNumbers}
303
- \`\`\`
304
-
305
- 请判断这个问题是否有效,以及是否已经被修复。`;
306
-
307
- return { systemPrompt, userPrompt };
238
+ return buildIssueVerifyPrompt({
239
+ issue,
240
+ fileContent,
241
+ ruleInfo,
242
+ specsSection,
243
+ });
308
244
  }
309
245
  }
package/src/mcp/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { t, z, type SpaceflowContext, type GitProviderService } from "@spaceflow/core";
2
2
  import { ReviewSpecService } from "../review-spec";
3
3
  import type { ReviewConfig } from "../review.config";
4
+ import { extractGlobsFromIncludes } from "../review-includes-filter";
4
5
  import { join } from "path";
5
6
  import { existsSync } from "fs";
6
7
 
@@ -117,7 +118,9 @@ export const tools = [
117
118
  .filter((rule) => {
118
119
  const includes = rule.includes || spec.includes;
119
120
  if (includes.length === 0) return true;
120
- return micromatch.isMatch(filePath, includes, { matchBase: true });
121
+ const globs = extractGlobsFromIncludes(includes);
122
+ if (globs.length === 0) return true;
123
+ return micromatch.isMatch(filePath, globs, { matchBase: true });
121
124
  })
122
125
  .map((rule) => ({
123
126
  id: rule.id,
@@ -0,0 +1,95 @@
1
+ import type { PromptFn } from "./types";
2
+ import { validateNonEmptyString, validateRequired } from "./types";
3
+
4
+ /**
5
+ * 代码审查公共系统提示词基础
6
+ */
7
+ const CODE_REVIEW_BASE_SYSTEM_PROMPT = `你是一个专业的代码审查专家,负责根据团队的编码规范对代码进行严格审查。
8
+
9
+ ## 审查要求
10
+
11
+ 1. **严格遵循规范**:只按照上述审查规范进行审查,不要添加规范之外的要求
12
+ 2. **精准定位问题**:每个问题必须指明具体的行号,行号从文件内容中的 "行号|" 格式获取
13
+ 3. **避免重复报告**:如果提示词中包含"上一次审查结果",请不要重复报告已存在的问题
14
+ 4. **提供可行建议**:对于每个问题,提供具体的修改建议代码
15
+
16
+ ## 注意事项
17
+
18
+ - 变更文件内容已在上下文中提供,无需调用读取工具
19
+ - 你可以读取项目中的其他文件以了解上下文
20
+ - 不要调用编辑工具修改文件,你的职责是审查而非修改
21
+ - 文件内容格式为 "CommitHash 行号| 代码",输出的 line 字段应对应原始行号
22
+
23
+ ## 输出要求
24
+
25
+ - 发现问题时:在 issues 数组中列出所有问题,每个问题包含 file、line、ruleId、specFile、reason、suggestion、severity
26
+ - 无论是否发现问题:都必须在 summary 中提供该文件的审查总结,简要说明审查结果`;
27
+
28
+ /**
29
+ * 代码审查 - 系统提示词构建
30
+ */
31
+ export interface CodeReviewSystemContext {
32
+ specsSection: string;
33
+ [key: string]: unknown;
34
+ }
35
+
36
+ export const buildCodeReviewSystemPrompt: PromptFn<CodeReviewSystemContext> = (ctx) => {
37
+ validateNonEmptyString(ctx.specsSection, "specsSection");
38
+ return {
39
+ systemPrompt: `${CODE_REVIEW_BASE_SYSTEM_PROMPT}
40
+
41
+ ## 审查规范
42
+
43
+ ${ctx.specsSection}`,
44
+ userPrompt: "",
45
+ };
46
+ };
47
+
48
+ /**
49
+ * 代码审查 - 单文件审查提示词
50
+ */
51
+ export interface FileReviewContext {
52
+ filename: string;
53
+ status: string;
54
+ linesWithNumbers: string;
55
+ commitsSection: string;
56
+ fileDirectoryInfo: string;
57
+ previousReviewSection: string;
58
+ specsSection: string;
59
+ [key: string]: unknown;
60
+ }
61
+
62
+ export const buildFileReviewPrompt: PromptFn<FileReviewContext> = (ctx) => {
63
+ // 验证必需的输入参数
64
+ validateNonEmptyString(ctx.filename, "filename");
65
+ validateNonEmptyString(ctx.status, "status");
66
+ validateNonEmptyString(ctx.linesWithNumbers, "linesWithNumbers");
67
+ validateRequired(ctx.specsSection, "specsSection");
68
+
69
+ return {
70
+ systemPrompt: `${CODE_REVIEW_BASE_SYSTEM_PROMPT}
71
+
72
+ ## 审查规范
73
+
74
+ ${ctx.specsSection}`,
75
+ userPrompt: `## ${ctx.filename} (${ctx.status})
76
+
77
+ ### 文件内容
78
+
79
+ \`\`\`
80
+ ${ctx.linesWithNumbers}
81
+ \`\`\`
82
+
83
+ ### 该文件的相关 Commits
84
+
85
+ ${ctx.commitsSection}
86
+
87
+ ### 该文件所在的目录树
88
+
89
+ ${ctx.fileDirectoryInfo}
90
+
91
+ ### 上一次审查结果
92
+
93
+ ${ctx.previousReviewSection}`,
94
+ };
95
+ };
@@ -0,0 +1,105 @@
1
+ import type { PromptFn } from "./types";
2
+ import { validateArray, validateRequired } from "./types";
3
+ import type { DeletedCodeBlock } from "../deletion-impact.service";
4
+
5
+ /**
6
+ * 删除影响分析 - 标准 LLM 模式
7
+ */
8
+ export interface DeletionImpactContext {
9
+ deletedBlocks: DeletedCodeBlock[];
10
+ references: Map<string, string[]>;
11
+ [key: string]: unknown;
12
+ }
13
+
14
+ const DELETION_IMPACT_SYSTEM = `你是一个代码审查专家,专门分析删除代码可能带来的影响。
15
+
16
+ ## 任务
17
+ 分析以下被删除的代码块,判断删除这些代码是否会影响到其他功能。
18
+
19
+ ## 分析要点
20
+ 1. **功能依赖**: 被删除的代码是否被其他模块调用或依赖
21
+ 2. **接口变更**: 删除是否会导致 API 或接口不兼容
22
+ 3. **副作用**: 删除是否会影响系统的其他行为
23
+ 4. **数据流**: 删除是否会中断数据处理流程
24
+
25
+ ## 风险等级判断标准
26
+ - **high**: 删除的代码被其他文件直接调用,删除后会导致编译错误或运行时异常
27
+ - **medium**: 删除的代码可能影响某些功能的行为,但不会导致直接错误
28
+ - **low**: 删除的代码影响较小,可能只是清理无用代码
29
+ - **none**: 删除的代码确实是无用代码,不会产生任何影响
30
+
31
+ ## 输出要求
32
+ - 对每个有风险的删除块给出详细分析
33
+ - 如果删除是安全的,也要说明原因
34
+ - 提供具体的建议`;
35
+
36
+ function buildDeletedCodeSection(ctx: DeletionImpactContext): string {
37
+ return ctx.deletedBlocks
38
+ .map((block, index) => {
39
+ const refs = ctx.references.get(`${block.file}:${block.startLine}-${block.endLine}`) || [];
40
+ return `### 删除块 ${index + 1}: ${block.file}:${block.startLine}-${block.endLine}\n\n\`\`\`\n${block.content}\n\`\`\`\n\n可能引用此代码的文件: ${refs.length > 0 ? refs.join(", ") : "未发现直接引用"}\n`;
41
+ })
42
+ .join("\n");
43
+ }
44
+
45
+ export const buildDeletionImpactPrompt: PromptFn<DeletionImpactContext> = (ctx) => {
46
+ validateArray(ctx.deletedBlocks, "deletedBlocks");
47
+ validateRequired(ctx.references, "references");
48
+ return {
49
+ systemPrompt: DELETION_IMPACT_SYSTEM,
50
+ userPrompt: `## 被删除的代码块\n\n${buildDeletedCodeSection(ctx)}\n请分析这些删除操作可能带来的影响。`,
51
+ };
52
+ };
53
+
54
+ /** @deprecated 使用 buildDeletionImpactPrompt */
55
+ export const buildDeletionImpactSystemPrompt: PromptFn<DeletionImpactContext> = (ctx) =>
56
+ buildDeletionImpactPrompt(ctx);
57
+
58
+ /** @deprecated 使用 buildDeletionImpactPrompt */
59
+ export const buildDeletionImpactUserPrompt: PromptFn<DeletionImpactContext> = (ctx) =>
60
+ buildDeletionImpactPrompt(ctx);
61
+
62
+ const DELETION_IMPACT_AGENT_SYSTEM = `你是一个资深代码架构师,擅长分析代码变更的影响范围和潜在风险。
63
+
64
+ ## 任务
65
+ 深入分析以下被删除的代码块,评估删除操作对代码库的影响。
66
+
67
+ ## 你的能力
68
+ 你可以使用以下工具来深入分析代码:
69
+ - **Read**: 读取文件内容,查看被删除代码的完整上下文
70
+ - **Grep**: 搜索代码库,查找对被删除代码的引用
71
+ - **Glob**: 查找匹配模式的文件
72
+
73
+ ## 分析流程
74
+ 1. 首先阅读被删除代码的上下文,理解其功能
75
+ 2. 使用 Grep 搜索代码库中对这些代码的引用
76
+ 3. 分析引用处的代码,判断删除后的影响
77
+ 4. 给出风险评估和建议
78
+
79
+ ## 风险等级判断标准
80
+ - **high**: 删除的代码被其他文件直接调用,删除后会导致编译错误或运行时异常
81
+ - **medium**: 删除的代码可能影响某些功能的行为,但不会导致直接错误
82
+ - **low**: 删除的代码影响较小,可能只是清理无用代码
83
+ - **none**: 删除的代码确实是无用代码,不会产生任何影响
84
+
85
+ ## 输出要求
86
+ - 对每个有风险的删除块给出详细分析
87
+ - 如果删除是安全的,也要说明原因
88
+ - 提供具体的建议`;
89
+
90
+ export const buildDeletionImpactAgentPrompt: PromptFn<DeletionImpactContext> = (ctx) => {
91
+ validateArray(ctx.deletedBlocks, "deletedBlocks");
92
+ validateRequired(ctx.references, "references");
93
+ return {
94
+ systemPrompt: DELETION_IMPACT_AGENT_SYSTEM,
95
+ userPrompt: `## 被删除的代码块\n\n${buildDeletedCodeSection(ctx)}\n## 补充说明\n\n请使用你的工具能力深入分析这些删除操作可能带来的影响。\n- 如果需要查看更多上下文,请读取相关文件\n- 如果需要确认引用关系,请搜索代码库\n- 分析完成后,给出结构化的影响评估`,
96
+ };
97
+ };
98
+
99
+ /** @deprecated 使用 buildDeletionImpactAgentPrompt */
100
+ export const buildDeletionImpactAgentSystemPrompt: PromptFn<DeletionImpactContext> = (ctx) =>
101
+ buildDeletionImpactAgentPrompt(ctx);
102
+
103
+ /** @deprecated 使用 buildDeletionImpactAgentPrompt */
104
+ export const buildDeletionImpactAgentUserPrompt: PromptFn<DeletionImpactContext> = (ctx) =>
105
+ buildDeletionImpactAgentPrompt(ctx);
@@ -0,0 +1,37 @@
1
+ // 统一导出所有提示词
2
+
3
+ // 类型定义
4
+ export type { PromptFn, PromptContext, PromptResult } from "./types";
5
+
6
+ // JSON Schemas
7
+ export { REVIEW_SCHEMA, DELETION_IMPACT_SCHEMA, VERIFY_SCHEMA } from "./schemas";
8
+
9
+ // 代码审查提示词
10
+ export {
11
+ buildCodeReviewSystemPrompt,
12
+ buildFileReviewPrompt,
13
+ type CodeReviewSystemContext,
14
+ type FileReviewContext,
15
+ } from "./code-review";
16
+
17
+ // PR 描述生成提示词
18
+ export {
19
+ buildPrDescriptionPrompt,
20
+ buildPrTitlePrompt,
21
+ type PrDescriptionContext,
22
+ type PrTitleContext,
23
+ } from "./pr-description";
24
+
25
+ // 删除影响分析提示词
26
+ export {
27
+ buildDeletionImpactPrompt,
28
+ buildDeletionImpactAgentPrompt,
29
+ buildDeletionImpactSystemPrompt,
30
+ buildDeletionImpactUserPrompt,
31
+ buildDeletionImpactAgentSystemPrompt,
32
+ buildDeletionImpactAgentUserPrompt,
33
+ type DeletionImpactContext,
34
+ } from "./deletion-impact";
35
+
36
+ // 问题验证提示词
37
+ export { buildIssueVerifyPrompt, type IssueVerifyContext } from "./issue-verify";
@@ -0,0 +1,86 @@
1
+ import type { PromptFn } from "./types";
2
+ import { validateRequired, validateArray } from "./types";
3
+ import type { ReviewIssue, ReviewRule, ReviewSpec, FileContentLine } from "../review-spec";
4
+
5
+ /**
6
+ * 问题验证提示词上下文
7
+ */
8
+ export interface IssueVerifyContext {
9
+ issue: ReviewIssue;
10
+ fileContent: FileContentLine[];
11
+ ruleInfo: { rule: ReviewRule; spec: ReviewSpec } | null;
12
+ specsSection?: string;
13
+ [key: string]: unknown;
14
+ }
15
+
16
+ /**
17
+ * 构建问题验证提示词
18
+ */
19
+ export const buildIssueVerifyPrompt: PromptFn<IssueVerifyContext> = (ctx) => {
20
+ // 验证必需的输入参数
21
+ validateRequired(ctx.issue, "issue");
22
+ validateArray(ctx.fileContent, "fileContent");
23
+
24
+ const padWidth = String(ctx.fileContent.length).length;
25
+ const linesWithNumbers = ctx.fileContent
26
+ .map(([, line], index) => `${String(index + 1).padStart(padWidth)}| ${line}`)
27
+ .join("\n");
28
+
29
+ const systemPrompt = `你是一个代码审查专家。你的任务是判断之前发现的一个代码问题:
30
+ 1. 是否有效(是否真的违反了规则)
31
+ 2. 是否已经被修复
32
+
33
+ 请仔细分析当前的代码内容。
34
+
35
+ ## 输出要求
36
+ - valid: 布尔值,true 表示问题有效(代码确实违反了规则),false 表示问题无效(误报)
37
+ - fixed: 布尔值,true 表示问题已经被修复,false 表示问题仍然存在
38
+ - reason: 判断依据
39
+
40
+ ## 判断标准
41
+
42
+ ### valid 判断
43
+ - 根据规则 ID 和问题描述,判断代码是否真的违反了该规则
44
+ - 如果问题描述与实际代码不符,valid 为 false
45
+ - 如果规则不适用于该代码场景,valid 为 false
46
+
47
+ ### fixed 判断
48
+ - 只有当问题所在的代码已被修改,且修改后的代码不再违反规则时,fixed 才为 true
49
+ - 如果问题所在的代码仍然存在且仍违反规则,fixed 必须为 false
50
+ - 如果代码行号发生变化但问题本质仍存在,fixed 必须为 false
51
+
52
+ ## 重要提醒
53
+ - valid=false 时,fixed 的值无意义(无效问题无需修复)
54
+ - 请确保 valid 和 fixed 的值与 reason 的描述一致!`;
55
+
56
+ // 构建规则定义部分
57
+ let ruleSection = "";
58
+ if (ctx.specsSection) {
59
+ ruleSection = ctx.specsSection;
60
+ } else if (ctx.ruleInfo) {
61
+ const { spec, rule } = ctx.ruleInfo;
62
+ ruleSection = `### ${spec.filename} (${spec.type})\n\n${spec.content.slice(0, 200)}...\n\n#### 规则\n- ${rule.id}: ${rule.title}\n ${rule.description}`;
63
+ }
64
+
65
+ const userPrompt = `## 规则定义
66
+
67
+ ${ruleSection}
68
+
69
+ ## 之前发现的问题
70
+
71
+ - **文件**: ${ctx.issue.file}
72
+ - **行号**: ${ctx.issue.line}
73
+ - **规则**: ${ctx.issue.ruleId} (来自 ${ctx.issue.specFile})
74
+ - **问题描述**: ${ctx.issue.reason}
75
+ ${ctx.issue.suggestion ? `- **原建议**: ${ctx.issue.suggestion}` : ""}
76
+
77
+ ## 当前文件内容
78
+
79
+ \`\`\`
80
+ ${linesWithNumbers}
81
+ \`\`\`
82
+
83
+ 请判断这个问题是否有效,以及是否已经被修复。`;
84
+
85
+ return { systemPrompt, userPrompt };
86
+ };