@zephyrdeng/pi-review 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +110 -13
  2. package/README.zh-CN.md +64 -3
  3. package/dist/args.d.ts +8 -0
  4. package/dist/args.d.ts.map +1 -1
  5. package/dist/args.js +147 -28
  6. package/dist/args.js.map +1 -1
  7. package/dist/args.test.d.ts +2 -0
  8. package/dist/args.test.d.ts.map +1 -0
  9. package/dist/args.test.js +115 -0
  10. package/dist/args.test.js.map +1 -0
  11. package/dist/cli-exit.test.d.ts +2 -0
  12. package/dist/cli-exit.test.d.ts.map +1 -0
  13. package/dist/cli-exit.test.js +84 -0
  14. package/dist/cli-exit.test.js.map +1 -0
  15. package/dist/cli.js +16 -2
  16. package/dist/cli.js.map +1 -1
  17. package/dist/config.d.ts +1 -0
  18. package/dist/config.d.ts.map +1 -1
  19. package/dist/config.js +1 -0
  20. package/dist/config.js.map +1 -1
  21. package/dist/extensions/review.d.ts +2 -0
  22. package/dist/extensions/review.js +22 -0
  23. package/dist/extensions/rv-prompts.d.ts +19 -0
  24. package/dist/extensions/rv-prompts.js +132 -0
  25. package/dist/index.d.ts +17 -7
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +12 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/json-events.d.ts +45 -0
  30. package/dist/json-events.d.ts.map +1 -1
  31. package/dist/json-events.js +185 -0
  32. package/dist/json-events.js.map +1 -1
  33. package/dist/json-events.test.js +64 -1
  34. package/dist/json-events.test.js.map +1 -1
  35. package/dist/loop.d.ts +36 -0
  36. package/dist/loop.d.ts.map +1 -0
  37. package/dist/loop.js +73 -0
  38. package/dist/loop.js.map +1 -0
  39. package/dist/loop.test.d.ts +2 -0
  40. package/dist/loop.test.d.ts.map +1 -0
  41. package/dist/loop.test.js +83 -0
  42. package/dist/loop.test.js.map +1 -0
  43. package/dist/matcher.d.ts +74 -0
  44. package/dist/matcher.d.ts.map +1 -0
  45. package/dist/matcher.js +202 -0
  46. package/dist/matcher.js.map +1 -0
  47. package/dist/matcher.test.d.ts +2 -0
  48. package/dist/matcher.test.d.ts.map +1 -0
  49. package/dist/matcher.test.js +161 -0
  50. package/dist/matcher.test.js.map +1 -0
  51. package/dist/meta-footer.d.ts +15 -1
  52. package/dist/meta-footer.d.ts.map +1 -1
  53. package/dist/meta-footer.js +108 -0
  54. package/dist/meta-footer.js.map +1 -1
  55. package/dist/meta-footer.test.js +43 -1
  56. package/dist/meta-footer.test.js.map +1 -1
  57. package/dist/panel-aggregate.d.ts +18 -0
  58. package/dist/panel-aggregate.d.ts.map +1 -0
  59. package/dist/panel-aggregate.js +247 -0
  60. package/dist/panel-aggregate.js.map +1 -0
  61. package/dist/panel-aggregate.test.d.ts +2 -0
  62. package/dist/panel-aggregate.test.d.ts.map +1 -0
  63. package/dist/panel-aggregate.test.js +461 -0
  64. package/dist/panel-aggregate.test.js.map +1 -0
  65. package/dist/panel-cli.test.d.ts +2 -0
  66. package/dist/panel-cli.test.d.ts.map +1 -0
  67. package/dist/panel-cli.test.js +188 -0
  68. package/dist/panel-cli.test.js.map +1 -0
  69. package/dist/panel-config.d.ts +19 -0
  70. package/dist/panel-config.d.ts.map +1 -0
  71. package/dist/panel-config.js +115 -0
  72. package/dist/panel-config.js.map +1 -0
  73. package/dist/panel-config.test.d.ts +2 -0
  74. package/dist/panel-config.test.d.ts.map +1 -0
  75. package/dist/panel-config.test.js +91 -0
  76. package/dist/panel-config.test.js.map +1 -0
  77. package/dist/panel-loop.test.d.ts +2 -0
  78. package/dist/panel-loop.test.d.ts.map +1 -0
  79. package/dist/panel-loop.test.js +118 -0
  80. package/dist/panel-loop.test.js.map +1 -0
  81. package/dist/panel.d.ts +10 -0
  82. package/dist/panel.d.ts.map +1 -0
  83. package/dist/panel.js +315 -0
  84. package/dist/panel.js.map +1 -0
  85. package/dist/presets.d.ts +2 -1
  86. package/dist/presets.d.ts.map +1 -1
  87. package/dist/presets.js +10 -0
  88. package/dist/presets.js.map +1 -1
  89. package/dist/prompt.d.ts +14 -1
  90. package/dist/prompt.d.ts.map +1 -1
  91. package/dist/prompt.js +61 -15
  92. package/dist/prompt.js.map +1 -1
  93. package/dist/prompt.test.d.ts +2 -0
  94. package/dist/prompt.test.d.ts.map +1 -0
  95. package/dist/prompt.test.js +37 -0
  96. package/dist/prompt.test.js.map +1 -0
  97. package/dist/review-result.d.ts +5 -0
  98. package/dist/review-result.d.ts.map +1 -0
  99. package/dist/review-result.js +98 -0
  100. package/dist/review-result.js.map +1 -0
  101. package/dist/review-result.test.d.ts +2 -0
  102. package/dist/review-result.test.d.ts.map +1 -0
  103. package/dist/review-result.test.js +196 -0
  104. package/dist/review-result.test.js.map +1 -0
  105. package/dist/review.d.ts +10 -4
  106. package/dist/review.d.ts.map +1 -1
  107. package/dist/review.js +82 -20
  108. package/dist/review.js.map +1 -1
  109. package/dist/review.meta.test.js +2 -2
  110. package/dist/review.meta.test.js.map +1 -1
  111. package/dist/skill-protocol.test.d.ts +2 -0
  112. package/dist/skill-protocol.test.d.ts.map +1 -0
  113. package/dist/skill-protocol.test.js +35 -0
  114. package/dist/skill-protocol.test.js.map +1 -0
  115. package/dist/types.d.ts +147 -5
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/types.js +11 -0
  118. package/dist/types.js.map +1 -1
  119. package/package.json +3 -3
  120. package/resources/panel-presets.json +21 -0
  121. package/resources/system-prompt.md +11 -1
  122. package/skills/pi-review/SKILL.md +90 -12
  123. package/skills/pi-review/references/codex-tools.md +19 -6
