@zephyrdeng/pi-review 0.15.0 → 0.15.2

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.
Files changed (78) hide show
  1. package/README.md +22 -4
  2. package/README.zh-CN.md +22 -5
  3. package/dist/args.d.ts.map +1 -1
  4. package/dist/args.js +22 -0
  5. package/dist/args.js.map +1 -1
  6. package/dist/child-isolation.test.js +4 -1
  7. package/dist/child-isolation.test.js.map +1 -1
  8. package/dist/classify.d.ts +36 -0
  9. package/dist/classify.d.ts.map +1 -0
  10. package/dist/classify.js +173 -0
  11. package/dist/classify.js.map +1 -0
  12. package/dist/classify.test.d.ts +2 -0
  13. package/dist/classify.test.d.ts.map +1 -0
  14. package/dist/classify.test.js +93 -0
  15. package/dist/classify.test.js.map +1 -0
  16. package/dist/cli-exit.test.js +8 -0
  17. package/dist/cli-exit.test.js.map +1 -1
  18. package/dist/cli.js +34 -1
  19. package/dist/cli.js.map +1 -1
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/jev.d.ts +117 -0
  25. package/dist/jev.d.ts.map +1 -0
  26. package/dist/jev.js +294 -0
  27. package/dist/jev.js.map +1 -0
  28. package/dist/jev.test.d.ts +2 -0
  29. package/dist/jev.test.d.ts.map +1 -0
  30. package/dist/jev.test.js +206 -0
  31. package/dist/jev.test.js.map +1 -0
  32. package/dist/loop.d.ts +18 -1
  33. package/dist/loop.d.ts.map +1 -1
  34. package/dist/loop.js +39 -0
  35. package/dist/loop.js.map +1 -1
  36. package/dist/loop.test.js +36 -0
  37. package/dist/loop.test.js.map +1 -1
  38. package/dist/matcher.d.ts +16 -3
  39. package/dist/matcher.d.ts.map +1 -1
  40. package/dist/matcher.js +31 -12
  41. package/dist/matcher.js.map +1 -1
  42. package/dist/matcher.test.js +30 -6
  43. package/dist/matcher.test.js.map +1 -1
  44. package/dist/meta-footer.d.ts.map +1 -1
  45. package/dist/meta-footer.js +6 -2
  46. package/dist/meta-footer.js.map +1 -1
  47. package/dist/panel-cli.test.js +145 -3
  48. package/dist/panel-cli.test.js.map +1 -1
  49. package/dist/panel.d.ts.map +1 -1
  50. package/dist/panel.js +48 -4
  51. package/dist/panel.js.map +1 -1
  52. package/dist/pi-config.d.ts +7 -0
  53. package/dist/pi-config.d.ts.map +1 -1
  54. package/dist/pi-config.js +15 -1
  55. package/dist/pi-config.js.map +1 -1
  56. package/dist/pi-config.test.js +6 -0
  57. package/dist/pi-config.test.js.map +1 -1
  58. package/dist/round-compare.d.ts +23 -0
  59. package/dist/round-compare.d.ts.map +1 -0
  60. package/dist/round-compare.js +45 -0
  61. package/dist/round-compare.js.map +1 -0
  62. package/dist/round-compare.test.d.ts +2 -0
  63. package/dist/round-compare.test.d.ts.map +1 -0
  64. package/dist/round-compare.test.js +63 -0
  65. package/dist/round-compare.test.js.map +1 -0
  66. package/dist/types.d.ts +17 -1
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/types.js.map +1 -1
  69. package/extensions/rv-config.test.ts +10 -0
  70. package/extensions/rv-config.ts +23 -0
  71. package/package.json +1 -1
  72. package/resources/providers/orcarouter.json +7 -4
  73. package/resources/providers/orcarouter.toml +11 -0
  74. package/skills/pi-review/SKILL.md +14 -1
  75. package/dist/extensions/review.d.ts +0 -2
  76. package/dist/extensions/review.js +0 -22
  77. package/dist/extensions/rv-prompts.d.ts +0 -19
  78. package/dist/extensions/rv-prompts.js +0 -132
