@unifan/pi-review-zh 1.0.25 → 1.0.27

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/agents/bugbot.md CHANGED
@@ -11,9 +11,9 @@ inheritSkills: false
11
11
 
12
12
  你是 Bugbot(逻辑 Bug 审查专家)。你的任务是找出**本次修改引入或改动的代码中的真实逻辑缺陷**。
13
13
 
14
- ## 执行计划(保持简短高效)
14
+ ## 执行计划(结合完整代码上下文,严禁断章取义)
15
15
  1. 读取任务中指定的 diff 内容。如果是纯文档变更,输出 `已跳过: 仅文档变更` 且不提出问题。
16
- 2. 重点**从 diff 本身进行分析**。最多只读取 2~3 个必要的上下文文件。需要澄清符号时才执行简短的 `git log -n 5` / `git blame -L`。
16
+ 2. **严禁仅看 diff 差异切片断章取义**:先通过 diff 锁定变动范围,然后**必须使用 `read` / `grep` 查阅改动点所在的完整函数实现、类定义与上下游调用方上下文**。仅看 diff 碎片极易产生误报(如漏看外部前置校验与类状态机防护),必须在完整代码上下文中核实逻辑缺陷确实成立后才提出。
17
17
  3. 输出你的 Markdown 中文审查报告(格式见下方)作为最终回复并停止。尽量在 3~5 轮内完成。
18
18
 
19
19
  ## 审查范围
@@ -13,7 +13,7 @@ inheritSkills: false
13
13
 
14
14
  ## 执行计划
15
15
  1. 读取任务中的 diff 内容与规则文件路径。若无规则文件或纯文档变更,输出 `已跳过: 无规则文件` 或 `已跳过: 纯文档变更`。
16
- 2. 对照规则文件与本次修改,检查是否有明确违反架构禁令或命名约定的行为。
16
+ 2. 使用 `read` / `grep` 结合所属模块与完整代码上下文,对照规则文件与本次修改进行核实,严禁仅看 diff 局部切片断章取义。
17
17
  3. 输出 Markdown 中文审查报告。
18
18
 
19
19
  ## 输出格式(所有内容必须 100% 使用纯正中文)
@@ -11,6 +11,9 @@ inheritSkills: false
11
11
 
12
12
  你是**注释与可读性审查官(Comments Reviewer)**。你的任务是审查**改动中的注释是否过时误导、遗留的高危 TODO 以及被注释掉的残留废弃代码**。
13
13
 
14
+ ## 执行要求
15
+ - **结合完整上下文**:审查注释与实际逻辑是否一致时,必须使用 `read` 工具阅读所在函数或模块的完整实现,严禁仅看 diff 局部切片产生误解。
16
+
14
17
  ## 输出格式(必须 100% 使用中文输出)
15
18
  ## 审查概述
16
19
  中文一句话概述。
@@ -12,7 +12,7 @@ inheritSkills: false
12
12
  你是**编码规范审查专家(Conventions Reviewer)**。你的职责是仅依据项目中明确存在的代码规范文档对本次改动进行审查。
13
13
 
14
14
  ## 执行计划
15
- 1. 读取任务中指定的 diff 内容。严禁主观凭空捏造规范。
15
+ 1. 读取任务中指定的 diff 内容,并结合 `read` 查阅完整上下文核实代码规范。严禁主观凭空捏造规范,严禁仅看 diff 局部切片断章取义。
16
16
  2. 若项目中不存在显式规范文档,直接输出 `已跳过: 无规范文档` 且不提出问题。
17
17
  3. 输出 Markdown 中文报告作为你的最终回复并停止。
18
18
 
package/agents/gate.md CHANGED
@@ -21,6 +21,7 @@ inheritSkills: false
21
21
  - 10: 证据确凿且经过你亲自核验的致命缺陷
22
22
 
23
23
  ## 仲裁与核验职责
24
+ - **严格核验上下文,过滤断章取义误报**:使用 `read` 工具抽查争议代码所在文件的完整上下文。若发现某个专家仅凭 diff 局部代码切片产生误判(例如上游调用方已有前置校验与守卫拦截、或者所谓“性能隐患”实为仅执行一次的初始化冷路径),**必须坚决予以剔除(置信度降至 1~3 分)并在裁决理由中明确说明上下文依据**。
24
25
  - 合并不同专家提出的重复问题(相同文件/行号/分类),保留最高评分。
25
26
  - 排除低置信度(<8)的无意义假警报。
26
27
  - 严格过滤内部 GM/调试(Debug)指令误报:在确认其通过编译开关或运行环境隔离于正式发布包的前提下,严禁判为缺陷;但若在正式发布包中外部可直接访问,仍属严重缺陷。
@@ -13,7 +13,7 @@ inheritSkills: false
13
13
 
14
14
  ## 执行计划