package/dist/types.d.ts CHANGED
@@ -1,7 +1,21 @@
1
1
  export declare const VERDICTS: readonly ["approve", "request_changes", "needs_clarification", "blocked"];
2
2
  export type Verdict = (typeof VERDICTS)[number];
3
+ export declare const REVIEW_STATUSES: readonly ["clean", "has_findings", "needs_human", "blocked"];
4
+ export type ReviewStatus = (typeof REVIEW_STATUSES)[number];
5
+ export interface ReviewFinding {
6
+ id?: string;
7
+ severity?: string;
8
+ path?: string;
9
+ summary: string;
10
+ actionable: boolean;
11
+ }
12
+ export interface StructuredReviewResult extends VerdictInfo {
13
+ status: ReviewStatus;
14
+ findings: ReviewFinding[];
15
+ actionableCount: number;
16
+ }
3
17
  export interface ParsedArgs {
4
- command: "review" | "models" | "install" | "install-skill" | "uninstall-skill" | "update";
18
+ command: "review" | "loop" | "models" | "install" | "install-skill" | "uninstall-skill" | "update";
5
19
  /** For `install`: run `pi install npm:@zephyrdeng/pi-review` */
6
20
  installPi?: boolean;
7
21
  /** For `install`: run agent skill install (skills CLI / Claude fallback) */
@@ -15,6 +29,8 @@ export interface ParsedArgs {
15
29
  stream: boolean;
16
30
  /** When set, run the child in --mode json and stream its event log to this file path. */
17
31
  progressLog?: string;
32
+ /** Review budget for the loop command. */
33
+ maxRounds?: number;
18
34
  continueHandle?: string;
19
35
  model?: string;
20
36
  provider?: string;
@@ -22,6 +38,18 @@ export interface ParsedArgs {
22
38
  tools?: string;
23
39
  name?: string;
24
40
  search?: string[];
41
+ /** Panel: number of independent reviewers (generic same-model panel). */
42
+ reviewers?: number;
43
+ /** Panel: named expert-panel preset. */
44
+ panel?: string;
45
+ /** Panel: consensus policy (any | quorum | majority | unanimous). */
46
+ consensus?: string;
47
+ /** Panel: minimum agreement for quorum consensus. */
48
+ minAgree?: number;
49
+ /** Panel: model used for semantic consensus adjudication. */
50
+ consensusModel?: string;
51
+ /** Panel: bounded reviewer concurrency. */
52
+ concurrency?: number;
25
53
  }
26
54
  export interface ReviewPreset {
27
55
  description: string;
@@ -37,17 +65,131 @@ export interface VerdictInfo {
37
65
  verdictSource: "parsed" | "fallback" | "runtime_error";
38
66
  parseError?: string;
39
67
  }
40
- export interface ReviewMeta {
68
+ export interface ReviewMeta extends StructuredReviewResult {
41
69
  reviewMode: string;
42
- verdict: Verdict;
43
- verdictSource: string;
44
70
  durationMs: number;
45
71
  model: string | null;
72
+ /** Thinking level requested for this review (off|minimal|low|medium|high|xhigh|max), if any. */
73
+ thinking?: string;
74
+ /** Token usage from the child pi --mode json stream, when available. */
75
+ usage?: TokenUsage;
46
76
  sessionHandle?: string;
47
- parseError?: string;
77
+ }
78
+ export interface ReviewRunResult {
79
+ meta: ReviewMeta;
80
+ exitCode: number;
48
81
  }
49
82
  export interface SplitPayload {
50
83
  fileRefs: string[];
51
84
  userText: string;
52
85
  }
86
+ export declare const CONSENSUS_POLICIES: readonly ["any", "quorum", "majority", "unanimous"];
87
+ export type ConsensusPolicy = (typeof CONSENSUS_POLICIES)[number];
88
+ /** Token usage accumulated across an agent turn (from pi's --mode json stream). */
89
+ export interface TokenUsage {
90
+ input: number;
91
+ output: number;
92
+ cacheRead: number;
93
+ cacheWrite: number;
94
+ reasoning: number;
95
+ totalTokens: number;
96
+ costTotal?: number;
97
+ }
98
+ /** Documented initial maximum number of reviewers in one panel. */
99
+ export declare const MAX_REVIEWERS = 8;
100
+ /** Default minimum agreement for a multi-reviewer quorum panel. */
101
+ export declare const DEFAULT_PANEL_MIN_AGREE = 2;
102
+ /** Confidence at or above which a semantic adjudicator match merges clusters. */
103
+ export declare const SEMANTIC_MATCH_CONFIDENCE_THRESHOLD = 0.6;
104
+ /** A raw finding tagged with reviewer identity and a globally-unique source ID. */
105
+ export interface SourceFinding {
106
+ /** Globally unique id scoped to reviewer identity, e.g. "r1#F1". */
107
+ id: string;
108
+ reviewerId: string;
109
+ finding: ReviewFinding;
110
+ }
111
+ /**
112
+ * A cluster of findings that represent the same underlying issue.
113
+ * `confirmed` is true only when actionable support meets the consensus
114
+ * threshold; otherwise the cluster is a non-blocking advisory.
115
+ */
116
+ export interface FindingCluster {
117
+ /** Stable cluster id within one panel evaluation, e.g. "C1". */
118
+ id: string;
119
+ summary: string;
120
+ severity?: string;
121
+ path?: string;
122
+ confirmed: boolean;
123
+ /** Distinct reviewers contributing any finding to this cluster. */
124
+ supportCount: number;
125
+ /** Distinct reviewers contributing an actionable finding. */
126
+ actionableSupportCount: number;
127
+ supportingReviewerIds: string[];
128
+ sourceFindingIds: string[];
129
+ }
130
+ export type PanelHealth = "healthy" | "needs_human" | "blocked";
131
+ /** Per-reviewer provenance recorded in the aggregate panel metadata. */
132
+ export interface ReviewerOutcome {
133
+ reviewerId: string;
134
+ role?: string;
135
+ model?: string | null;
136
+ thinking?: string;
137
+ usage?: TokenUsage;
138
+ durationMs: number;
139
+ status: ReviewStatus;
140
+ verdict: Verdict;
141
+ verdictSource: VerdictInfo["verdictSource"];
142
+ /** True when this reviewer contributed parseable findings to aggregation. */
143
+ contributed: boolean;
144
+ runtimeError?: string;
145
+ parseError?: string;
146
+ }
147
+ /** Additive panel fields shared by the aggregation result and the review meta. */
148
+ export interface PanelFields {
149
+ strategy: "panel";
150
+ panelPreset?: string;
151
+ configuredReviewers: number;
152
+ successfulReviewers: number;
153
+ consensusPolicy: ConsensusPolicy;
154
+ consensusThreshold: number;
155
+ panelHealth: PanelHealth;
156
+ confirmedClusters: FindingCluster[];
157
+ advisories: FindingCluster[];
158
+ reviewers: ReviewerOutcome[];
159
+ adjudicationUsed: boolean;
160
+ adjudicationErrors?: string[];
161
+ }
162
+ /** Pure aggregate panel result (no Pi, no I/O). */
163
+ export interface PanelAggregationResult extends StructuredReviewResult, PanelFields {
164
+ }
165
+ /** Review metadata for a panel evaluation; additive over ReviewMeta. */
166
+ export interface PanelReviewMeta extends ReviewMeta, PanelFields {
167
+ }
168
+ /** A reviewer's structured submission fed to the pure aggregation seam. */
169
+ export interface ReviewerSubmission {
170
+ reviewerId: string;
171
+ role?: string;
172
+ model?: string | null;
173
+ thinking?: string;
174
+ usage?: TokenUsage;
175
+ durationMs: number;
176
+ result: StructuredReviewResult;
177
+ }
178
+ /** One reviewer definition inside a named panel preset. */
179
+ export interface PanelReviewerSpec {
180
+ id: string;
181
+ role: string;
182
+ provider?: string;
183
+ model?: string;
184
+ thinking?: string;
185
+ }
186
+ /** A named expert-panel preset. */
187
+ export interface PanelPreset {
188
+ description: string;
189
+ reviewers: PanelReviewerSpec[];
190
+ consensus?: ConsensusPolicy;
191
+ minAgree?: number;
192
+ consensusModel?: string;
193
+ concurrency?: number;
194
+ }
53
195
  //# sourceMappingURL=types.d.ts.map
@@ -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,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IAC1F,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,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,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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;CACnB;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,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,2 +1,13 @@
1
1
  export const VERDICTS = ["approve", "request_changes", "needs_clarification", "blocked"];
2
+ export const REVIEW_STATUSES = ["clean", "has_findings", "needs_human", "blocked"];
3
+ // ---------------------------------------------------------------------------
4
+ // Panel review
5
+ // ---------------------------------------------------------------------------
6
+ export const CONSENSUS_POLICIES = ["any", "quorum", "majority", "unanimous"];
7
+ /** Documented initial maximum number of reviewers in one panel. */
8
+ export const MAX_REVIEWERS = 8;
9
+ /** Default minimum agreement for a multi-reviewer quorum panel. */
10
+ export const DEFAULT_PANEL_MIN_AGREE = 2;
11
+ /** Confidence at or above which a semantic adjudicator match merges clusters. */
12
+ export const SEMANTIC_MATCH_CONFIDENCE_THRESHOLD = 0.6;
2
13
  //# sourceMappingURL=types.js.map
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"}
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;AA4F5F,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,mEAAmE;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zephyrdeng/pi-review",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
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>",
@@ -24,7 +24,7 @@
24
24
  "cli"
25
25
  ],
26
26
  "bin": {
27
- "pi-review": "./bin/pi-review.js"
27
+ "pi-review": "bin/pi-review.js"
28
28
  },
29
29
  "exports": {
30
30
  ".": {
@@ -67,7 +67,7 @@
67
67
  "build": "tsc",
68
68
  "check": "tsc --noEmit",
69
69
  "smoke": "node dist/cli.js --help >/dev/null",
70
- "test": "npx --yes tsx --test src/child-process.test.ts src/review.meta.test.ts src/meta-footer.test.ts src/json-events.test.ts src/install-args.test.ts extensions/rv-prompts.test.ts extensions/rv-completions.test.ts extensions/rv-model-priorities.test.ts extensions/rv-locale.test.ts extensions/rv-semantic.test.ts",
70
+ "test": "npx --yes tsx --test src/args.test.ts src/cli-exit.test.ts src/child-process.test.ts src/review.meta.test.ts src/review-result.test.ts src/loop.test.ts src/meta-footer.test.ts src/prompt.test.ts src/skill-protocol.test.ts src/json-events.test.ts src/install-args.test.ts src/panel-aggregate.test.ts src/matcher.test.ts src/panel-config.test.ts src/panel-loop.test.ts src/panel-cli.test.ts extensions/rv-prompts.test.ts extensions/rv-completions.test.ts extensions/rv-model-priorities.test.ts extensions/rv-locale.test.ts extensions/rv-semantic.test.ts",
71
71
  "test:rv": "npx --yes tsx --test extensions/rv-prompts.test.ts extensions/rv-completions.test.ts extensions/rv-model-priorities.test.ts extensions/rv-locale.test.ts extensions/rv-semantic.test.ts",
72
72
  "prepublishOnly": "npm run build",
73
73
  "pack:dry": "npm pack --dry-run"
@@ -0,0 +1,21 @@
1
+ {
2
+ "code-experts": {
3
+ "description": "Code review panel with independent correctness, security, and testing lenses.",
4
+ "consensus": "quorum",
5
+ "minAgree": 2,
6
+ "reviewers": [
7
+ {
8
+ "id": "correctness",
9
+ "role": "Correctness reviewer: focus on logic errors, regressions, concurrency, API contracts, edge cases, and maintainability."
10
+ },
11
+ {
12
+ "id": "security",
13
+ "role": "Security reviewer: focus on input validation, authn/authz, secrets, injection, unsafe deserialization, and trust boundaries."
14
+ },
15
+ {
16
+ "id": "testing",
17
+ "role": "Testing reviewer: focus on missing tests, weak assertions, flakiness, coverage gaps, and behavior that would escape the test suite."
18
+ }
19
+ ]
20
+ }
21
+ }
@@ -34,7 +34,17 @@ One of: approve | request_changes | needs_clarification | blocked
34
34
  Short conclusion in 2-5 bullets.
35
35
 
36
36
  ## Findings
37
- Prioritized findings. Each finding should include severity, evidence, impact, and recommendation. If there are no material findings, write "No material findings."
37
+ Prioritized findings. For every material finding, use this exact shape (increment IDs as F1, F2, ...):
38
+
39
+ ### F1: <summary>
40
+ - Severity: critical | high | medium | low
41
+ - Path: <path or none>
42
+ - Actionable: yes | no
43
+ - Evidence: <concrete evidence>
44
+ - Impact: <why it matters>
45
+ - Recommendation: <specific next step>
46
+
47
+ Set Actionable to yes when the host must fix or consciously reject the finding before clean closeout. Use no for informational or explicitly out-of-scope follow-up findings. If there are no material findings, write "No material findings."
38
48
 
39
49
  ## Risks and Blind Spots
40
50
  What could still be wrong, missing, or unverified.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pi-review
3
- description: Use pi-review to delegate isolated code, diff, repository, architecture, or plan reviews to a fresh Pi session and return only the review conclusion. Model selection presets for code, frontend, and plan review (see references/model-selection.md). On Claude Code or Codex, default to --progress-log with a background shell run and tail the log (chat tools buffer stdout). Use when the user asks for Pi review, isolated review, code review, plan review, challenge review, review status/progress, or wants to avoid context pollution.
3
+ description: Use pi-review to delegate isolated code, diff, repository, architecture, or plan reviews to fresh Pi sessions and return review conclusions. Also use for loop review, review-fix-re-review closeout, structured review gates, and review status/progress. Model selection presets for code, frontend, and plan review are in references/model-selection.md. On Claude Code or Codex, default to --progress-log with a background shell run and tail the log (chat tools buffer stdout).
4
4
  ---
5
5
 
6
6
  # Pi Review
@@ -45,15 +45,10 @@ When resolving this fallback, use the actual directory that contains this `SKILL
45
45
 
46
46
  ## Streaming vs agent hosts (Claude Code / Codex)
47
47
 
48
- - `pi-review` **streams** child `pi` stdout/stderr to the process terminal by default (`--no-stream` buffers until exit). That helps **Pi** and real terminals, not most agent chat UIs.
49
- - **Claude Code, Cursor, Codex**, and similar hosts **buffer tool stdout** until the bash command exits, so the chat shows the review **all at once** even though the CLI is streaming. That is expected—not a misconfiguration.
50
- - Default `text` mode also produces **no stdout** during tool-use/thinking (only the final answer), so even a local terminal stays quiet for most of a multi-minute review.
51
- - **Recommended for Claude Code / Codex (live progress):** always use `--progress-log <path>` unless the user explicitly wants a silent blocking wait:
52
- 1. Pick a writable path (e.g. `/tmp/pi-review-<id>.jsonl`).
53
- 2. Start `pi-review --progress-log <path> ...` in a **background** or **async** shell invocation (not a blocking foreground Bash that you wait on with no updates).
54
- 3. While the child runs, **tail** the log and summarize milestones to the user (filter out `message_update` / `tool_execution_update` unless they asked for token-level detail).
55
- 4. When the process exits, show the Markdown body and ASCII `── pi-review` footer from the command result (or re-read the final output as the skill’s step 4 describes).
56
- - Fall back to a **local terminal** with default streaming only if the host cannot run background commands or tail a file.
48
+ - `pi-review` always runs the child in `--mode json` internally. In streaming mode it forwards **readable text deltas** to stdout live and writes **semantic milestone notices** (`pi-review: review started`, `pi-review: tool <name> started/finished`, `pi-review: review finished`) to **stderr**. Token usage (`input`/`output`/`cache`/`reasoning`) is accumulated by default — no `--progress-log` required to see it in the ASCII footer or `PI_REVIEW_META_JSON`.
49
+ - `--progress-log <path>` is now an **optional** convenience: it tees the raw `--mode json` event stream to a file for external observation (tail, debugging). It no longer gates token visibility.
50
+ - **Claude Code, Cursor, Codex** and similar hosts still buffer a Bash tool's stdout until the command exits. The semantic milestone notices on stderr + the final Markdown + ASCII footer on stdout give you progress and the result without needing to tail a file. If you still want the full event log for fine-grained debugging, add `--progress-log <path>` and tail it.
51
+ - **Pi interactive** sessions stream text deltas live to the terminal by default — no `--no-stream` or `--progress-log` needed.
57
52
 
58
53
  ## Review status (no slash command)
59
54
 
@@ -78,6 +73,87 @@ There is **no** `/status` slash in this skill. When the user asks for **review s
78
73
 
79
74
  Do not implement findings from a status check; status is informational only.
80
75
 
76
+ ## Loop closeout protocol
77
+
78
+ Use this protocol when the host is closing out implementation work and may edit between reviews. `pi-review` and every child session remain review-only; the host agent owns all fixes.
79
+
80
+ 1. **Freeze the scope baseline before the first review.** Record the originating task, accepted files/modules, required behavior, and proof commands. Do not silently expand this baseline because a reviewer noticed adjacent cleanup.
81
+ 2. **Run a bounded structured gate.** Prefer the productized command:
82
+ ```bash
83
+ pi-review loop --max-rounds 1 [shared review options] -- <@files|text...>
84
+ ```
85
+ A one-round invocation gives the host a fix point between reviews. Increase `--max-rounds` only when repeated independent review of the unchanged tree is intentional; the CLI never waits for edits. Re-invocation after a host fix is a new process. On Claude Code / Codex, compose `loop` with the normal `--progress-log <path>` background + tail workflow. On Pi, retain default foreground streaming. `loop` rejects `--keep-session`, `--continue`, and `--name`.
86
+ 3. **Read the gate signals.** Parse `status`, `findings`, and `actionableCount` from each `PI_REVIEW_META_JSON` line and use the final loop summary. Expected statuses are `clean`, `has_findings`, `needs_human`, and `blocked`.
87
+ 4. **Apply the scope governor to every finding:**
88
+ - **in-scope blocker** — accepted, actionable, and required by the frozen task; the host may fix it now.
89
+ - **follow-up** — valid but outside the baseline or not required for safe closeout; record it without drive-by edits.
90
+ - **stop-and-escalate** — ambiguous intent, architectural expansion, unsafe migration, blocked tooling, or anything requiring a human decision; stop rather than guess.
91
+ - A rejected finding must be intentional and recorded with its rationale in the final report. Never silently ignore it.
92
+ - 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.
93
+ 5. **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.
94
+ 6. **Re-review until a stop condition:**
95
+ - `clean` → gate open; proceed to final proof and closeout.
96
+ - `has_findings` → classify, fix accepted in-scope blockers, and re-invoke within the agreed host-cycle budget.
97
+ - `needs_human` or `blocked` → stop early and escalate with the review history.
98
+ - budget exhausted → report remaining findings and ask for a decision; do not loop indefinitely.
99
+ 7. **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.
100
+ 8. **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.
101
+
102
+ 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.
103
+
104
+ ## Panel review
105
+
106
+ 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.
107
+
108
+ ### When to use panel vs single review
109
+
110
+ - **Single review (default):** keep for small, low-cost changes. Reviewer count defaults to one; the existing execution, output, status mapping, and exit policy stay unchanged.
111
+ - **Panel review:** use when a change deserves independent scrutiny. Activate it with `--reviewers <n>` (2-8) or `--panel <name>`.
112
+
113
+ ### Consensus
114
+
115
+ A finding becomes a **confirmed finding** (gate-relevant) only when enough independent reviewers mark the issue **actionable**. Otherwise it stays a non-blocking **advisory**.
116
+
117
+ Consensus policies (default `quorum` for multi-reviewer panels):
118
+
119
+ | Policy | Threshold |
120
+ |--------|----------|
121
+ | `any` | one actionable reviewer confirms |
122
+ | `quorum` | configured minimum agreement (default 2; set with `--min-agree`) |
123
+ | `majority` | `floor(reviewers / 2) + 1` |
124
+ | `unanimous` | every reviewer |
125
+
126
+ Multi-reviewer panels default to **quorum with minimum agreement 2** so panel mode never silently becomes any-finding fail-closed. Single-review stays threshold one.
127
+
128
+ ### Advisories
129
+
130
+ Singleton (uncorroborated) findings remain visible as **advisories** but do **not** change clean status or fail the gate. They are recorded as non-blocking follow-ups; the host promotes them only with explicit human acceptance. Confirmed actionable clusters produce `has_findings`; no confirmed clusters produce `clean`.
131
+
132
+ ### Aggregation
133
+
134
+ Two-phase matching: deterministic matching on stable anchors (path + normalized summary) first; only ambiguous same-path candidates go to a constrained **semantic adjudicator** (enabled with `--consensus-model`). The adjudicator clusters findings and may **not** invent findings, drop findings, add evidence, or act as another reviewer — it has no write tools. Low-confidence matches stay separate advisories so uncertain similarity cannot manufacture quorum.
135
+
136
+ ### Cost multipliers
137
+
138
+ Cost is visible before execution. Reviewer runs = `--reviewers <n>` × `--max-rounds` (loop). One consensus-adjudication call may run per round when `--consensus-model` is set, tracked separately. Use `--concurrency <n>` to bound provider/machine pressure (default: reviewer count, never exceeds it).
139
+
140
+ ### Host-only fixes
141
+
142
+ Panel review composes with Loop Review: one loop round evaluates one **complete panel** with fresh reviewer sessions. The CLI never edits, patches, or waits for filesystem changes — the host agent remains the only actor allowed to fix between process invocations. Apply the scope governor to **confirmed** findings exactly as for single-review findings. Rejected confirmed findings must be recorded with rationale. `--max-rounds 1` keeps the patch-by-patch closeout workflow.
143
+
144
+ Panel review rejects `--keep-session`, `--continue`, and `--name` in v1 (reviewers run `--no-session`). Reviewer runtime failure → `blocked`; unstructured dirty output or unresolved clarification → `needs_human`; never silently clean.
145
+
146
+ ### Examples
147
+
148
+ ```bash
149
+ # Single panel review
150
+ pi-review --reviewers 3 --consensus quorum --min-agree 2 -- @src
151
+ # Expert preset
152
+ pi-review --panel code-experts --consensus majority -- @src
153
+ # Panel loop review (up to 6 reviewer runs + adjudication)
154
+ pi-review loop --reviewers 3 --consensus quorum --max-rounds 2 -- @src
155
+ ```
156
+
81
157
  ## Steps
82
158
 
83
159
  1. Prime the model catalog and pick a model:
@@ -116,8 +192,8 @@ Do not implement findings from a status check; status is informational only.
116
192
 
117
193
  4. Return the result:
118
194
  - Show the Markdown review body and the **ASCII footer** (`── pi-review` block on stdout). Do not paste raw `PI_REVIEW_META_JSON` to the user unless they ask for machine output.
119
- - Scripts: parse `PI_REVIEW_META_JSON:` from **stderr** (or set `PI_REVIEW_META_STDOUT=1` to also emit JSON on stdout).
120
- - Do not apply findings automatically; implementation is a separate user decision.
195
+ - Scripts: parse `PI_REVIEW_META_JSON:` from **stderr** (or set `PI_REVIEW_META_STDOUT=1` to emit JSON on stdout instead).
196
+ - For an ordinary review-only request, do not apply findings automatically; implementation is a separate user decision. When the user already requested implementation closeout, follow **Loop closeout protocol** and let only the host fix accepted in-scope blockers.
121
197
  Completion criterion: the user sees the review conclusion and readable footer.
122
198
 
123
199
  ## Examples
@@ -127,6 +203,8 @@ pi-review -- @src/foo.ts
127
203
  pi-review --model openai/gpt-5.5 -- @src/foo.ts
128
204
  pi-review --mode challenge --keep-session -- @docs/design.md
129
205
  pi-review --mode challenge --continue <sessionHandle> -- "expand finding 2"
206
+ pi-review loop --max-rounds 1 -- @src
207
+ pi-review loop --max-rounds 1 --progress-log /tmp/pi-review-loop.jsonl -- @src
130
208
  ```
131
209
 
132
210
  ## Status examples (user phrasing)
@@ -12,19 +12,32 @@ General Codex subagent and worktree mappings live in the **using-superpowers** s
12
12
 
13
13
  ## Long-running `pi-review` (default on Codex / Claude Code)
14
14
 
15
- Native shell tools usually **buffer stdout/stderr until the command exits**. A multi-minute `pi-review` run can look like a silent wait, then one large dump—even though the CLI streams by default. Default `text` mode also emits **no stdout** during tool-use/thinking (only the final answer).
15
+ Native shell tools usually **buffer stdout/stderr until the command exits**. A multi-minute `pi-review` run can look like a silent wait, then one large dump. `pi-review` mitigates this in two ways that need **no** `--progress-log`:
16
+
17
+ 1. **Semantic milestone notices on stderr** (`pi-review: review started`, `pi-review: tool <name> started/finished`, `pi-review: review finished`). Capture stderr separately or interleave it to show progress.
18
+ 2. **Token usage by default**: the ASCII footer and `PI_REVIEW_META_JSON` always include `thinking` + token usage (`input`/`output`/`cache`/`reasoning`) when the child session reports them — no `--progress-log` required.
16
19
 
17
20
  When the **pi-review** skill applies on Codex, Claude Code, or Cursor:
18
21
 
19
- 1. **Default:** `pi-review --progress-log <path> ...` (writable file, e.g. `/tmp/pi-review-<id>.jsonl`).
20
- 2. Start that command in a **background** or **async** shell invocation—not a single blocking call with no interim updates.
21
- 3. **Tail** the log while the child runs; summarize milestones to the user (skip `message_update` / `tool_execution_update` unless they want token-level detail).
22
- 4. After exit, show the Markdown review and ASCII `── pi-review` footer (skill step 4).
22
+ 1. **Default:** run `pi-review ... -- <target>` (foreground or background). Stderr carries milestone notices; stdout carries the review Markdown + ASCII footer on exit.
23
+ 2. If you want the **full** `--mode json` event log for fine-grained debugging, add `--progress-log <path>` and tail it — but this is optional, not required for tokens or progress.
24
+ 3. After exit, show the Markdown review body and ASCII `── pi-review` footer (skill step 4).
23
25
 
24
- **Pi interactive (`/rv`)** is different: foreground `pi-review`, default streaming only—do **not** auto-add `--progress-log` unless the user asked.
26
+ **Pi interactive (`/rv`)**: foreground `pi-review`, default streaming. Text deltas appear live on the terminal; no `--progress-log` unless the user asked.
25
27
 
26
28
  See the parent skill: sections *Default workflow by host* and *Streaming vs agent hosts (Claude Code / Codex)*.
27
29
 
30
+ ### Loop closeout
31
+
32
+ `loop` composes with the same default streaming + stderr-milestone workflow:
33
+
34
+ ```bash
35
+ pi-review loop --max-rounds 1 -- @src
36
+ # optional: --progress-log /tmp/pi-review-loop.jsonl for the full event log
37
+ ```
38
+
39
+ A non-zero command exit is an expected gate result when findings remain. Wait for the process, read the final `PI_REVIEW_META_JSON` / loop summary, let the host fix only accepted in-scope findings, rerun focused proof, and invoke a new loop process. The child review session never edits. Reuse or truncate the progress log deliberately because every loop round appends events to the chosen path.
40
+
28
41
  **Model choice:** after `pi-review models`, use **[model-selection.md](./model-selection.md)** (code / frontend / plan presets)—same guidance as Pi `/rv` completions.
29
42
 
30
43
  Example tail (milestone events only):