@@ -0,0 +1,23 @@
1
+ import type { FindingMatcher } from "./matcher.js";
2
+ /** Minimal finding shape needed for cross-round comparison. */
3
+ export interface RoundFindingRef {
4
+ id: string;
5
+ summary: string;
6
+ path?: string;
7
+ }
8
+ export interface RoundComparison {
9
+ /** Current-round findings semantically present in the previous round too. */
10
+ persisting: number;
11
+ /** Current-round findings with no previous-round counterpart. */
12
+ added: number;
13
+ /** Previous-round findings with no current-round counterpart. */
14
+ resolved: number;
15
+ }
16
+ /**
17
+ * Compare two rounds' actionable findings through the injected matcher.
18
+ * Advisory by construction: ids are namespaced by round, so a match can never
19
+ * invent or lose findings — worst case is a missed merge (reported as
20
+ * added+resolved), never a false one.
21
+ */
22
+ export declare function compareRoundFindings(previous: RoundFindingRef[], current: RoundFindingRef[], matcher: FindingMatcher): Promise<RoundComparison>;
23
+ //# sourceMappingURL=round-compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-compare.d.ts","sourceRoot":"","sources":["../src/round-compare.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,eAAe,EAAE,EAC3B,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAsB1B"}
@@ -0,0 +1,45 @@
1
+ // Cross-round finding comparison for loop review.
2
+ //
3
+ // Reuses the panel matcher's "same underlying issue?" machinery verbatim: the
4
+ // previous round's actionable findings and the current round's are tagged as
5
+ // two pseudo-reviewers ("prev" / "curr") and run through the same
6
+ // deterministic-first, optionally Jev-adjudicated matching. A group spanning
7
+ // both rounds is a persisting finding; curr-only is new; prev-only is no
8
+ // longer detected.
9
+ //
10
+ // Within one loop process the tree never changes between rounds, so this
11
+ // measures finding *stability* across independent review sessions — which is
12
+ // also the non-convergence signal: an identical actionable set twice in a row
13
+ // means further rounds on the same tree cannot change the gate.
14
+ /**
15
+ * Compare two rounds' actionable findings through the injected matcher.
16
+ * Advisory by construction: ids are namespaced by round, so a match can never
17
+ * invent or lose findings — worst case is a missed merge (reported as
18
+ * added+resolved), never a false one.
19
+ */
20
+ export async function compareRoundFindings(previous, current, matcher) {
21
+ const tag = (round) => (f) => ({
22
+ id: `${round}#${f.id}`,
23
+ reviewerId: round,
24
+ finding: { summary: f.summary, actionable: true, ...(f.path ? { path: f.path } : {}) },
25
+ });
26
+ const result = await matcher.match([...previous.map(tag("prev")), ...current.map(tag("curr"))]);
27
+ const prevMatched = new Set();
28
+ const currMatched = new Set();
29
+ for (const group of result.groups) {
30
+ const prevIds = group.filter((id) => id.startsWith("prev#"));
31
+ const currIds = group.filter((id) => id.startsWith("curr#"));
32
+ if (prevIds.length === 0 || currIds.length === 0)
33
+ continue;
34
+ for (const id of prevIds)
35
+ prevMatched.add(id);
36
+ for (const id of currIds)
37
+ currMatched.add(id);
38
+ }
39
+ return {
40
+ persisting: currMatched.size,
41
+ added: current.length - currMatched.size,
42
+ resolved: previous.length - prevMatched.size,
43
+ };
44
+ }
45
+ //# sourceMappingURL=round-compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-compare.js","sourceRoot":"","sources":["../src/round-compare.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,kEAAkE;AAClE,6EAA6E;AAC7E,yEAAyE;AACzE,mBAAmB;AACnB,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAC9E,gEAAgE;AAqBhE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAA2B,EAC3B,OAA0B,EAC1B,OAAuB;IAEvB,MAAM,GAAG,GAAG,CAAC,KAAsB,EAAE,EAAE,CAAC,CAAC,CAAkB,EAAiB,EAAE,CAAC,CAAC;QAC9E,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE;QACtB,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;KACvF,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhG,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC3D,KAAK,MAAM,EAAE,IAAI,OAAO;YAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9C,KAAK,MAAM,EAAE,IAAI,OAAO;YAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO;QACL,UAAU,EAAE,WAAW,CAAC,IAAI;QAC5B,KAAK,EAAE,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,IAAI;QACxC,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,IAAI;KAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=round-compare.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-compare.test.d.ts","sourceRoot":"","sources":["../src/round-compare.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "vitest";
3
+ import { compareRoundFindings } from "./round-compare.js";
4
+ import { DeterministicMatcher, SemanticMatcher } from "./matcher.js";
5
+ const det = new DeterministicMatcher();
6
+ test("identical sets: all persisting, nothing added or resolved", async () => {
7
+ const prev = [{ id: "F1", summary: "Off-by-one in loop", path: "src/cli.ts" }];
8
+ const curr = [{ id: "F1", summary: "off-by-one in loop", path: "./src/cli.ts" }];
9
+ const result = await compareRoundFindings(prev, curr, det);
10
+ assert.deepEqual(result, { persisting: 1, added: 0, resolved: 0 });
11
+ });
12
+ test("disjoint sets: everything added and resolved", async () => {
13
+ const prev = [{ id: "F1", summary: "Off-by-one", path: "src/a.ts" }];
14
+ const curr = [{ id: "F1", summary: "SQL injection", path: "src/b.ts" }];
15
+ const result = await compareRoundFindings(prev, curr, det);
16
+ assert.deepEqual(result, { persisting: 0, added: 1, resolved: 1 });
17
+ });
18
+ test("partial overlap: one persists, one resolved, one added", async () => {
19
+ const prev = [
20
+ { id: "F1", summary: "Off-by-one", path: "src/a.ts" },
21
+ { id: "F2", summary: "Old bug now fixed", path: "src/b.ts" },
22
+ ];
23
+ const curr = [
24
+ { id: "F1", summary: "Off-by-one", path: "src/a.ts" },
25
+ { id: "F2", summary: "Brand new bug", path: "src/c.ts" },
26
+ ];
27
+ const result = await compareRoundFindings(prev, curr, det);
28
+ assert.deepEqual(result, { persisting: 1, added: 1, resolved: 1 });
29
+ });
30
+ test("wording drift across rounds merges via a Jev-style adjudicator", async () => {
31
+ // Deterministic matching cannot merge these; a semantic adjudicator can.
32
+ const adjudicator = {
33
+ adjudicate: async () => ({ merges: [{ sourceFindingIds: ["prev#F1", "curr#F1"], confidence: 0.9 }] }),
34
+ };
35
+ const matcher = new SemanticMatcher(adjudicator);
36
+ const prev = [{ id: "F1", summary: "Off-by-one in loop bound", path: "src/cli.ts" }];
37
+ const curr = [{ id: "F1", summary: "Loop can iterate past the array end", path: "src/cli.ts" }];
38
+ const result = await compareRoundFindings(prev, curr, matcher);
39
+ assert.deepEqual(result, { persisting: 1, added: 0, resolved: 0 });
40
+ });
41
+ test("a persisting finding reported by two rounds counts once per round", async () => {
42
+ // Round N had two reviewers' worth of duplicates collapsed upstream; here
43
+ // prev has one finding, curr has two differently-worded instances of it.
44
+ const adjudicator = {
45
+ adjudicate: async ({ candidates }) => ({
46
+ merges: [{ sourceFindingIds: candidates.flatMap((c) => c.findings.map((f) => f.id)), confidence: 0.9 }],
47
+ }),
48
+ };
49
+ const matcher = new SemanticMatcher(adjudicator);
50
+ const prev = [{ id: "F1", summary: "eval executes user input", path: "src/x.ts" }];
51
+ const curr = [
52
+ { id: "F1", summary: "arbitrary code execution via eval", path: "src/x.ts" },
53
+ { id: "F2", summary: "unsanitized string reaches eval", path: "src/x.ts" },
54
+ ];
55
+ const result = await compareRoundFindings(prev, curr, matcher);
56
+ assert.deepEqual(result, { persisting: 2, added: 0, resolved: 0 });
57
+ });
58
+ test("empty previous round: everything is added", async () => {
59
+ const curr = [{ id: "F1", summary: "Bug", path: "src/a.ts" }];
60
+ const result = await compareRoundFindings([], curr, det);
61
+ assert.deepEqual(result, { persisting: 0, added: 1, resolved: 0 });
62
+ });
63
+ //# sourceMappingURL=round-compare.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-compare.test.js","sourceRoot":"","sources":["../src/round-compare.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" | "models" | "install" | "install-skill" | "uninstall-skill" | "update";
48
+ command: "review" | "loop" | "classify" | "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) */
@@ -109,6 +109,10 @@ export interface ParsedArgs {
109
109
  uiTtlSeconds?: number;
110
110
  /** Panel: auto-open the dashboard URL in the default browser (default: true; --no-ui-open sets false). */
111
111
  uiOpen?: boolean;
112
+ /** Classify: frozen task/scope baseline (literal text or @file). */
113
+ baseline?: string;
114
+ /** Classify: path to a file containing a review's PI_REVIEW_META_JSON (default: stdin). */
115
+ metaFile?: string;
112
116
  }
