@zephyrdeng/pi-review 0.15.2 → 0.16.1

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/dist/screen.js ADDED
@@ -0,0 +1,284 @@
1
+ // pi-review screen: gate-grade Jev screening — typed judgments only, no LLM
2
+ // prose generation on this path.
3
+ //
4
+ // Each file is sliced into declaration-level hunks deterministically; one
5
+ // System One call fans out a catch-all Noul plus one Noul per catalog defect
6
+ // pattern per hunk; hits assemble ReviewFinding-shaped results from pattern
7
+ // templates. Catalog misses still surface as "unmatched defect signal"
8
+ // findings, so the gate never silently drops a strong catch-all signal —
9
+ // deeper review (full `pi-review`) is the escape hatch, not silent loss.
10
+ // Mechanism and measurements: docs/research/jev-screening-case.md.
11
+ import fs from "node:fs";
12
+ import { evaluateNouls, resolveJevConnection, GENERIC_NOUL_CRITERIA, } from "./jev.js";
13
+ import { expandMaybeHome, fail } from "./utils.js";
14
+ /** Probability floor for both the catch-all and per-pattern questions. */
15
+ export const SCREEN_THRESHOLD = 0.6;
16
+ /** ponytail: beyond this many hunks per file the tail merges into the last hunk; deeper review owns huge files. */
17
+ export const MAX_HUNKS_PER_FILE = 40;
18
+ /** The screening API accepted 561 Nouls in one call; chunk with headroom below that. */
19
+ export const MAX_QUESTIONS_PER_CALL = 480;
20
+ /**
21
+ * Defect-pattern catalog. Coverage is the product knob: a hit assembles the
22
+ * finding from the template with zero LLM prose; a miss falls back to the
23
+ * catch-all finding. Add patterns as history shows repeated misses.
24
+ */
25
+ export const SCREEN_PATTERNS = {
26
+ off_by_one_loop: {
27
+ title: "Off-by-one loop bound reads past array end",
28
+ severity: "critical",
29
+ category: "correctness",
30
+ recommendation: "Change `i <= arr.length` to `i < arr.length`.",
31
+ },
32
+ unawaited_async: {
33
+ title: "Async call not awaited (fire-and-forget)",
34
+ severity: "critical",
35
+ category: "data-loss",
36
+ recommendation: "await the promise or explicitly handle rejection; silent persistence loss otherwise.",
37
+ },
38
+ sql_injection: {
39
+ title: "SQL injection via string interpolation",
40
+ severity: "critical",
41
+ category: "security",
42
+ recommendation: "Use parameterized queries instead of template-string interpolation.",
43
+ },
44
+ slice_off_by_one: {
45
+ title: "slice() end index off by one drops an element",
46
+ severity: "major",
47
+ category: "correctness",
48
+ recommendation: "Use `slice(start, end)` — end is already exclusive.",
49
+ },
50
+ float_money: {
51
+ title: "Float accumulation for money",
52
+ severity: "major",
53
+ category: "correctness",
54
+ recommendation: "Use integer cents or a decimal library for monetary sums.",
55
+ },
56
+ float_equality: {
57
+ title: "Exact float equality in branch condition",
58
+ severity: "major",
59
+ category: "correctness",
60
+ recommendation: "Compare with an epsilon or restructure; `===` on computed floats is unreliable.",
61
+ },
62
+ cache_aliasing: {
63
+ title: "Mutable cached object shared by reference",
64
+ severity: "minor",
65
+ category: "correctness",
66
+ recommendation: "Clone on read/write or freeze cached values.",
67
+ },
68
+ missing_validation: {
69
+ title: "Missing input validation",
70
+ severity: "minor",
71
+ category: "correctness",
72
+ recommendation: "Validate arguments at the trust boundary.",
73
+ },
74
+ };
75
+ const PATTERN_IDS = Object.keys(SCREEN_PATTERNS);
76
+ const CONTROL_KEYWORDS = new Set(["if", "for", "while", "switch", "catch", "else", "do", "return", "new"]);
77
+ /**
78
+ * Declaration-boundary heuristic: function/class/interface/type/arrow
79
+ * declarations and method signatures. Language-agnostic enough for TS/JS/Go-
80
+ * style sources; a file with no recognizable boundaries becomes one hunk.
81
+ */
82
+ const BOUNDARY = /^\s*(?:(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+(\w+)|(?:export\s+)?(?:abstract\s+)?class\s+(\w+)|(?:export\s+)?interface\s+(\w+)|(?:export\s+)?type\s+(\w+)\s*=|(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[\w$]+)\s*=>|(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(?:async\s+)?(\w+)\s*\([^)]*\)\s*[:\w\[\]<>|, ]*\{?\s*$)/;
83
+ export function sliceHunks(path, text, maxHunks = MAX_HUNKS_PER_FILE) {
84
+ const lines = text.split("\n");
85
+ const boundaries = [];
86
+ lines.forEach((line, index) => {
87
+ const match = BOUNDARY.exec(line);
88
+ if (!match)
89
+ return;
90
+ const name = match.slice(1).find((group) => group !== undefined);
91
+ if (!name || CONTROL_KEYWORDS.has(name))
92
+ return;
93
+ boundaries.push({ index, name });
94
+ });
95
+ const seen = new Map();
96
+ const uniqueId = (base) => {
97
+ const n = (seen.get(base) ?? 0) + 1;
98
+ seen.set(base, n);
99
+ return n === 1 ? base : `${base}#${n}`;
100
+ };
101
+ const hunks = [];
102
+ const push = (base, startIndex, endIndex) => {
103
+ const code = lines.slice(startIndex, endIndex + 1).join("\n");
104
+ if (!code.trim())
105
+ return;
106
+ hunks.push({ id: uniqueId(base), path, startLine: startIndex + 1, endLine: endIndex + 1, code });
107
+ };
108
+ if (boundaries.length === 0) {
109
+ push("file", 0, lines.length - 1);
110
+ return hunks;
111
+ }
112
+ push("header", 0, boundaries[0].index - 1);
113
+ boundaries.forEach((boundary, i) => {
114
+ const end = i + 1 < boundaries.length ? boundaries[i + 1].index - 1 : lines.length - 1;
115
+ push(boundary.name, boundary.index, end);
116
+ });
117
+ // Merge overflow into the last hunk rather than dropping tail code.
118
+ if (hunks.length > maxHunks) {
119
+ const kept = hunks.slice(0, maxHunks);
120
+ const last = kept[kept.length - 1];
121
+ const tail = hunks[hunks.length - 1];
122
+ last.endLine = tail.endLine;
123
+ last.code = lines.slice(last.startLine - 1, last.endLine).join("\n");
124
+ return kept;
125
+ }
126
+ return hunks;
127
+ }
128
+ /**
129
+ * Fan out every question in one call, chunking sequentially past
130
+ * MAX_QUESTIONS_PER_CALL. Missing answers read as "no" (conservative).
131
+ */
132
+ async function evaluateChunked(connection, state, questions, fetchImpl) {
133
+ const entries = Object.entries(questions);
134
+ const probabilities = {};
135
+ let calls = 0;
136
+ let usage;
137
+ let model;
138
+ for (let offset = 0; offset < entries.length; offset += MAX_QUESTIONS_PER_CALL) {
139
+ const chunk = Object.fromEntries(entries.slice(offset, offset + MAX_QUESTIONS_PER_CALL));
140
+ const result = await evaluateNouls(connection, state, chunk, fetchImpl ?? fetch, GENERIC_NOUL_CRITERIA);
141
+ Object.assign(probabilities, result.probabilities);
142
+ calls += 1;
143
+ if (result.usage) {
144
+ usage = {
145
+ inputTokens: (usage?.inputTokens ?? 0) + result.usage.inputTokens,
146
+ outputTokens: (usage?.outputTokens ?? 0) + result.usage.outputTokens,
147
+ };
148
+ }
149
+ model = result.model ?? model;
150
+ }
151
+ return { probabilities, calls, ...(usage ? { usage } : {}), ...(model ? { model } : {}) };
152
+ }
153
+ /** Screen pre-sliced hunks; pure of filesystem and process exit so tests drive it with a mocked fetch. */
154
+ export async function screenHunks(connection, hunks, options = {}) {
155
+ const startedAt = Date.now();
156
+ const questions = {};
157
+ hunks.forEach((hunk, i) => {
158
+ questions[`d${i}`] =
159
+ `Does hunk "${hunk.id}" contain a real correctness, security, or data-loss defect that should block merge? ` +
160
+ "Ignore style and hypothetical concerns.";
161
+ PATTERN_IDS.forEach((patternId, p) => {
162
+ questions[`p${i}_${p}`] = `Does hunk "${hunk.id}" contain this defect: ${SCREEN_PATTERNS[patternId].title}?`;
163
+ });
164
+ });
165
+ const state = {
166
+ task: "Screen code hunks for real defects worth blocking a merge on. Judge each hunk independently against the supplied code.",
167
+ hunks: hunks.map((hunk) => ({
168
+ id: hunk.id,
169
+ path: hunk.path,
170
+ lines: `${hunk.startLine}-${hunk.endLine}`,
171
+ code: hunk.code,
172
+ })),
173
+ };
174
+ const result = await evaluateChunked(connection, state, questions, options.fetchImpl);
175
+ const findings = [];
176
+ const hunkReports = [];
177
+ hunks.forEach((hunk, i) => {
178
+ const catchAll = result.probabilities[`d${i}`];
179
+ const hits = PATTERN_IDS.map((patternId, p) => ({ patternId, probability: result.probabilities[`p${i}_${p}`] }))
180
+ .filter((hit) => hit.probability !== undefined && hit.probability >= SCREEN_THRESHOLD)
181
+ .sort((a, b) => b.probability - a.probability);
182
+ for (const hit of hits) {
183
+ const pattern = SCREEN_PATTERNS[hit.patternId];
184
+ findings.push({
185
+ id: `S${findings.length + 1}`,
186
+ severity: pattern.severity,
187
+ path: hunk.path,
188
+ summary: pattern.title,
189
+ actionable: true,
190
+ details: `Evidence: hunk "${hunk.id}" (${hunk.path}:${hunk.startLine}-${hunk.endLine}) matched defect pattern ` +
191
+ `"${hit.patternId}" (p=${hit.probability.toFixed(2)}, category=${pattern.category}).`,
192
+ recommendation: pattern.recommendation,
193
+ location: { startLine: hunk.startLine, endLine: hunk.endLine },
194
+ });
195
+ }
196
+ if (hits.length === 0 && catchAll !== undefined && catchAll >= SCREEN_THRESHOLD) {
197
+ findings.push({
198
+ id: `S${findings.length + 1}`,
199
+ severity: "major",
200
+ path: hunk.path,
201
+ summary: `Possible defect in "${hunk.id}" matched no known pattern — needs deeper review`,
202
+ actionable: true,
203
+ details: `Evidence: the screening catch-all scored p=${catchAll.toFixed(2)} for hunk "${hunk.id}" ` +
204
+ `(${hunk.path}:${hunk.startLine}-${hunk.endLine}) but every catalog pattern scored below ${SCREEN_THRESHOLD}.`,
205
+ recommendation: "Run a full `pi-review` on this file for evidence-backed findings.",
206
+ location: { startLine: hunk.startLine, endLine: hunk.endLine },
207
+ });
208
+ }
209
+ hunkReports.push({
210
+ id: hunk.id,
211
+ path: hunk.path,
212
+ startLine: hunk.startLine,
213
+ endLine: hunk.endLine,
214
+ ...(catchAll !== undefined ? { defectProbability: catchAll } : {}),
215
+ patterns: hits.map((hit) => hit.patternId),
216
+ });
217
+ });
218
+ return {
219
+ status: findings.length > 0 ? "has_findings" : "clean",
220
+ findings,
221
+ hunkReports,
222
+ questions: Object.keys(questions).length,
223
+ calls: result.calls,
224
+ durationMs: Date.now() - startedAt,
225
+ ...(result.model ? { model: result.model } : {}),
226
+ ...(result.usage ? { usage: result.usage } : {}),
227
+ };
228
+ }
229
+ export function formatScreenAscii(result) {
230
+ const lines = ["── pi-review screen " + "─".repeat(20)];
231
+ const flagged = result.hunkReports.filter((h) => (h.defectProbability ?? 0) >= SCREEN_THRESHOLD || h.patterns.length > 0);
232
+ lines.push(` Status ${result.status}`);
233
+ lines.push(` Hunks ${result.hunkReports.length} screened, ${flagged.length} flagged ` +
234
+ `(${result.questions} questions, ${result.calls} call${result.calls === 1 ? "" : "s"}, ${(result.durationMs / 1000).toFixed(1)}s)`);
235
+ lines.push(` Findings ${result.findings.length}`);
236
+ if (result.findings.length > 0) {
237
+ lines.push("");
238
+ for (const finding of result.findings) {
239
+ const where = finding.path ? `${finding.path}:${finding.location?.startLine ?? "?"}-${finding.location?.endLine ?? "?"}` : "?";
240
+ lines.push(` ${finding.id} ${(finding.severity ?? "?").toUpperCase()} ${where}`);
241
+ lines.push(` ${finding.summary}`);
242
+ }
243
+ }
244
+ lines.push("─".repeat(39));
245
+ return lines.join("\n");
246
+ }
247
+ export async function runScreen(parsed) {
248
+ const paths = parsed.screenPaths ?? [];
249
+ if (paths.length === 0) {
250
+ fail("screen: provide files to screen: pi-review screen <@files|paths...>");
251
+ }
252
+ const connection = resolveJevConnection(process.env);
253
+ if (!connection) {
254
+ process.stderr.write("pi-review: screen requires a TypeSafe API key: export TYPESAFE_API_KEY (see README — Jev enhancement mode).\n");
255
+ process.exit(4);
256
+ }
257
+ const hunks = [];
258
+ for (const raw of paths) {
259
+ const file = expandMaybeHome(raw.startsWith("@") ? raw.slice(1) : raw);
260
+ let text;
261
+ try {
262
+ text = fs.readFileSync(file, "utf8");
263
+ }
264
+ catch (error) {
265
+ fail(`screen: cannot read ${file}: ${error.message}`);
266
+ }
267
+ hunks.push(...sliceHunks(file, text));
268
+ }
269
+ if (hunks.length === 0) {
270
+ fail("screen: no screenable content — every file was empty");
271
+ }
272
+ let result;
273
+ try {
274
+ result = await screenHunks(connection, hunks);
275
+ }
276
+ catch (error) {
277
+ process.stderr.write(`pi-review: screen failed: ${error.message}\n`);
278
+ process.exit(4);
279
+ }
280
+ process.stdout.write(`${formatScreenAscii(result)}\n`);
281
+ process.stderr.write(`PI_REVIEW_SCREEN_JSON: ${JSON.stringify(result)}\n`);
282
+ process.exit(result.status === "clean" ? 0 : 1);
283
+ }
284
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=screen.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.test.d.ts","sourceRoot":"","sources":["../src/screen.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,156 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "vitest";
3
+ import { sliceHunks, screenHunks, formatScreenAscii, SCREEN_PATTERNS, SCREEN_THRESHOLD, MAX_QUESTIONS_PER_CALL, } from "./screen.js";
4
+ const CONN = { apiKey: "test-key", baseUrl: "https://example.test", model: "jev-test" };
5
+ const FIXTURE = `import { randomUUID } from "node:crypto";
6
+
7
+ export interface Order {
8
+ id: string;
9
+ }
10
+
11
+ export class OrderService {
12
+ async getOrder(id: string): Promise<Order | undefined> {
13
+ return undefined;
14
+ }
15
+
16
+ async placeOrder(customerId: string, items: unknown[]): Promise<void> {
17
+ let total = 0;
18
+ for (let i = 0; i <= items.length; i++) {
19
+ total += 1;
20
+ }
21
+ if (total === 100.0) {
22
+ return;
23
+ }
24
+ }
25
+
26
+ async listPage(items: Order[], page: number): Promise<Order[]> {
27
+ return items.slice(0, page - 1);
28
+ }
29
+ }
30
+ `;
31
+ /** Mock System One: per-question probability map, missing ids fall back to `fallback`. */
32
+ function noulFetch(probabilities, fallback = 0.05) {
33
+ return (async (_url, init) => {
34
+ const body = JSON.parse(init.body);
35
+ const answers = {};
36
+ for (const id of Object.keys(body.questions)) {
37
+ answers[id] = { type: "noul", noul: probabilities[id] ?? fallback };
38
+ }
39
+ return {
40
+ ok: true,
41
+ status: 200,
42
+ json: async () => ({ model: "jev-1.13.0", answers, usage: { input_tokens: 100, output_tokens: 10 } }),
43
+ };
44
+ });
45
+ }
46
+ test("sliceHunks splits at declarations with a header hunk and line ranges", () => {
47
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
48
+ const ids = hunks.map((h) => h.id);
49
+ assert.deepEqual(ids, ["header", "Order", "OrderService", "getOrder", "placeOrder", "listPage"]);
50
+ const placeOrder = hunks.find((h) => h.id === "placeOrder");
51
+ assert.ok(placeOrder.code.includes("i <= items.length"));
52
+ assert.ok(!placeOrder.code.includes("listPage"));
53
+ assert.equal(placeOrder.startLine, FIXTURE.split("\n").findIndex((l) => l.includes("async placeOrder")) + 1);
54
+ assert.ok(placeOrder.endLine > placeOrder.startLine);
55
+ });
56
+ test("sliceHunks skips control-flow keywords and empty headers", () => {
57
+ const hunks = sliceHunks("x.ts", "export function main() {\n if (a) {\n for (let i = 0;;) {}\n }\n}\n");
58
+ assert.deepEqual(hunks.map((h) => h.id), ["main"]);
59
+ });
60
+ test("sliceHunks falls back to one file hunk when no boundary matches", () => {
61
+ const hunks = sliceHunks("plain.txt", "alpha\nbeta\ngamma\n");
62
+ assert.equal(hunks.length, 1);
63
+ assert.equal(hunks[0].id, "file");
64
+ assert.equal(hunks[0].endLine, 4); // trailing newline counts as an empty 4th line
65
+ });
66
+ test("sliceHunks merges overflow into the last hunk instead of dropping code", () => {
67
+ const text = Array.from({ length: 5 }, (_, i) => `export function f${i}() {\n return ${i};\n}`).join("\n") + "\n";
68
+ const hunks = sliceHunks("many.ts", text, 3);
69
+ assert.equal(hunks.length, 3);
70
+ assert.ok(hunks[2].code.includes("f4"));
71
+ assert.ok(hunks[2].endLine === text.split("\n").length);
72
+ });
73
+ test("screenHunks assembles pattern-matched findings from templates", async () => {
74
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
75
+ const placeIdx = hunks.findIndex((h) => h.id === "placeOrder");
76
+ const loopIdx = Object.keys(SCREEN_PATTERNS).indexOf("off_by_one_loop");
77
+ const eqIdx = Object.keys(SCREEN_PATTERNS).indexOf("float_equality");
78
+ const result = await screenHunks(CONN, hunks, {
79
+ fetchImpl: noulFetch({ [`d${placeIdx}`]: 0.96, [`p${placeIdx}_${loopIdx}`]: 0.98, [`p${placeIdx}_${eqIdx}`]: 0.8 }),
80
+ });
81
+ assert.equal(result.status, "has_findings");
82
+ assert.equal(result.findings.length, 2);
83
+ const first = result.findings[0];
84
+ assert.equal(first.summary, SCREEN_PATTERNS.off_by_one_loop.title);
85
+ assert.equal(first.severity, "critical");
86
+ assert.equal(first.actionable, true);
87
+ assert.equal(first.path, "order-service.ts");
88
+ assert.equal(first.location?.startLine, hunks[placeIdx].startLine);
89
+ assert.ok(first.details.includes("off_by_one_loop"));
90
+ assert.equal(first.recommendation, SCREEN_PATTERNS.off_by_one_loop.recommendation);
91
+ });
92
+ test("screenHunks emits an unmatched-signal finding when only the catch-all fires", async () => {
93
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
94
+ const getIdx = hunks.findIndex((h) => h.id === "getOrder");
95
+ const result = await screenHunks(CONN, hunks, { fetchImpl: noulFetch({ [`d${getIdx}`]: 0.9 }) });
96
+ assert.equal(result.status, "has_findings");
97
+ assert.equal(result.findings.length, 1);
98
+ assert.ok(result.findings[0].summary.includes("matched no known pattern"));
99
+ assert.ok(result.findings[0].recommendation.includes("pi-review"));
100
+ });
101
+ test("screenHunks reports clean when everything is below threshold", async () => {
102
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
103
+ const result = await screenHunks(CONN, hunks, { fetchImpl: noulFetch({}) });
104
+ assert.equal(result.status, "clean");
105
+ assert.equal(result.findings.length, 0);
106
+ assert.equal(result.questions, hunks.length * (Object.keys(SCREEN_PATTERNS).length + 1));
107
+ assert.equal(result.calls, 1);
108
+ });
109
+ test("screenHunks chunks question volumes past the per-call cap", async () => {
110
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
111
+ const perHunk = Object.keys(SCREEN_PATTERNS).length + 1;
112
+ const expectedCalls = Math.ceil((hunks.length * perHunk) / MAX_QUESTIONS_PER_CALL);
113
+ assert.ok(expectedCalls >= 1);
114
+ // Force chunking with a tiny cap by screening many copies.
115
+ const many = Array.from({ length: Math.ceil(MAX_QUESTIONS_PER_CALL / perHunk) + 1 }, () => hunks).flat();
116
+ const result = await screenHunks(CONN, many, { fetchImpl: noulFetch({}) });
117
+ assert.ok(result.calls >= 2);
118
+ assert.equal(result.status, "clean");
119
+ });
120
+ test("screenHunks treats missing answers as no-signal", async () => {
121
+ const hunks = sliceHunks("order-service.ts", FIXTURE);
122
+ const result = await screenHunks(CONN, hunks, {
123
+ fetchImpl: (async (_url, init) => ({
124
+ ok: true,
125
+ status: 200,
126
+ json: async () => ({ answers: {} }), // every answer omitted
127
+ })),
128
+ });
129
+ assert.equal(result.status, "clean");
130
+ assert.equal(result.hunkReports.length, hunks.length);
131
+ assert.ok(result.hunkReports.every((h) => h.defectProbability === undefined));
132
+ });
133
+ test("formatScreenAscii renders status, hunks, and finding lines", () => {
134
+ const text = formatScreenAscii({
135
+ status: "has_findings",
136
+ findings: [
137
+ {
138
+ id: "S1",
139
+ severity: "critical",
140
+ path: "a.ts",
141
+ summary: "SQL injection via string interpolation",
142
+ actionable: true,
143
+ location: { startLine: 3, endLine: 9 },
144
+ },
145
+ ],
146
+ hunkReports: [{ id: "h", path: "a.ts", startLine: 3, endLine: 9, defectProbability: 0.9, patterns: ["sql_injection"] }],
147
+ questions: 9,
148
+ calls: 1,
149
+ durationMs: 900,
150
+ });
151
+ assert.ok(text.includes("has_findings"));
152
+ assert.ok(text.includes("S1"));
153
+ assert.ok(text.includes("a.ts:3-9"));
154
+ assert.ok(SCREEN_THRESHOLD > 0 && SCREEN_THRESHOLD < 1);
155
+ });
156
+ //# sourceMappingURL=screen.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.test.js","sourceRoot":"","sources":["../src/screen.test.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -45,7 +45,7 @@ export interface StructuredReviewResult extends VerdictInfo {
45
45
  actionableCount: number;
46
46
  }
47
47
  export interface ParsedArgs {
48
- command: "review" | "loop" | "classify" | "models" | "install" | "install-skill" | "uninstall-skill" | "update";
48
+ command: "review" | "loop" | "classify" | "screen" | "models" | "install" | "install-skill" | "uninstall-skill" | "update";
49
49
  /** For `install`: run `pi install npm:@zephyrdeng/pi-review` */
50
50
  installPi?: boolean;
51
51
  /** For `install`: run agent skill install (skills CLI / Claude + agy direct fallback) */
@@ -113,6 +113,8 @@ export interface ParsedArgs {
113
113
  baseline?: string;
114
114
  /** Classify: path to a file containing a review's PI_REVIEW_META_JSON (default: stdin). */
115
115
  metaFile?: string;
116
+ /** Screen: files to screen (@file or bare path). */
117
+ screenPaths?: string[];
116
118
  }
117
119
  export interface ReviewPreset {
118
120
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,SAAS,CAAU,CAAC;AAGlG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;AAuI5F;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAU,CAAC;AA8C9C,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AActF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,yDAAyD;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAE7E,mEAAmE;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,SAAS,CAAU,CAAC;AAGlG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;AAyI5F;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAU,CAAC;AA8C9C,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AActF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,yDAAyD;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAE7E,mEAAmE;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC"}
@@ -312,7 +312,7 @@ export function registerPanelReviewTool(pi: ExtensionAPI): void {
312
312
  consensus: Type.Optional(Type.String({ description: "any | quorum | majority | unanimous" })),
313
313
  minAgree: Type.Optional(Type.Number({ description: "Quorum threshold when consensus=quorum" })),
314
314
  consensusModel: Type.Optional(Type.String({ description: "Model for semantic adjudication only" })),
315
- concurrency: Type.Optional(Type.Number({ description: "Bound parallel reviewers (≤ reviewer count)" })),
315
+ concurrency: Type.Optional(Type.Number({ description: "Bound parallel reviewers (≤ reviewer count). Omit for full parallelism — all reviewers run concurrently by default; do not pass 1 unless the provider account cannot handle concurrent requests." })),
316
316
  model: Type.Optional(Type.String({ description: "Optional shared reviewer model." })),
317
317
  thinking: Type.Optional(Type.String({ description: "Optional thinking level." })),
318
318
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zephyrdeng/pi-review",
3
- "version": "0.15.2",
3
+ "version": "0.16.1",
4
4
  "description": "Isolated AI-powered code and plan reviews from the command line",
5
5
  "type": "module",
6
6
  "author": "ZephyrDeng <zephyrTang@aliyun.com>",
@@ -47,6 +47,7 @@ There is no `/rv-config set` command — the agent is the config editor. When th
47
47
 
48
48
  | Host | How to run `pi-review` |
49
49
  |------|-------------------------|
50
+ | **Fast CI / Pre-commit Gate** | Run `pi-review screen <@files\|paths...>` (~1s wall time, zero LLM generation). Immediately blocks obvious defects (off-by-one, SQLi, unawaited async, float money) via typed Jev judgments before launching full reviewer sessions. |
50
51
  | **Pi** (`/rv`) | New panel reviews call the native `pi_review` API tool, shown to users as **Pi Review Panel**, which launches the packaged CLI in event mode and renders live reviewer state. Continuations, kept sessions, `/rv-loop`, and explicit `--no-stream` use the shell CLI. |
51
52
  | **Pi terminal** | Foreground `pi-review`; text deltas stream live by default. |
52
53
  | **Claude Code / Codex / Cursor / agy (Antigravity)** and similar agent hosts | These hosts buffer a shell tool's output until the command exits, so a foreground run looks like a silent wait. **Panel review (`--reviewers`/`--panel`) default: `--ui web --ui-url-file <path>` + background run** — get the dashboard in front of the user: on Claude Code the CLI auto-open lands in the system default browser; on Codex open the `--ui-url-file` URL in the host's built-in browser (the CLI cannot reach a GUI there); on agy prefer the host browser / share the URL the same way; hand over the URL as fallback either way. **Single review / `loop` default: `--progress-log <path>` + background run + tail the log** (`--ui web` requires an active panel and rejects `loop`). See [references/codex-tools.md](./references/codex-tools.md). Map skill mentions of `Bash` to your host shell tool. |
@@ -143,6 +144,35 @@ Use this protocol when the host is closing out implementation work and may edit
143
144
 
144
145
  The shell exit policy is: `0` clean, `1` status is `has_findings`, `2` usage error, `3` needs human, `4` blocked/runtime failure. A non-zero loop result is a gate signal, not permission for the child reviewer to edit.
145
146
 
147
+ ## Gate-grade fast screening (`pi-review screen`)
148
+
149
+ `pi-review screen <@files|paths...>` is a sub-second gate check that completely skips LLM prose generation. It slices files at declaration boundaries into hunks, evaluates each hunk against defect patterns via single-call typed Jev judgments, and assembles findings from catalog templates in **~1.0–1.2s**:
150
+
151
+ ```bash
152
+ pi-review screen @src/order-service.ts
153
+ ```
154
+
155
+ ### When to choose `screen` vs `review` vs `panel` vs `loop`
156
+
157
+ - **Use `screen`** for Pre-commit / Pre-push hooks, fast CI PR pre-flight checks, or when an operator asks for an instant sanity pass. Exit codes: `0` (clean), `1` (has findings / blocked), `4` (no `TYPESAFE_API_KEY`).
158
+ - **Use `review`** (single review) for routine local development and self-review where one model's prose recommendations are sufficient.
159
+ - **Use `panel`** (`--reviewers N`) for PR merge gates, security-sensitive changes, or cross-model verification where independent agreement matters.
160
+ - **Use `loop`** (`loop [--until clean]`) during automated implementation closeout where an agent iteratively patches code and re-verifies until clean.
161
+
162
+ ## CLI arguments: when to use each
163
+
164
+ | Argument | When to use |
165
+ |---|---|
166
+ | `screen <paths>` | Instant (~1s) gate screening; no LLM child session spawned. Requires `TYPESAFE_API_KEY`. |
167
+ | `--reviewer-model <id=model[:thinking]>` | In panel mode, to assign specific models or thinking levels to individual reviewers (e.g. `r1=openai/gpt-5:high`, `r2=zenmux/deepseek/deepseek-v4.1-flash:low`). Essential for cross-family heterogeneous panels. |
168
+ | `--concurrency <n>` | Bounds parallel reviewer execution. **Omit for full speed** (all reviewers run concurrently by default). Only pass `<n>` if the provider account has strict concurrent request limits. |
169
+ | `--consensus-model <model>` | Explicitly forces an LLM child session to act as the adjudicator instead of Jev System One. Use when you explicitly want full-text LLM reasoning on finding clusters. |
170
+ | `--consensus <policy>` / `--min-agree <n>` | Fine-tunes panel quorum. Defaults to `quorum` with `min-agree: 2`. Use `unanimous` for zero-tolerance security releases, or `any` for broad bug hunts. |
171
+ | `--until clean` | In `loop` mode, automates iterative convergence (stops when confirmed actionable issues drop to 0 or hard `--max-rounds` cap is hit). |
172
+ | `--progress-log <path>` | Streams compact JSON events to a file; essential for background runs in buffered-output hosts like Claude Code, Codex, or Cursor. |
173
+ | `--ui web` | Starts a loopback browser dashboard for panel runs; recommended for visual inspection on agent hosts. |
174
+
175
+
146
176
  ## Panel review
147
177
 
148
178
  Panel review runs multiple **independent** reviewers in isolated child sessions and aggregates their findings into one gate result. Reviewers cannot see one another's findings, so agreement represents independent discovery.