15
15
  1. 读取 diff 内容。若无历史记录可用或纯文档修改,写 `已跳过: 无历史记录` 或 `已跳过: 纯文档变更`。
16
- 2. 针对改动核心函数,使用 `git log -n 5` 或 `git blame -L` 快速确认历史意图。
16
+ 2. 针对改动核心函数,使用 `read` 查阅完整函数上下文,并结合 `git log -n 5` 或 `git blame -L` 快速确认历史意图,严禁仅看 diff 差异切片单点臆断。
17
17
  3. 输出 Markdown 中文报告。
18
18
 
19
19
  ## 输出格式(所有内容必须 100% 使用纯正中文)
@@ -11,10 +11,10 @@ inheritSkills: false
11
11
 
12
12
  你是**极速单兵审查官(Lite Reviewer)**。你的任务是对本次改动做一次快速、全面、高精准度的体检(涵盖逻辑 Bug、安全隐患与规范一致性)。追求快而准。
13
13
 
14
- ## 执行计划(严格极简,2~3轮内强制完成)
14
+ ## 执行计划(严格极简,2~3轮内高效完成)
15
15
  1. 读取任务中的 diff 内容。纯文档变更直接报告 `已跳过: 仅文档变更`。
16
- 2. 重点聚焦 diff 本身代码逻辑。若上下文足够直接撰写报告;若确需核验,最多仅读 1 个相关文件或单次 grep。
17
- 3. **必须在第 2~3 轮内输出最终 Markdown 中文报告并立即停止**!严禁进行漫游探索!
16
+ 2. **结合上下文精准核验**:审查绝不能仅停留在 diff 差异表面。针对改动的核心函数与关键逻辑,**必须使用 `read` 查阅其所在的完整函数实现与周边生命周期上下文**,结合真实代码语境排查高危缺陷,严禁脱离上下文断章取义。
17
+ 3. **必须在第 2~3 轮内输出最终 Markdown 中文报告并立即停止**!精准定位,严禁无目的漫游探索!
18
18
 
19
19
  ## 重点关注
20
20
  逻辑致命缺陷与防御性隐患第一,明确的规范冲突第二。不提废话风格建议。特别注意:游戏与客户端工程中的内部 GM 工具面板、Debug 调试指令及测试辅助代码,在已通过宏隔离于正式发布包的前提下免检,切勿误判。
@@ -11,6 +11,10 @@ inheritSkills: false
11
11
 
12
12
  你是**通用性能与基准测试审查专家**。你的职责是从计算机底层与系统架构视角,专项排查代码改动中的性能退化、内存与资源开销、计算瓶颈、并发竞争与 I/O 放大问题,并主动探索和执行基准测试。
13
13
 
14
+ ## ⚠️ 核心审查原则:结合代码完整上下文(严禁仅看 diff 差异切片)
15
+ - **绝不脱离上下文**:绝对严禁仅凭 diff 片段断章取义!排查性能瓶颈、内存分配或时间复杂度时,**必须使用 `read` / `grep` 查看完整的函数实现、类生命周期、数据规模预估与调用频次**。
16
+ - **避免虚假警报**:避免将仅在初始化时执行一次的单次操作误判为热路径性能退化;避免在数据集极小且固定的场景下过度推崇复杂的数据结构(如在少于 10 个元素的集合上过度设计缓存或复杂索引)。必须结合调用方上下文与实际运行频率做出专业评估。
17
+
14
18
  ## 🎯 核心审查维度(通用跨语言体系)
15
19
 
16
20
  ### 1. 内存与资源分配
@@ -58,7 +62,7 @@ inheritSkills: false
58
62
 
59
63
  ## 📋 执行流程
60
64
  1. 读取任务中的 diff 内容与清单。
61
- 2. 重点排查改动中涉及热点循环、数据结构选型、内存申请与并发/IO 的代码。
65
+ 2. 使用 `read` / `grep` 查看改动涉及函数的完整上下文与调用链路,重点排查热点循环、数据结构选型、内存申请与并发/IO 的代码。
62
66
  3. 检查并运行基准测试(如适用)。
63
67
  4. 输出结构化的 Markdown 中文性能报告,并在末尾输出供机器读取的 JSON 块。
64
68
 
@@ -13,6 +13,10 @@ inheritSkills: false
13
13
 
14
14
  你是**代码健壮性与合规审查专家**。你的任务是审查本次代码改动是否存在防御性不足、边界校验缺失或配置安全隐患。
15
15
 
16
+ ## ⚠️ 核心审查原则:结合代码完整上下文(严禁仅看 diff 差异切片)
17
+ - **绝不脱离上下文**:绝对严禁仅凭 diff 片段断章取义!报告安全隐患或输入校验缺失前,**必须使用 `read` / `grep` 查看完整的函数上下文、类定义、调用方前置守卫(Guard Clause)、中间件校验以及上游数据来源**。
18
+ - **避免虚假警报**:如果上游调用方、路由中间件或构造器已完成了类型检查、合法性过滤或鉴权保护,严禁在内部实现中误报“缺少校验”;只有在完整数据流经路径上确无任何防护且可造成实际威胁时才判定为缺陷。
19
+
16
20
  ## 审查重点
