@unifan/pi-review-zh 1.0.6 → 1.0.7
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/index.ts +28 -2
- package/package.json +1 -1
- package/src/cli-args.ts +7 -1
- package/src/config.ts +2 -2
- package/src/directive.ts +41 -4
- package/src/review-run.ts +12 -1
package/index.ts
CHANGED
|
@@ -25,11 +25,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
25
25
|
registerReviewReportTool(pi);
|
|
26
26
|
registerPiReviewRenderer(pi);
|
|
27
27
|
pi.registerCommand("review", {
|
|
28
|
-
description: "
|
|
28
|
+
description: "启动日常 AI 代码审查 (3 大核心专家 + 门禁裁判长)。--lite 极速单兵,--perf 性能审查,--full 全量会诊。",
|
|
29
29
|
getArgumentCompletions: (prefix: string) => {
|
|
30
30
|
const options = [
|
|
31
|
-
{ value: "--lite", label: "--lite", description: "极速单专家审查 (
|
|
31
|
+
{ value: "--lite", label: "--lite", description: "极速单专家审查 (无门禁,低延迟极省 Token)" },
|
|
32
32
|
{ value: "--perf", label: "--perf", description: "专项性能与基准测试审查 (GC/内存分配/CPU/Benchmark)" },
|
|
33
|
+
{ value: "--full", label: "--full", description: "全量 6 专家深度会诊 (Bugbot/安全/合规/历史/注释/性能 + 门禁)" },
|
|
33
34
|
{ value: "--gate-model", label: "--gate-model", description: "指定当前审查的门禁裁判模型" },
|
|
34
35
|
];
|
|
35
36
|
const trimmed = prefix.trimStart();
|
|
@@ -69,6 +70,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
69
70
|
input: parsed.input,
|
|
70
71
|
lite: parsed.lite,
|
|
71
72
|
perf: parsed.perf,
|
|
73
|
+
full: parsed.full,
|
|
72
74
|
gateModel: parsed.gateModel,
|
|
73
75
|
});
|
|
74
76
|
if (!prepared) {
|
|
@@ -139,6 +141,30 @@ export default function (pi: ExtensionAPI) {
|
|
|
139
141
|
},
|
|
140
142
|
});
|
|
141
143
|
|
|
144
|
+
pi.registerCommand("review-full", {
|
|
145
|
+
description: "全量 6 专家深度代码审查会诊 (Bugbot/安全/合规/历史/注释/性能 + 门禁总裁判)",
|
|
146
|
+
handler: async (args, ctx) => {
|
|
147
|
+
const notify = (msg: string, level: "info" | "warning" | "error" = "info") => {
|
|
148
|
+
if (ctx.hasUI) ctx.ui.notify(msg, level);
|
|
149
|
+
else console.log(`pi-review: ${msg}`);
|
|
150
|
+
};
|
|
151
|
+
try {
|
|
152
|
+
const { config, legacyWarnings } = loadConfig();
|
|
153
|
+
for (const w of legacyWarnings) notify(`pi-review 提示: ${w}`, "warning");
|
|
154
|
+
pi.sendMessage({ customType: "pi-review", content: args ? `/review-full ${args}` : "/review-full", display: true });
|
|
155
|
+
const prepared = await prepareRun({ cwd: ctx.cwd, input: args, full: true });
|
|
156
|
+
if (!prepared) {
|
|
157
|
+
notify("没有检测到需要审查的内容 (未找到修改、PR 或非 Git 仓库)。", "info");
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
pi.sendMessage({ customType: "pi-review-directive", content: prepared.directiveText, display: false }, { triggerTurn: true });
|
|
161
|
+
} catch (err) {
|
|
162
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
163
|
+
notify(`全量代码审查启动失败: ${message}`, "error");
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
142
168
|
pi.registerCommand("review-config", {
|
|
143
169
|
description: "编辑代码审查配置 (~/.pi/agent/pi-review.json)",
|
|
144
170
|
handler: async (_args, ctx) => {
|
package/package.json
CHANGED
package/src/cli-args.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface ParsedReviewArgs {
|
|
|
11
11
|
lite: boolean;
|
|
12
12
|
/** Dedicated performance review mode: perf-reviewer with benchmark capabilities. */
|
|
13
13
|
perf: boolean;
|
|
14
|
+
/** Full multi-agent review mode: all 6 reviewers + gate. */
|
|
15
|
+
full: boolean;
|
|
14
16
|
/** Override the gate model for this run (otherwise config.gate.model). */
|
|
15
17
|
gateModel?: string;
|
|
16
18
|
}
|
|
@@ -24,7 +26,7 @@ const LEGACY_VALUED_FLAGS = new Set([
|
|
|
24
26
|
|
|
25
27
|
export function parseReviewArgs(raw: string): ParsedReviewArgs {
|
|
26
28
|
const tokens = tokenize(raw);
|
|
27
|
-
const result: ParsedReviewArgs = { noSpawn: false, lite: false, perf: false };
|
|
29
|
+
const result: ParsedReviewArgs = { noSpawn: false, lite: false, perf: false, full: false };
|
|
28
30
|
const inputParts: string[] = [];
|
|
29
31
|
|
|
30
32
|
for (let i = 0; i < tokens.length; i++) {
|
|
@@ -45,6 +47,10 @@ export function parseReviewArgs(raw: string): ParsedReviewArgs {
|
|
|
45
47
|
result.perf = true;
|
|
46
48
|
continue;
|
|
47
49
|
}
|
|
50
|
+
if (t === "--full") {
|
|
51
|
+
result.full = true;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
48
54
|
if (t === "--gate-model") {
|
|
49
55
|
const id = tokens[++i];
|
|
50
56
|
if (id) result.gateModel = id;
|
package/src/config.ts
CHANGED
|
@@ -55,7 +55,7 @@ export const DEFAULT_CONFIG: PiReviewConfig = {
|
|
|
55
55
|
"history-context": {
|
|
56
56
|
id: "history-context",
|
|
57
57
|
label: "History Context",
|
|
58
|
-
enabled:
|
|
58
|
+
enabled: false,
|
|
59
59
|
model: "inherit",
|
|
60
60
|
},
|
|
61
61
|
"security-review": {
|
|
@@ -67,7 +67,7 @@ export const DEFAULT_CONFIG: PiReviewConfig = {
|
|
|
67
67
|
"code-comments": {
|
|
68
68
|
id: "code-comments",
|
|
69
69
|
label: "Code Comments",
|
|
70
|
-
enabled:
|
|
70
|
+
enabled: false,
|
|
71
71
|
model: "inherit",
|
|
72
72
|
},
|
|
73
73
|
conventions: {
|
package/src/directive.ts
CHANGED
|
@@ -237,9 +237,9 @@ export function buildWorkflowScript(input: {
|
|
|
237
237
|
const READ_ONLY_PREFIX =
|
|
238
238
|
"只读任务(READ-ONLY)——仅执行审查分析与基准测试。严禁修改源码文件。仅返回审查发现。所有分析总结、问题描述与建议必须使用纯正中文。";
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
lines.push("");
|
|
242
|
-
lines.push("
|
|
240
|
+
lines.push("let reviewers;");
|
|
241
|
+
lines.push("try {");
|
|
242
|
+
lines.push(" reviewers = await runs.all([");
|
|
243
243
|
for (const r of reviewers) {
|
|
244
244
|
const tb = LEAN_BUDGETS.defaultToolBudget;
|
|
245
245
|
const tbForId = r.id === "history-context" ? LEAN_BUDGETS.historyToolBudget : tb;
|
|
@@ -303,7 +303,44 @@ export function buildWorkflowScript(input: {
|
|
|
303
303
|
);
|
|
304
304
|
lines.push(" },");
|
|
305
305
|
}
|
|
306
|
-
lines.push("]);");
|
|
306
|
+
lines.push(" ]);");
|
|
307
|
+
lines.push("} catch (firstErr) {");
|
|
308
|
+
lines.push(" // 自动网络重试保护:若首次并发因网络波动超时,自动延迟800ms后重试一次");
|
|
309
|
+
lines.push(" await new Promise((resolve) => setTimeout(resolve, 800));");
|
|
310
|
+
lines.push(" reviewers = await runs.all([");
|
|
311
|
+
for (const r of reviewers) {
|
|
312
|
+
const tb = LEAN_BUDGETS.defaultToolBudget;
|
|
313
|
+
const tbForId = r.id === "history-context" ? LEAN_BUDGETS.historyToolBudget : tb;
|
|
314
|
+
const taskParts = [
|
|
315
|
+
READ_ONLY_PREFIX,
|
|
316
|
+
`读取 ${JSON.stringify(diffPath)} 作为改动内容——diff 是权威的修改记录,工作区文件仅作上下文参考。所有问题描述必须使用中文。`,
|
|
317
|
+
`你的当前工作区为目标工作区 (${JSON.stringify(workspacePath)})。在此目录下执行必要的 read/grep。`,
|
|
318
|
+
"在额度内完成分析;最终回复必须输出格式规范的 Markdown 审查报告(包含中文 Summary / Findings / Coverage 章节)并停止。所有问题描述、证据引用和总结必须使用纯正中文。",
|
|
319
|
+
];
|
|
320
|
+
const modelClause =
|
|
321
|
+
r.model && r.model !== "inherit"
|
|
322
|
+
? `\n model: ${JSON.stringify(r.model)},`
|
|
323
|
+
: "";
|
|
324
|
+
lines.push(" {");
|
|
325
|
+
lines.push(` key: ${JSON.stringify(r.id)},`);
|
|
326
|
+
lines.push(` agent: ${JSON.stringify(leanAgentName(r.id))},`);
|
|
327
|
+
lines.push(` task: [`);
|
|
328
|
+
for (const part of taskParts) {
|
|
329
|
+
lines.push(` ${JSON.stringify(part)},`);
|
|
330
|
+
}
|
|
331
|
+
lines.push(` ].join(" "),`);
|
|
332
|
+
lines.push(` cwd: ${JSON.stringify(workspacePath)},`);
|
|
333
|
+
if (r.thinking) {
|
|
334
|
+
lines.push(` thinking: ${JSON.stringify(r.thinking)},`);
|
|
335
|
+
}
|
|
336
|
+
lines.push(` toolBudget: { soft: ${tbForId.soft}, hard: ${tbForId.hard} },`);
|
|
337
|
+
lines.push(
|
|
338
|
+
` turnBudget: { maxTurns: ${budgets.turnBudget.maxTurns}, graceTurns: ${budgets.turnBudget.graceTurns} },${modelClause}`,
|
|
339
|
+
);
|
|
340
|
+
lines.push(" },");
|
|
341
|
+
}
|
|
342
|
+
lines.push(" ]);");
|
|
343
|
+
lines.push("}");
|
|
307
344
|
lines.push("");
|
|
308
345
|
|
|
309
346
|
// Gate
|
package/src/review-run.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface PrepareRunInput {
|
|
|
49
49
|
lite?: boolean;
|
|
50
50
|
/** Support `--perf` performance & benchmark mode. */
|
|
51
51
|
perf?: boolean;
|
|
52
|
+
/** Support `--full` all 6 reviewers mode. */
|
|
53
|
+
full?: boolean;
|
|
52
54
|
/** Optional per-run gate model override. */
|
|
53
55
|
gateModel?: string;
|
|
54
56
|
/** Set false for dry-runs — pruning is a side effect a dry run must not have. */
|
|
@@ -150,7 +152,16 @@ export async function prepareRun(input: PrepareRunInput): Promise<PreparedRun |
|
|
|
150
152
|
? [{ id: "perf-review", label: "Performance Review", enabled: true, model: "inherit" }]
|
|
151
153
|
: input.lite
|
|
152
154
|
? [{ id: "lite-review", label: "Lite Review", enabled: true, model: "inherit" }]
|
|
153
|
-
:
|
|
155
|
+
: input.full
|
|
156
|
+
? [
|
|
157
|
+
{ id: "claude-md-compliance", label: "Claude-MD Compliance", enabled: true, model: "inherit" },
|
|
158
|
+
{ id: "bugbot", label: "Bugbot", enabled: true, model: "inherit" },
|
|
159
|
+
{ id: "security-review", label: "Security Review", enabled: true, model: "inherit" },
|
|
160
|
+
{ id: "history-context", label: "History Context", enabled: true, model: "inherit" },
|
|
161
|
+
{ id: "code-comments", label: "Code Comments", enabled: true, model: "inherit" },
|
|
162
|
+
{ id: "perf-review", label: "Performance Review", enabled: true, model: "inherit" },
|
|
163
|
+
]
|
|
164
|
+
: reviewersForRouting(target, config, profile);
|
|
154
165
|
const skippedReasons = adaptiveSkips(profile);
|
|
155
166
|
// The report tool uses this to reject findings that did not come from this
|
|
156
167
|
// run's roster (stale-artifact contamination guard).
|