113
117
  export interface ReviewPreset {
114
118
  description: string;
@@ -252,6 +256,12 @@ export interface PanelFields {
252
256
  advisories: FindingCluster[];
253
257
  reviewers: ReviewerOutcome[];
254
258
  adjudicationUsed: boolean;
259
+ /**
260
+ * Which engine ran semantic adjudication: a Jev (TypeSafe System One)
261
+ * typed-decision call, or a review-only Pi child. Present only when
262
+ * adjudicationUsed is true. Absent on metas written before Jev support.
263
+ */
264
+ adjudicationEngine?: "jev" | "pi";
255
265
  adjudicationErrors?: string[];
256
266
  /**
257
267
  * Every source finding a contributing reviewer produced during this
@@ -262,6 +272,12 @@ export interface PanelFields {
262
272
  * always populates it (possibly `[]`).
263
273
  */
264
274
  sourceFindings?: SourceFinding[];
275
+ /**
276
+ * Present when the Jev adjudication enhancement could not run (no API key,
277
+ * or the Jev call failed and the Pi adjudicator took over). Absent on a
278
+ * clean Jev or plain-Pi adjudication.
279
+ */
280
+ adjudicationFallbackNote?: string;
265
281
  }
266
282
  /** Pure aggregate panel result (no Pi, no I/O). */
267
283
  export interface PanelAggregationResult extends StructuredReviewResult, PanelFields {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,2EAA4E,CAAC;AAClG,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,eAAO,MAAM,eAAe,8DAA+D,CAAC;AAC5F,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IACnG,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yFAAyF;IACzF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,kGAAkG;IAClG,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,oEAAoE;IACpE,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,mGAAmG;IACnG,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0GAA0G;IAC1G,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,GAAG,UAAU,GAAG,eAAe,GAAG,cAAc,CAAC;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAG,CAAU,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,UAAW,SAAQ,sBAAsB;IACxD,iFAAiF;IACjF,WAAW,EAAE,OAAO,mBAAmB,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAMD,eAAO,MAAM,kBAAkB,qDAAsD,CAAC;AACtF,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mEAAmE;AACnE,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,yDAAyD;AACzD,eAAO,MAAM,qBAAqB,yCAA0C,CAAC;AAE7E,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,iFAAiF;AACjF,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAEhE,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;IAC5C,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,mDAAmD;AACnD,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,WAAW;CAAG;AAEtF,wEAAwE;AACxE,MAAM,WAAW,eAAgB,SAAQ,UAAU,EAAE,WAAW;IAC9D;;;;OAIG;IACH,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,4FAA4F;IAC5F,aAAa,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
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;AAmI5F;;;;;;;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;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"}
@@ -88,3 +88,13 @@ test("rv-config renders Chinese labels for zh locale", () => {
88
88
  assert.match(text, /childExtensions: true \(配置文件\)/);
89
89
  assert.match(text, /生效环境/);
90
90
  });
91
+
92
+ test("rv-config production path shows the missing-file note (not just the injected one)", () => {
93
+ const lines = buildRvConfigLines({
94
+ locale: "en",
95
+ env: {},
96
+ configPath: "/tmp/pi-review-definitely-missing-config-xyz/config.json",
97
+ resolved,
98
+ });
99
+ assert.match(lines.join("\n"), /\(missing — using defaults\)/);
100
+ });
@@ -5,12 +5,16 @@
5
5
  * locale-aware like the other /rv* commands.
6
6
  */
7
7
 
8
+ import fs from "node:fs";
9
+
8
10
  import {
9
11
  configFilePath,
10
12
  loadReviewConfigFile,
11
13
  parseReviewConfig,
12
14
  resolveChildExtensions,
13
15
  resolveConfig,
16
+ resolveJev,
17
+ hasJevApiKey,
14
18
  } from "@zephyrdeng/pi-review";
15
19
  import type { PiReviewConfig } from "@zephyrdeng/pi-review";
16
20
  import type { RvLocale } from "./rv-locale.js";
@@ -29,6 +33,9 @@ export interface RvConfigViewInput {
29
33
  type Strings = {
30
34
  header: string;
31
35
  childExtensions: string;
36
+ jev: string;
37
+ jevKeyPresent: string;
38
+ jevKeyMissing: string;
32
39
  configFileLabel: string;
33
40
  configFileMissing: string;
34
41
  envSection: string;
@@ -49,6 +56,9 @@ const STRINGS: Record<RvLocale, Strings> = {
49
56
  header: "Pi Review config",
50
57
  childExtensions:
51
58
  "Load host Pi extensions in review children so providers registered only by extensions (e.g. px:anthropic, zenmux) are usable; false keeps children isolated with --no-extensions (issue #8). Override one run: PI_REVIEW_CHILD_EXTENSIONS=1 or =0.",
59
+ jev: "Enhancement mode: route typed decision actions (panel consensus adjudication) to TypeSafe Jev instead of a review-only Pi child. An explicit --consensus-model keeps the Pi adjudicator. Override one run: PI_REVIEW_JEV=1 or =0.",
60
+ jevKeyPresent: "TYPESAFE_API_KEY: present",
61
+ jevKeyMissing: "TYPESAFE_API_KEY: missing — Jev stays off until a key is set",
52
62
  configFileLabel: "config file",
53
63
  configFileMissing: "(missing — using defaults)",
54
64
  envSection: "Resolved environment",
@@ -67,6 +77,9 @@ const STRINGS: Record<RvLocale, Strings> = {
67
77
  header: "Pi Review 配置",
68
78
  childExtensions:
69
79
  "是否让评审子进程加载宿主 Pi 扩展,以使用仅由扩展注册的 provider(如 px:anthropic、zenmux);false 表示隔离运行(--no-extensions,issue #8)。单次覆盖:PI_REVIEW_CHILD_EXTENSIONS=1 或 =0。",
80
+ jev: "增强模式:把 typed 决策动作(面板共识裁决)交给 TypeSafe Jev,而不是一个 review-only 的 Pi 子进程。显式 --consensus-model 时仍走 Pi 裁决器。单次覆盖:PI_REVIEW_JEV=1 或 =0。",
81
+ jevKeyPresent: "TYPESAFE_API_KEY:已设置",
82
+ jevKeyMissing: "TYPESAFE_API_KEY:未设置——设置 key 前 Jev 保持关闭",
70
83
  configFileLabel: "配置文件",
71
84
  configFileMissing: "(不存在——使用默认值)",
72
85
  envSection: "生效环境",
@@ -120,11 +133,19 @@ export function buildRvConfigLines(input: RvConfigViewInput): string[] {
120
133
  const load = loadReviewConfigFile(file);
121
134
  cfg = load.config;
122
135
  configNotes.push(...warnNotes(s, load.warnings));
136
+ // Production path must surface the same missing-file note as the injected
137
+ // test path — otherwise users can't tell "no config" from "empty config".
138
+ if (load.warnings.length === 0 && !fs.existsSync(file)) {
139
+ configNotes.push(s.configFileMissing);
140
+ }
123
141
  }
124
142
 
125
143
  const decision = resolveChildExtensions(env, cfg);
126
144
  const sourceLabel =
127
145
  decision.source === "env" ? s.sourceEnv : decision.source === "config" ? s.sourceConfig : s.sourceDefault;
146
+ const jevDecision = resolveJev(env, cfg);
147
+ const jevSourceLabel =
148
+ jevDecision.source === "env" ? s.sourceEnv : jevDecision.source === "config" ? s.sourceConfig : s.sourceDefault;
128
149
 
129
150
  const resolved = input.resolved ?? resolveConfig();
130
151
  const line = (key: string, value: string, description: string): string => {
@@ -136,6 +157,8 @@ export function buildRvConfigLines(input: RvConfigViewInput): string[] {
136
157
  lines.push(s.header);
137
158
  lines.push(`childExtensions: ${decision.enabled} (${sourceLabel})`);
138
159
  lines.push(` ${s.childExtensions}`);
160
+ lines.push(`jev: ${jevDecision.enabled} (${jevSourceLabel}) — ${hasJevApiKey(env) ? s.jevKeyPresent : s.jevKeyMissing}`);
161
+ lines.push(` ${s.jev}`);
139
162
  lines.push(`${s.configFileLabel}: ${file}`);
140
163
  for (const note of configNotes) lines.push(` ${note}`);
141
164
  lines.push("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zephyrdeng/pi-review",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
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>",
@@ -3,14 +3,15 @@
3
3
  "orcarouter": {
4
4
  "baseUrl": "https://api.orcarouter.ai/v1",
5
5
  "api": "openai-completions",
6
- "apiKey": "ORCA_KEY",
7
- "signupUrl": "https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36",
6
+ "apiKey": "$ORCA_KEY",
8
7
  "models": [
9
8
  {
10
9
  "id": "orcarouter/auto",
11
10
  "name": "OrcaRouter Auto",
12
11
  "reasoning": false,
13
- "input": ["text"],
12
+ "input": [
13
+ "text"
14
+ ],
14
15
  "contextWindow": 200000,
15
16
  "maxTokens": 8192
16
17
  },
@@ -18,7 +19,9 @@
18
19
  "id": "anthropic/claude-sonnet-4.6",
19
20
  "name": "Claude Sonnet 4.6",
20
21
  "reasoning": true,
21
- "input": ["text"],
22
+ "input": [
23
+ "text"
24
+ ],
22
25
  "contextWindow": 200000,
23
26
  "maxTokens": 8192
24
27
  }
@@ -0,0 +1,11 @@
1
+ # OrcaRouter provider configuration (Codex CLI / opencode-style TOML).
2
+ # Sign up & get a key: https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36
3
+
4
+ model = "orcarouter/auto"
5
+ model_provider = "orcarouter"
6
+
7
+ [model_providers.orcarouter]
8
+ name = "OrcaRouter"
9
+ base_url = "https://api.orcarouter.ai/v1"
10
+ wire_api = "responses"
11
+ env_key = "ORCA_KEY"
@@ -32,6 +32,17 @@ Review children stay isolated (`--no-extensions`) unless the persistent review c
32
32
 
33
33
  Before writing, tell the user the config is machine-level: every later pi-review on this machine (including bare CLI) inherits it. Write it only on acceptance; when editing an existing file, keep every unknown key and never overwrite a value the user set (invalid JSON — stop, do not overwrite). Verify on Pi with `/rv-config`, elsewhere with `cat ~/.pi/pi-review/config.json`. Isolate one run with `PI_REVIEW_CHILD_EXTENSIONS=0` (env overrides config). If a child exits with stale extension ctx after dispose/reload (issue #8), retry that one run with `PI_REVIEW_CHILD_EXTENSIONS=0`.
34
34
 
35
+ ### Setting config via the agent (preferred path)
36
+
37
+ There is no `/rv-config set` command — the agent is the config editor. When the user asks to change a pi-review setting, edit `~/.pi/pi-review/config.json` directly, with these rules:
38
+
39
+ - **Keys** — known schema today: `childExtensions` (bool), `jev` (bool). Keep every unknown key untouched (forward compat). Set only what the user asked for.
40
+ - **Desensitization (脱敏)** — the config file holds *flags only, never secrets*:
41
+ - `TYPESAFE_API_KEY` and any other API keys are **environment variables by design**; never write them into `config.json`, and never echo a key's value back to the user or into logs/docs. Show key state as set/unset only.
42
+ - Never commit `~/.pi/pi-review/config.json` (machine-level, may reflect personal setup) into any repo.
43
+ - After editing, confirm with `/rv-config` (Pi) or `cat` + `jq` (elsewhere) — display values, not file dumps, when the conversation is logged.
44
+ - **Sequence** — read the file (it may not exist), validate JSON, apply the one change, write back pretty-printed, verify with `/rv-config`, and state the machine-level consequence in one sentence.
45
+
35
46
  ## Default workflow by host
36
47
 
37
48
  | Host | How to run `pi-review` |
@@ -118,14 +129,16 @@ Use this protocol when the host is closing out implementation work and may edit
118
129
  - **stop-and-escalate** — ambiguous intent, architectural expansion, unsafe migration, blocked tooling, or anything requiring a human decision; stop rather than guess.
119
130
  - A rejected finding must be intentional and recorded with its rationale in the final report. Never silently ignore it.
120
131
  - Check sibling instances of the same bug class only inside the frozen task/PR scope. Do not turn the check into a repository-wide refactor.
132
+ - When `TYPESAFE_API_KEY` is available, `pi-review classify --baseline <text|@file> [--meta <path>]` turns this step into a typed Jev decision per finding (advisory; the host still owns the final call).
121
133
  6. **Fix only in-scope blockers in the host.** Never ask the child review session to implement fixes. After each host patch, rerun the narrowest relevant proof (focused test, typecheck, lint, or reproduction) before re-reviewing.
122
134
  7. **Re-review until a stop condition:**
123
135
  - `clean` → clean goal met; proceed to final proof and closeout.
124
136
  - `has_findings` → classify, fix accepted in-scope blockers, and re-invoke within the agreed host-cycle budget.
125
137
  - `needs_human` or `blocked` → stop early and escalate with the review history.
126
138
  - budget exhausted → report remaining findings and ask for a decision; do not loop indefinitely.
139
+ - `non_converging` → two consecutive rounds produced an identical actionable set; the tree is frozen between rounds, so more rounds are dice rolls. Fix in the host and re-invoke; do not re-roll.
127
140
  - With `--until clean`, the host owns the fix→re-review cycle until clean or hard budget. Advisories alone do not block clean; confirmed actionable findings do.
128
- 8. **Detect non-convergence.** After two non-converging patch cycles (the same finding persists, findings oscillate, or scope grows), pause and reclassify all remaining findings before any further edit.
141
+ 8. **Detect non-convergence.** After two non-converging patch cycles (the same finding persists, findings oscillate, or scope grows), pause and reclassify all remaining findings before any further edit. The loop's per-round `vs prev` comparison (persisting / new / resolved) is the machine signal for this; `--until clean` also stops early as `non_converging` when the actionable set is stable across two rounds.
129
142
  9. **Gate completion claims.** Never claim done, ship, commit-ready, or clean without a fresh `clean` result, unless the user gives explicit human acceptance of named remaining findings. Report accepted fixes, rejected findings with rationale, follow-ups, stop reason, and proof evidence.
130
143
 
131
144
  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.
@@ -1,2 +0,0 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- export default function piReviewExtension(pi: ExtensionAPI): void;
@@ -1,22 +0,0 @@
1
- import { buildRvOrchestrationPrompt, parseRvArgs, RV_COMPLETIONS } from "./rv-prompts.js";
2
- export default function piReviewExtension(pi) {
3
- pi.registerCommand("rv", {
4
- description: "Delegate pi-review to the agent (English prompts). Usage: /rv [--mode plan|challenge] [--model id] [--keep-session] @file-or-text | models",
5
- getArgumentCompletions: (prefix) => {
6
- const filtered = RV_COMPLETIONS.filter((item) => item.value.startsWith(prefix));
7
- return filtered.length
8
- ? filtered.map(({ value, hint }) => ({ value, label: value, description: hint }))
9
- : null;
10
- },
11
- handler: async (rawArgs, ctx) => {
12
- const trimmed = rawArgs.trim();
13
- const parsed = parseRvArgs(trimmed);
14
- const prompt = buildRvOrchestrationPrompt(parsed);
15
- if (!trimmed && !parsed.modelsOnly) {
16
- ctx.ui.notify("/rv needs a target or `models`. Try: /rv @path or /rv models", "warning");
17
- return;
18
- }
19
- pi.sendUserMessage(prompt);
20
- },
21
- });
22
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * English orchestration prompts for /rv — parent Pi agent runs pi-review per skill.
3
- * Child review sessions use presets in resources/review-presets.json (also English).
4
- */
5
- export type RvParsed = {
6
- mode: "code" | "plan" | "challenge";
7
- model?: string;
8
- keepSession: boolean;
9
- continueHandle?: string;
10
- modelsOnly: boolean;
11
- target: string;
12
- };
13
- export declare function parseRvArgs(raw: string): RvParsed;
14
- export declare function buildRvOrchestrationPrompt(parsed: RvParsed): string;
15
- /** Short labels for TUI completions (English). */
16
- export declare const RV_COMPLETIONS: {
17
- value: string;
18
- hint: string;
19
- }[];
@@ -1,132 +0,0 @@
1
- /**
2
- * English orchestration prompts for /rv — parent Pi agent runs pi-review per skill.
3
- * Child review sessions use presets in resources/review-presets.json (also English).
4
- */
5
- export function parseRvArgs(raw) {
6
- const tokens = raw.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) ?? [];
7
- const cleaned = tokens.map((t) => t.replace(/^['"]|['"]$/g, ""));
8
- let mode = "code";
9
- let model;
10
- let keepSession = false;
11
- let continueHandle;
12
- let modelsOnly = false;
13
- const rest = [];
14
- for (let i = 0; i < cleaned.length; i++) {
15
- const t = cleaned[i];
16
- if (t === "models" && rest.length === 0 && i === cleaned.length - 1) {
17
- modelsOnly = true;
18
- continue;
19
- }
20
- if (t === "--keep-session") {
21
- keepSession = true;
22
- continue;
23
- }
24
- if (t === "--mode" && cleaned[i + 1]) {
25
- const m = cleaned[++i];
26
- if (m === "plan" || m === "challenge" || m === "code")
27
- mode = m;
28
- continue;
29
- }
30
- if (t === "--model" && cleaned[i + 1]) {
31
- model = cleaned[++i];
32
- continue;
33
- }
34
- if (t === "--continue" && cleaned[i + 1]) {
35
- continueHandle = cleaned[++i];
36
- continue;
37
- }
38
- rest.push(t);
39
- }
40
- return {
41
- mode,
42
- model,
43
- keepSession,
44
- continueHandle,
45
- modelsOnly,
46
- target: rest.join(" ").trim(),
47
- };
48
- }
49
- function baseRules() {
50
- return [
51
- "Follow the pi-review skill.",
52
- "Run pi-review in an isolated child session; return only the review conclusion.",
53
- "Do not edit, patch, commit, or implement findings unless the user asks separately.",
54
- "Preserve the final PI_REVIEW_META line from pi-review output.",
55
- ].join(" ");
56
- }
57
- export function buildRvOrchestrationPrompt(parsed) {
58
- if (parsed.modelsOnly) {
59
- return [
60
- "Run the pi-review model catalog step.",
61
- baseRules(),
62
- "Execute: pi-review models",
63
- "Present a short English summary: how many providers, suggest 2–3 IDs suited for code review vs plan/challenge.",
64
- "Do not start a review until the user supplies a target (@path or text).",
65
- ].join("\n\n");
66
- }
67
- if (parsed.continueHandle) {
68
- return [
69
- "Continue a prior pi-review session.",
70
- baseRules(),
71
- `Execute: pi-review --continue ${parsed.continueHandle} -- ${parsed.target || "follow up on the previous review"}`,
72
- "Answer the follow-up in English; keep the same review-only scope.",
73
- ].join("\n\n");
74
- }
75
- if (!parsed.target) {
76
- return [
77
- "The /rv command needs a review target.",
78
- "Tell the user (in English): usage is /rv [--mode code|plan|challenge] [--model provider/model] [--keep-session] -- @files-or-brief",
79
- "Examples: /rv @src/foo.ts | /rv --mode challenge @docs/design.md | /rv models",
80
- ].join("\n\n");
81
- }
82
- const modeBlock = {
83
- code: [
84
- "Mode: code (default).",
85
- "Focus: correctness, regressions, security, concurrency, API contracts, edge cases, tests.",
86
- "Use read-only inspection via pi-review; no file mutations.",
87
- ].join(" "),
88
- plan: [
89
- "Mode: plan.",
90
- "Review architecture, design, or strategy through engineering, product, security, QA, ops, and DX lenses.",
91
- "Identify fatal flaws, trade-offs, sequencing risks, and minimal changes to de-risk the plan.",
92
- ].join(" "),
93
- challenge: [
94
- "Mode: challenge (adversarial).",
95
- "Pressure-test assumptions, boundaries, dependencies, failure modes, migration, and missing evidence.",
96
- "One-shot conclusion; do not run a live Q&A interview.",
97
- ].join(" "),
98
- };
99
- const cliParts = ["pi-review"];
100
- if (parsed.mode !== "code")
101
- cliParts.push(`--mode ${parsed.mode}`);
102
- if (parsed.model)
103
- cliParts.push(`--model ${parsed.model}`);
104
- if (parsed.keepSession)
105
- cliParts.push("--keep-session");
106
- cliParts.push("--", parsed.target);
107
- const modelStep = parsed.model
108
- ? `Use model exactly as given: ${parsed.model} (must appear in pi-review models output).`
109
- : "Run pi-review models first if needed; pick a suitable listed ID or omit --model for Pi default.";
110
- return [
111
- "Run pi-review for the target below.",
112
- baseRules(),
113
- modeBlock[parsed.mode],
114
- modelStep,
115
- parsed.keepSession
116
- ? "Use --keep-session so the user can follow up with /rv --continue <handle>."
117
- : "",
118
- `Execute:\n${cliParts.join(" ")}`,
119
- ]
120
- .filter(Boolean)
121
- .join("\n\n");
122
- }
123
- /** Short labels for TUI completions (English). */
124
- export const RV_COMPLETIONS = [
125
- { value: "@", hint: "file path after @ (e.g. @src/foo.ts)" },
126
- { value: "models", hint: "list pi-review models only" },
127
- { value: "--mode code", hint: "code / diff / MR review" },
128
- { value: "--mode plan", hint: "architecture or plan review" },
129
- { value: "--mode challenge", hint: "adversarial plan review" },
130
- { value: "--model ", hint: "provider/model from pi-review models" },
131
- { value: "--keep-session", hint: "persist session for follow-up" },
132
- ];