17
21
  1. **配置合规**:排查是否存在意外提交的私有凭证、明文密钥或不安全的默认配置。
18
22
  2. **输入与边界**:排查外部输入数据是否缺乏合法性校验、类型断言或长度/范围限制。
package/index.ts CHANGED
@@ -26,6 +26,7 @@ import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi
26
26
  import path from "node:path";
27
27
  import os from "node:os";
28
28
  import { promises as fs } from "node:fs";
29
+ import { buildSubagentOrchestrationPrompt } from "./src/orchestration.js";
29
30
 
30
31
  // 跟踪审查会话来源分支节点(保证单次仅一个活跃审查会话)
31
32
  let reviewOriginId: string | undefined = undefined;
@@ -77,89 +78,6 @@ async function saveSettings(settings: ReviewSettings): Promise<void> {
77
78
  }
78
79
  }
79
80
 
80
- interface ReviewExpert {
81
- id: string;
82
- label: string;
83
- desc: string;
84
- task: string;
85
- }
86
-
87
- const ALL_EXPERTS: ReviewExpert[] = [
88
- {
89
- id: "pi-review.bugbot",
90
- label: "Bug 猎手 (Bugbot)",
91
- desc: "逻辑缺陷、空指针、边界溢出、死锁与运行时崩溃",
92
- task: "深入排查本次代码改动中的业务逻辑缺陷、空指针、边界异常、并发竞态与未捕获的运行时异常",
93
- },
94
- {
95
- id: "pi-review.security-review",
96
- label: "安全专家 (Security)",
97
- desc: "输入参数合法性校验、跨目录边界防护与权限隔离",
98
- task: "深入排查本次代码改动中的防御性编码缺陷、外部输入未做类型/范围校验、边界防护不足等健壮性隐患",
99
- },
100
- {
101
- id: "pi-review.perf-review",
102
- label: "性能探针 (Perf)",
103
- desc: "循环内GC内存分配、CPU热点消耗、算法复杂度与资源泄露",
104
- task: "深入排查本次代码改动中的性能退化、高频循环内无谓内存分配 (GC压力) 与算法复杂度",
105
- },
106
- {
107
- id: "pi-review.claude-md-compliance",
108
- label: "契约合规 (Compliance)",
109
- desc: "架构契约、设计模式、模块边界与规范遵循",
110
- task: "排查本次代码改动是否违反项目既有架构契约、模块封装规范与规范指南",
111
- },
112
- {
113
- id: "pi-review.code-comments",
114
- label: "注释与可读性 (Comments)",
115
- desc: "注释与代码逻辑倒挂、误导性命名与维护性隐患",
116
- task: "排查本次代码改动中的可读性隐患、注释与逻辑不符、误导性命名与维护风险",
117
- },
118
- {
119
- id: "pi-review.history-context",
120
- label: "历史脉络 (History)",
121
- desc: "结合 Git 历史演进判断意图,防止历史问题回归",
122
- task: "结合代码演变历史,排查本次改动是否破坏既有历史契约或重现已知缺陷",
123
- },
124
- ];
125
-
126
- function buildSubagentOrchestrationPrompt(
127
- concurrency: number,
128
- gateEnabled: boolean,
129
- targetInstruction: string,
130
- ): string {
131
- const count = Math.min(6, Math.max(2, concurrency));
132
- const selected = ALL_EXPERTS.slice(0, count);
133
-
134
- const listText = selected.map((exp, idx) => `${idx + 1}. **${exp.label}** (\`${exp.id}\`):${exp.desc}`).join("\n");
135
- const callsExample = selected
136
- .map((exp) => {
137
- const fullTask = `${targetInstruction}\n\n【专项排查分工】:${exp.task}`;
138
- return `subagent({ agent: ${JSON.stringify(exp.id)}, task: ${JSON.stringify(fullTask)} });`;
139
- })
140
- .join("\n");
141
-
142
- const maxBackticks = (callsExample.match(/`+/g) || []).reduce((max, m) => Math.max(max, m.length), 2);
143
- const fence = "`".repeat(maxBackticks + 1);
144
-
145
- return `## 🚀 执行方式:多 Subagent 并发专家审查 (当前配置并发数: ${count} 个专家)
146
-
147
- 当前已配置并行启动以下 ${count} 个专家子代理进行分工审查:
148
-
149
- ${listText}
150
-
151
- ### 协作审查执行规范:
152
- 1. **并发调用子代理**:请在当前回合使用 \`subagent\` 工具**同时并行唤起**上述 ${count} 个专家子代理(单回合发起 ${count} 个并发 tool_call,严禁串行逐个调用):
153
- ${fence}js
154
- ${callsExample}
155
- ${fence}
156
- 2. **主审裁判长汇总整理**:当所有专家子代理执行完毕返回发现后,请你作为主审裁判长${gateEnabled ? "(门禁裁决)" : ""}:
157
- - 全面综合各专家的审查意见,对相同问题进行去重,剔除误报和低置信度内容(注意:项目中合法的内部 GM / Debug 调试工具在确保与正式生产环境隔离的前提下免检)。
158
- - 严格按照《核心代码审查准则》的 **[P0~P3]** 等级标准排布审查清单。
159
- - 给出最终综合裁决与一句话中文总评。
160
- 3. **语言强制要求**:所有任务入参、思考分析过程、综合汇报与最终报告必须 100% 为纯正中文,严禁出现任何英文段落或未翻译小标题!`;
161
- }
162
-
163
81
  function setReviewWidget(ctx: ExtensionContext, active: boolean) {
164
82
  if (!ctx.hasUI) return;
165
83
  if (!active) {
@@ -213,31 +131,31 @@ type ReviewTarget =
213
131
 
214
132
  // 针对不同审查目标的中文提示词
215
133
  const LITE_REVIEW_PROMPT =
216
- "【极速体检模式】请首先运行 `git diff` 获取代码改动,并针对改动涉及的核心函数按需使用 `read` 查阅周边上下文(如所在完整方法实现与生命周期),快速排查高危逻辑异常、运行时崩溃与防御性缺陷。注意:项目中内部 GM/Debug 调试工具在确认与生产环境隔离的前提下免检,切勿误判;但若正式生产包可直接触达仍属漏洞。结合上下文精准核验后直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
134
+ "【极速体检模式】请首先运行 `git diff` 锁定代码变动范围。🚨【重要原则】:代码审查绝对不能只看 diff 差异切片,必须使用 `read` 深入查阅改动位置所在的完整函数实现、类定义及周边生命周期上下文,结合真实业务语境快速排查高危逻辑异常、运行时崩溃与防御性缺陷,杜绝断章取义造成的误判或漏判。注意:项目中内部 GM/Debug 调试工具在确认与生产环境隔离的前提下免检,切勿误判;但若正式生产包可直接触达仍属漏洞。结合完整上下文精准核验后直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
217
135
 
218
136
  const FULL_REVIEW_PROMPT =
219
- "【全量深度审查模式】请对当前代码改动展开深度的上下文关联审查:首先运行 `git diff` 全量查阅改动,必须使用 `read` / `grep` 深入查阅改动方法所在的完整类定义、调用方契约、状态机与生命周期等关键上下文,深入排查业务逻辑隐患、边界异常、并发安全、性能GC开销与架构契约。注意:项目中内部 GM 调试面板与测试辅助逻辑在已隔离于正式生产包的前提下免检,切勿误判。结合完整代码脉络直接输出详尽审查清单。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
137
+ "【全量深度审查模式】请对当前代码改动展开深度的上下文关联审查:🚨【最高核心原则】:严禁仅看 diff 差异碎片断章取义!审查必须先运行 `git diff` 全量锁定改动范围,再针对每一个核心改动点,必须使用 `read` / `grep` 深入查阅改动方法所在的完整类定义、调用方契约、状态机与生命周期等全局上下文,深入排查业务逻辑隐患、边界异常、并发安全、性能GC开销与架构契约。注意:项目中内部 GM 调试面板与测试辅助逻辑在已隔离于正式生产包的前提下免检,切勿误判。结合完整代码脉络与上下文直接输出详尽审查清单。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
220
138
 
221
139
  const UNCOMMITTED_PROMPT =
222
- "请审查当前代码的所有改动(包含暂存区、未暂存区以及新增文件)。先运行 `git diff` 与 `git status` 获取改动,再针对关键改动按需使用 `read` / `grep` 查阅周边上下文代码与调用链路,排查真实业务缺陷与边界异常(注意:项目中内部 GM/Debug 调试指令在与生产环境隔离的前提下属于正常研发代码,勿误判),结合完整上下文直接输出审查发现。严禁输出任何步骤清单或待办列表。所有输出必须使用纯正中文。";
140
+ "请审查当前代码的所有改动(包含暂存区、未暂存区以及新增文件)。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合代码的上下文一起看!请先运行 `git diff` 与 `git status` 获取改动范围,再针对关键改动必须使用 `read` / `grep` 查阅周边上下文代码、所在函数的完整实现与调用链路,排查真实业务缺陷与边界异常(注意:项目中内部 GM/Debug 调试指令在与生产环境隔离的前提下属于正常研发代码,勿误判),结合完整上下文直接输出审查发现。严禁输出任何步骤清单或待办列表。所有输出必须使用纯正中文。";
223
141
 
224
142
  const BASE_BRANCH_PROMPT_WITH_MERGE_BASE =
225
- "请审查当前分支相对于基准分支 '{baseBranch}' 的改动(合并基准 commit: {mergeBaseSha})。运行 `git diff {mergeBaseSha}` 查看改动,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
143
+ "请审查当前分支相对于基准分支 '{baseBranch}' 的改动(合并基准 commit: {mergeBaseSha})。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!运行 `git diff {mergeBaseSha}` 查看改动后,针对修改点必须使用 `read` / `grep` 结合所在完整函数、类定义与周边调用上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
226
144
 
227
145
  const BASE_BRANCH_PROMPT_FALLBACK =
228
- "请审查当前分支相对于基准分支 '{branch}' 的改动。先使用 `git merge-base` 与 `git diff` 查看改动,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
146
+ "请审查当前分支相对于基准分支 '{branch}' 的改动。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!先使用 `git merge-base` 与 `git diff` 查看改动,再使用 `read` / `grep` 查阅改动点所在的完整函数与周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
229
147
 
230
148
  const COMMIT_PROMPT_WITH_TITLE =
231
- '请审查提交 commit {sha} ("{title}") 引入的代码改动。运行 `git show {sha}` 查看差异,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
149
+ '请审查提交 commit {sha} ("{title}") 引入的代码改动。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!运行 `git show {sha}` 查看差异后,针对修改点必须使用 `read` / `grep` 查阅所在完整函数与周边调用上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
232
150
 
233
151
  const COMMIT_PROMPT =
234
- "请审查提交 commit {sha} 引入的代码改动。运行 `git show {sha}` 查看差异,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
152
+ "请审查提交 commit {sha} 引入的代码改动。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!运行 `git show {sha}` 查看差异后,针对修改点必须使用 `read` / `grep` 查阅所在完整函数与周边调用上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
235
153
 
236
154
  const PULL_REQUEST_PROMPT =
237
- '请审查 Pull Request #{prNumber} ("{title}") 相对于基准分支 \'{baseBranch}\' 的改动(合并基准 commit: {mergeBaseSha})。运行 `git diff {mergeBaseSha}` 查看改动,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
155
+ '请审查 Pull Request #{prNumber} ("{title}") 相对于基准分支 \'{baseBranch}\' 的改动(合并基准 commit: {mergeBaseSha})。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!运行 `git diff {mergeBaseSha}` 查看改动后,针对修改点必须使用 `read` / `grep` 查阅所在完整函数与周边调用上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
238
156
 
239
157
  const PULL_REQUEST_PROMPT_FALLBACK =
240
- '请审查 Pull Request #{prNumber} ("{title}") 相对于基准分支 \'{baseBranch}\' 的改动。先运行 `git diff` 查看改动,并按需使用 `read` / `grep` 结合周边上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
158
+ '请审查 Pull Request #{prNumber} ("{title}") 相对于基准分支 \'{baseBranch}\' 的改动。🚨【重要原则】:代码审查不能只看 diff 差异部分,必须结合完整代码上下文一起看!先运行 `git diff` 查看改动后,针对修改点必须使用 `read` / `grep` 查阅所在完整函数与周边调用上下文深入分析,直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。';
241
159
 
242
160
  const FOLDER_REVIEW_PROMPT =
243
161
  "请对以下目录/文件路径的代码进行快照审查:{paths}。直接读取这些文件并结合上下文直接输出审查发现。严禁输出任何步骤清单。所有输出必须使用纯正中文。";
@@ -248,7 +166,13 @@ const REVIEW_RUBRIC = `> 💡【工程环境与上下文声明】:
248
166
  >
249
167
  > 🚨【最高执行原则】:
250
168
  > 1. **全流程纯中文**:思维链(Thinking)、推理分析与最终报告必须 100% 使用纯正中文,严禁包含任何英文段落或英文小标题!
251
- > 2. **结合上下文,拒绝断章取义**:仅看 diff 的片段容易产生误判。请**先运行 \`git diff\` 锁定变动,再针对改动涉及的关键方法、类生命周期或调用方,按需使用 \`read\` 或 \`grep\` 查阅必要的上下文代码**(精准核验,切勿无目的漫游遍历),结合真实完整的业务上下文做出准确裁决!
169
+ > 2. **结合完整上下文,严禁只看 diff 差异切片**:
170
+ > - 仅看 diff 局部的 +/- 增删碎片极易脱离语境断章取义,造成重大误判(如误把外部已保护的入参判为缺少校验、未看到完整函数的生命周期流转、或忽视既有架构的已有防护)。
171
+ > - **必须遵循“Diff 锁定改动范围 -> Read/Grep 深入查阅上下文”的严谨审查流程**:
172
+ > - 步骤一:先运行 \`git diff\` 或 \`git show\` 锁定被修改的文件与行号范围;
173
+ > - 步骤二:对每一个核心修改点,**必须使用 \`read\` 查阅其所在的完整函数实现、类定义、状态机与生命周期**;
174
+ > - 步骤三:按需使用 \`grep\` 追踪上下游调用方契约与数据来源;
175
+ > - 步骤四:只有结合完整上下文验证成立、证据确凿的真实缺陷,才允许记录到审查清单中!坚决杜绝因仅看 diff 片段产生的假警报与误报。
252
176
  > 3. **直接审查,拒绝繁琐步骤**:严禁打印任何工作流待办清单(Checklist)或环境测试命令!
253
177
 
254
178
  # 核心代码审查准则
@@ -256,16 +180,16 @@ const REVIEW_RUBRIC = `> 💡【工程环境与上下文声明】:
256
180
  你是一名资深技术专家,正在审查提交的代码改动。请结合完整代码上下文,直击本质,拦截真实缺陷:
257
181
 
258
182
  ## 重点排查范围
259
- 1. **代码正确性与边界**:结合函数整体逻辑与调用方,排查业务逻辑缺陷、空指针/未定义引用、边界越界、生命周期异常、未捕获的运行时崩溃。
183
+ 1. **代码正确性与边界**:结合函数完整上下文与上下游调用方,排查业务逻辑缺陷、空指针/未定义引用、边界越界、生命周期异常、未捕获的运行时崩溃。
260
184
  2. **并发与状态安全**:结合上下文状态机与生命周期,排查竞态条件、死锁隐患、异步缺少等待、脏状态残留。
261
- 3. **性能与内存开销**:高频主循环内的大量堆内存分配 (GC 压力)、不必要的深拷贝、高复杂度算法、资源句柄泄露。
262
- 4. **输入验证与安全边界**:外部未受信任输入是否缺乏合法性检查、参数未做参数化转义、类型断言与长度/范围限制,是否存在跨目录访问或越权风险。
185
+ 3. **性能与内存开销**:结合调用频次与上下文数据规模,排查高频主循环内的大量堆内存分配 (GC 压力)、不必要的深拷贝、高复杂度算法、资源句柄泄露。
186
+ 4. **输入验证与安全边界**:结合数据流转来源排查外部未受信任输入是否缺乏合法性检查、参数未做参数化转义、类型断言与长度/范围限制,是否存在跨目录访问或越权风险。
263
187
  5. **只关注本次改动**:严禁将改动前既有的历史代码当作本次改动的缺陷。
264
188
 
265
189
  ## 严格过滤误报
266
190
  - ❌ 严禁提出吹毛求疵、纯属个人审美的风格建议。
267
191
  - ❌ 严禁提出 Linter / 类型检查器会自动捕获的浅层格式建议。
268
- - ❌ 严禁脱离上下文进行无端猜测,每条问题必须有明确的代码与上下文事实证据。
192
+ - ❌ 严禁脱离上下文进行无端猜测,每条问题必须有明确的代码与完整上下文事实证据。
269
193
  - 💡 **开发与测试工具免检准则**:在游戏、客户端与业务系统中,\`GM\`(Game Master/内部调试面板)、\`Debug\` 指令、测试出战模拟等属于受信任的研发辅助逻辑,**在通过编译宏(如 \`#if UNITY_EDITOR || DEVELOPMENT_BUILD\`)或环境判断已隔离于正式生产环境的前提下,严禁将其误判为安全漏洞或缺陷**;但若此类入口在正式生产发布包中无防护可被客户端或外部请求触达,仍属 P0 安全隐患,必须报告。
270
194
 
271
195
  ## 缺陷等级标记 [P0~P3]
@@ -278,8 +202,8 @@ const REVIEW_RUBRIC = `> 💡【工程环境与上下文声明】:
278
202
  ### 审查发现清单
279
203
  每个问题按以下格式列出(若无存活缺陷,明确输出:\`未发现存活的代码缺陷,代码质量良好,建议合并。\`):
280
204
  - **[P0|P1|P2|P3] 简短标题**:\`文件路径:行号\`
281
- - **缺陷说明**:结合上下文简明说明后果与触发场景。
282
- - **代码证据**:引用关键代码及上下文。
205
+ - **缺陷说明**:结合完整代码上下文简明说明后果与触发场景。
206
+ - **代码证据**:引用关键代码及所在上下文。
283
207
  - **修改建议**:给出最小化修复思路或代码替换块(可使用 \`\`\`suggestion)。
284
208
 
285
209
  ### 综合裁决
@@ -1062,6 +986,13 @@ export default function reviewExtension(pi: ExtensionAPI) {
1062
986
  ...runtimeSettings,
1063
987
  };
1064
988
 
989
+ const sessionModel = ctx.model;
990
+ const thinkingLevel = ctx.thinkingLevel ?? pi.getThinkingLevel();
991
+ if (settings.mode === "subagents" && !sessionModel) {
992
+ ctx.ui.notify("当前未选择模型,请先使用 /model 选择模型。", "error");
993
+ return;
994
+ }
995
+
1065
996
  let effectiveFreshSession = useFreshSession;
1066
997
 
1067
998
  if (effectiveFreshSession) {
@@ -1110,8 +1041,10 @@ export default function reviewExtension(pi: ExtensionAPI) {
1110
1041
 
1111
1042
  let fullPrompt = REVIEW_RUBRIC;
1112
1043
 
1113
- if (settings.mode === "subagents") {
1114
- fullPrompt += `\n\n---\n\n${buildSubagentOrchestrationPrompt(settings.concurrency, settings.gateEnabled, prompt)}`;
1044
+ if (settings.mode === "subagents" && sessionModel) {
1045
+ fullPrompt += `\n\n---\n\n${buildSubagentOrchestrationPrompt(
1046
+ settings.concurrency, settings.gateEnabled, prompt, sessionModel, thinkingLevel,
1047
+ )}`;
1115
1048
  }
1116
1049
 
1117
1050
  fullPrompt += `\n\n---\n\n## 本次审查任务指示\n\n${prompt}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-review-zh",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Pi 交互式 AI 代码审查扩展(支持单模型与多 Subagent 并发 2~6 专家自由切换,Codex 经典架构)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,91 @@
1
+ interface ReviewExpert {
2
+ id: string;
3
+ label: string;
4
+ desc: string;
5
+ task: string;
6
+ }
7
+
8
+ const ALL_EXPERTS: ReviewExpert[] = [
9
+ {
10
+ id: "pi-review.bugbot",
11
+ label: "Bug 猎手 (Bugbot)",
12
+ desc: "逻辑缺陷、空指针、边界溢出、死锁与运行时崩溃",
13
+ task: "深入排查本次代码改动中的业务逻辑缺陷、空指针、边界异常、并发竞态与未捕获的运行时异常",
14
+ },
15
+ {
16
+ id: "pi-review.security-review",
17
+ label: "安全专家 (Security)",
18
+ desc: "输入参数合法性校验、跨目录边界防护与权限隔离",
19
+ task: "深入排查本次代码改动中的防御性编码缺陷、外部输入未做类型/范围校验、边界防护不足等健壮性隐患",
20
+ },
21
+ {
22
+ id: "pi-review.perf-review",
23
+ label: "性能探针 (Perf)",
24
+ desc: "循环内GC内存分配、CPU热点消耗、算法复杂度与资源泄露",
25
+ task: "深入排查本次代码改动中的性能退化、高频循环内无谓内存分配 (GC压力) 与算法复杂度",
26
+ },
27
+ {
28
+ id: "pi-review.claude-md-compliance",
29
+ label: "契约合规 (Compliance)",
30
+ desc: "架构契约、设计模式、模块边界与规范遵循",
31
+ task: "排查本次代码改动是否违反项目既有架构契约、模块封装规范与规范指南",
32
+ },
33
+ {
34
+ id: "pi-review.code-comments",
35
+ label: "注释与可读性 (Comments)",
36
+ desc: "注释与代码逻辑倒挂、误导性命名与维护性隐患",
37
+ task: "排查本次代码改动中的可读性隐患、注释与逻辑不符、误导性命名与维护风险",
38
+ },
39
+ {
40
+ id: "pi-review.history-context",
41
+ label: "历史脉络 (History)",
42
+ desc: "结合 Git 历史演进判断意图,防止历史问题回归",
43
+ task: "结合代码演变历史,排查本次改动是否破坏既有历史契约或重现已知缺陷",
44
+ },
45
+ ];
46
+
47
+ export function buildSubagentOrchestrationPrompt(
48
+ concurrency: number,
49
+ gateEnabled: boolean,
50
+ targetInstruction: string,
51
+ sessionModel: { provider: string; id: string },
52
+ thinkingLevel: string,
53
+ ): string {
54
+ const count = Math.min(6, Math.max(2, concurrency));
55
+ const selected = ALL_EXPERTS.slice(0, count);
56
+
57
+ const listText = selected.map((exp, idx) => `${idx + 1}. **${exp.label}** (\`${exp.id}\`):${exp.desc}`).join("\n");
58
+ // 每次执行显式固定当前会话模型和档位,避免子代理默认配置覆盖会话选择。
59
+ const model = `${sessionModel.provider}/${sessionModel.id}:${thinkingLevel}`;
60
+ const tasks = selected.map((exp) => ({
61
+ key: exp.id,
62
+ agent: exp.id,
63
+ model,
64
+ task: `${targetInstruction}\n\n【专项排查分工】:${exp.task}`,
65
+ }));
66
+ const callsExample = `subagent(${JSON.stringify({
67
+ async: true,
68
+ workflowScript: `const results = await runs.all(${JSON.stringify(tasks)});\nreturn results;`,
69
+ }, null, 2)});`;
70
+
71
+ const maxBackticks = (callsExample.match(/`+/g) || []).reduce((max, m) => Math.max(max, m.length), 2);
72
+ const fence = "`".repeat(maxBackticks + 1);
73
+
74
+ return `## 🚀 执行方式:多 Subagent 并发专家审查 (当前配置并发数: ${count} 个专家)
75
+
76
+ 当前已配置并行启动以下 ${count} 个专家子代理进行分工审查:
77
+
78
+ ${listText}
79
+
80
+ ### 协作审查执行规范:
81
+ 1. **上下文审查铁律**:所有专家在审查时,**绝对严禁仅看 diff 差异片段断章取义**!必须结合改动位置所在的完整函数实现、类定义、状态机与调用方上下文深入分析,确认在真实全局代码执行流中确实存在问题后才提出。
82
+ 2. **并发调用子代理**:先调用 \`subagent({ action: "list", capabilities: true })\`,确认上述专家均可执行且未禁用;再通过下方**一个异步工作流**并行启动全部专家。每个专家必须使用示例中的 \`model\` 参数,继承本次会话模型与思考档位(${thinkingLevel}),不得省略或改用代理默认档位。运行失败时报告具体原因并停止,不得静默更换模型或执行方式:
83
+ ${fence}js
84
+ ${callsExample}
85
+ ${fence}
86
+ 3. **主审裁判长汇总整理**:当所有专家子代理执行完毕返回发现后,请你作为主审裁判长${gateEnabled ? "(门禁裁决)" : ""}:
87
+ - 全面综合各专家的审查意见,重点甄别并剔除脱离上下文仅看 diff 产生的假警报,对相同问题进行去重,剔除误报和低置信度内容(注意:项目中合法的内部 GM / Debug 调试工具在确保与正式生产环境隔离的前提下免检)。
88
+ - 严格按照《核心代码审查准则》的 **[P0~P3]** 等级标准排布审查清单。
89
+ - 给出最终综合裁决与一句话中文总评。
90
+ 4. **语言强制要求**:所有任务入参、思考分析过程、综合汇报与最终报告必须 100% 为纯正中文,严禁出现任何英文段落或未翻译小标题!`;
91
+ }
@@ -0,0 +1,52 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { readFile } from 'node:fs/promises';
4
+ import ts from 'typescript';
5
+
6
+ const source = await readFile(new URL('../src/orchestration.ts', import.meta.url), 'utf8');
7
+ const compiled = ts.transpileModule(source, {
8
+ compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext },
9
+ }).outputText;
10
+ const { buildSubagentOrchestrationPrompt } = await import(`data:text/javascript;base64,${Buffer.from(compiled).toString('base64')}`);
11
+ const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
12
+
13
+ // 执行实际生成的工作流,使用假运行器捕获请求,不启动模型或子代理。
14
+ async function runExample(prompt) {
15
+ const example = prompt.match(/(`{3,})js\n([\s\S]*?)\n\1/);
16
+ assert.ok(example, '应包含可执行的工作流示例');
17
+ let request;
18
+ new Function('subagent', example[2])(value => { request = value; });
19
+ assert.equal(request.async, true);
20
+ let tasks;
21
+ const results = [{ output: '审查完成' }];
22
+ const actual = await new AsyncFunction('runs', request.workflowScript)({
23
+ all: async value => { tasks = value; return results; },
24
+ });
25
+ assert.equal(actual, results);
26
+ return tasks;
27
+ }
28
+
29
+ test('所有专家在不同并发数下继承会话模型及全部思考档位', async () => {
30
+ for (const thinking of ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']) {
31
+ for (const count of [2, 3, 4, 5, 6]) {
32
+ const prompt = buildSubagentOrchestrationPrompt(count, true, '检查当前差异', { provider: '会话提供方', id: '会话模型' }, thinking);
33
+ const tasks = await runExample(prompt);
34
+ assert.equal(tasks.length, count);
35
+ assert.equal(new Set(tasks.map(task => task.key)).size, count);
36
+ for (const task of tasks) {
37
+ assert.equal(task.model, `会话提供方/会话模型:${thinking}`);
38
+ assert.match(task.task, /检查当前差异/);
39
+ }
40
+ assert.match(prompt, /capabilities: true/);
41
+ }
42
+ }
43
+ });
44
+
45
+ test('用户任务中的引号、换行和代码围栏不破坏工作流或模型参数', async () => {
46
+ const target = '检查 "路径"\n```ts\nconst value = `${input}`;\n```\n反斜线 \\';
47
+ const prompt = buildSubagentOrchestrationPrompt(3, false, target, { provider: '代理', id: '模型/别名' }, 'max');
48
+ const tasks = await runExample(prompt);
49
+ assert.ok(tasks.every(task => task.task.startsWith(target)));
50
+ assert.ok(tasks.every(task => task.model === '代理/模型/别名:max'));
51
+ assert.doesNotMatch(prompt, /(门禁裁决)/);
52
+ });