@zephyrdeng/pi-review 0.16.1 → 0.17.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/README.md +103 -491
- package/README.zh-CN.md +108 -274
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +6 -0
- package/dist/args.js.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/extensions/review.d.ts +2 -0
- package/dist/extensions/review.js +22 -0
- package/dist/extensions/rv-prompts.d.ts +19 -0
- package/dist/extensions/rv-prompts.js +132 -0
- package/dist/jev.d.ts.map +1 -1
- package/dist/jev.js +29 -13
- package/dist/jev.js.map +1 -1
- package/dist/jev.test.js +46 -0
- package/dist/jev.test.js.map +1 -1
- package/dist/screen-memory.d.ts +111 -0
- package/dist/screen-memory.d.ts.map +1 -0
- package/dist/screen-memory.js +320 -0
- package/dist/screen-memory.js.map +1 -0
- package/dist/screen-memory.test.d.ts +2 -0
- package/dist/screen-memory.test.d.ts.map +1 -0
- package/dist/screen-memory.test.js +145 -0
- package/dist/screen-memory.test.js.map +1 -0
- package/dist/screen.d.ts +17 -0
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +183 -11
- package/dist/screen.js.map +1 -1
- package/dist/screen.test.js +69 -1
- package/dist/screen.test.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/pi-review/SKILL.md +8 -0
package/README.md
CHANGED
|
@@ -1,358 +1,60 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# pi-review
|
|
2
4
|
|
|
5
|
+
**Isolated, multi-reviewer AI code review — as a CLI, a CI gate, and an agent skill.**
|
|
6
|
+
|
|
3
7
|
[](https://www.npmjs.com/package/@zephyrdeng/pi-review)
|
|
4
|
-
[](https://www.npmjs.com/package/@zephyrdeng/pi-review)
|
|
9
|
+
[](https://github.com/ZephyrDeng/pi-review/stargazers)
|
|
10
|
+
[](LICENSE)
|
|
5
11
|
[](https://nodejs.org)
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`pi-review` delegates review work to a fresh, isolated [Pi](https://github.com/anthropics/pi) session and returns a structured review conclusion. The child session is review-only — it reads code, analyzes it, and reports findings without making any changes.
|
|
10
|
-
|
|
11
|
-
Works as a standalone CLI, a Pi package (extension + skill), or integrated into CI pipelines and editor workflows.
|
|
12
|
-
|
|
13
|
-
## Prerequisites
|
|
14
|
-
|
|
15
|
-
- [Pi CLI](https://pi.dev) installed and configured with at least one model provider
|
|
16
|
-
|
|
17
|
-
## Run reviews on OrcaRouter
|
|
18
|
-
|
|
19
|
-
`pi-review` is model-agnostic — it runs on any model provider configured in your
|
|
20
|
-
[Pi](https://pi.dev) installation. To use [OrcaRouter](https://www.orcarouter.ai) as
|
|
21
|
-
the provider behind your reviews:
|
|
22
|
-
|
|
23
|
-
1. **Get a key** — no account yet? **Sign up with our referral link** <https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36> (also available from the badge below). Already have a key? Skip ahead.
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
export ORCA_KEY="sk-orca-..."
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
2. **Register the provider** — merge [`resources/providers/orcarouter.json`](./resources/providers/orcarouter.json) into `~/.pi/agent/models.json` (OpenAI-compatible). If that file already exists, **merge, don't copy** — `cp` would overwrite every other provider you configured:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
# fresh machine (no models.json yet):
|
|
33
|
-
cp resources/providers/orcarouter.json ~/.pi/agent/models.json
|
|
34
|
-
# existing models.json — merge instead (or edit by hand):
|
|
35
|
-
jq -s '.[0] * .[1]' ~/.pi/agent/models.json resources/providers/orcarouter.json > /tmp/models.json && mv /tmp/models.json ~/.pi/agent/models.json
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"providers": {
|
|
41
|
-
"orcarouter": {
|
|
42
|
-
"baseUrl": "https://api.orcarouter.ai/v1",
|
|
43
|
-
"api": "openai-completions",
|
|
44
|
-
"apiKey": "$ORCA_KEY",
|
|
45
|
-
"models": [
|
|
46
|
-
{
|
|
47
|
-
"id": "orcarouter/auto",
|
|
48
|
-
"name": "OrcaRouter Auto",
|
|
49
|
-
"reasoning": false,
|
|
50
|
-
"input": ["text"],
|
|
51
|
-
"contextWindow": 200000,
|
|
52
|
-
"maxTokens": 8192
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
3. **Pick the model** when you run a review:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
pi-review --model orcarouter/orcarouter/auto -- @src/foo.ts
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
[](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
|
|
67
|
-
|
|
68
|
-
## Features
|
|
13
|
+
[Quick start](#quick-start) · [Features](#why-pi-review) · [Screening workflow](docs/guide/screening.md) · [Panel review](docs/guide/panel-review.md) · [CLI reference](docs/guide/cli-reference.md) · [中文说明](README.zh-CN.md)
|
|
69
14
|
|
|
70
|
-
|
|
71
|
-
- **Multiple review modes** — code review, multi-lens plan review, adversarial challenge review
|
|
72
|
-
- **Structured output** — explicit `status`, structured findings (with optional per-finding `details`/`recommendation`/`location`), and a human-readable ASCII footer; one versioned, one-line `PI_REVIEW_META_JSON` on stderr for automation
|
|
73
|
-
- **Loop review gate** — bounded, isolated review rounds with `pi-review loop --max-rounds <n>`; the host remains the only editor
|
|
74
|
-
- **Model-agnostic** — use any model available in your Pi installation
|
|
75
|
-
- **Live streaming** — child review output is forwarded as it arrives (use `--no-stream` to buffer)
|
|
76
|
-
- **Progress logging for AI hosts** — `--progress-log <path>` writes a live, compact JSON event log so agent hosts that buffer tool stdout (Claude Code, Codex, ...) can still show real-time progress (`--progress-log-raw` keeps the verbatim stream)
|
|
77
|
-
- **Session continuity** — keep sessions alive for follow-up questions with `--keep-session`
|
|
78
|
-
- **Customizable presets** — extend or override review modes via JSON configuration
|
|
79
|
-
- **Pi package integration** — `/rv` slash command and agent skill included
|
|
15
|
+
</div>
|
|
80
16
|
|
|
81
|
-
|
|
17
|
+
---
|
|
82
18
|
|
|
83
|
-
-
|
|
84
|
-
- **Documentation** may be bilingual. See [README.zh-CN.md](./README.zh-CN.md) for 中文说明.
|
|
85
|
-
- **Git commits**: [Husky](https://typicode.github.io/husky/) runs `ai-commit` on `prepare-commit-msg` / `commit-msg` / `pre-commit` (see [`.husky/`](./.husky/)). Config: [`.ai-commit.yaml`](./.ai-commit.yaml) (English, `ai_footer: off`, **ai-commit v0.1.45+** on PATH). Or run `ai-commit commit` / `ai-commit generate` directly after `git add`.
|
|
86
|
-
|
|
87
|
-
## Installation
|
|
88
|
-
|
|
89
|
-
Dev dependencies use the [public npm registry](https://registry.npmjs.org/) (see [`.npmrc`](./.npmrc)); run `npm install` in the repo root for Husky hooks.
|
|
90
|
-
|
|
91
|
-
### CLI (recommended)
|
|
19
|
+
`pi-review` hands review work to a fresh, **read-only** [Pi](https://pi.dev) session and returns a structured verdict: findings with severity, evidence, location and a stable exit code. Run one reviewer, or a **panel of independent reviewers** that must agree before a finding blocks the gate. Your agent (Claude Code, Codex, Cursor, Pi) stays the only editor.
|
|
92
20
|
|
|
93
21
|
```bash
|
|
94
22
|
npm install -g @zephyrdeng/pi-review
|
|
23
|
+
pi-review -- @src/foo.ts # one reviewer
|
|
24
|
+
pi-review --panel code-experts --consensus majority -- @src # three lenses, one gate
|
|
95
25
|
```
|
|
96
26
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
npx @zephyrdeng/pi-review install
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Runs `pi install npm:@zephyrdeng/pi-review` when the Pi CLI is on PATH, then installs the agent skill for Claude Code, Codex, Cursor, and agy / Antigravity (via the [skills CLI](https://www.npmjs.com/package/skills), non-interactive `-y`). Forward extra flags to the skill step, e.g. `npx @zephyrdeng/pi-review install --agent claude-code codex agy -y` or `npx @zephyrdeng/pi-review install --agents-only --all`.
|
|
104
|
-
|
|
105
|
-
Use `--pi-only` or `--agents-only` to run one side. For Pi-only use, **do not** also run `install-skill` — the npm Pi package already exposes the skill via `pi.skills`.
|
|
106
|
-
|
|
107
|
-
### Pi package only
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
pi install npm:@zephyrdeng/pi-review
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Agent skill only (Claude Code, Codex, Cursor, agy, ...)
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="docs/assets/panel-live-pi.jpg" alt="Pi Review Panel: correctness, security and testing reviewers running live with model, tokens and cost" width="820">
|
|
29
|
+
</p>
|
|
114
30
|
|
|
115
|
-
|
|
116
|
-
npx @zephyrdeng/pi-review install-skill
|
|
117
|
-
```
|
|
31
|
+
## Why pi-review
|
|
118
32
|
|
|
119
|
-
|
|
33
|
+
| | |
|
|
34
|
+
|---|---|
|
|
35
|
+
| **Isolated, read-only reviewers** | Every review is a fresh child process with a hard `read,grep,find,ls` allowlist. It cannot edit, commit, or leak context from your main session. |
|
|
36
|
+
| **Panel consensus, not one opinion** | 2–8 independent reviewers who never see each other. A finding blocks only when enough of them agree (`any` / `quorum` / `majority` / `unanimous`); singletons stay visible as advisories. |
|
|
37
|
+
| **Mix models per reviewer** | `--reviewer-model r1=openai/gpt-5.6:high --reviewer-model r2=anthropic/claude-opus-4.8:xhigh` — cross-family panels catch what one vendor misses. |
|
|
38
|
+
| **Machine-readable, host-agnostic** | One versioned `PI_REVIEW_META_JSON` line, exit codes `0/1/3/4`, and an `events-jsonl` stream. Drop into CI, hooks, or your own renderer. |
|
|
39
|
+
| **Loop gate for agent closeout** | `pi-review loop --until clean` re-reviews after each fix round, diffs findings across rounds, and stops on convergence — never unbounded. |
|
|
40
|
+
| **~1s screening** | `pi-review screen` skips LLM generation entirely: deterministic slicing + typed [Jev](https://typesafe.ai) judgments against a defect catalog. Measured **1.2s** vs 30–50s for a full round. The catalog grows from use — custom patterns + a signal log via `pi-review screen-memory`. |
|
|
41
|
+
| **Live everywhere** | Native live rows in Pi, a loopback **web dashboard** for Claude Code / Codex, streamed milestones on stderr for plain terminals. |
|
|
42
|
+
| **Three review modes** | `code` (correctness, security, tests), `plan` (six expert lenses), `challenge` (adversarial pressure test). Extend via JSON presets. |
|
|
120
43
|
|
|
121
|
-
|
|
44
|
+
## See it work
|
|
122
45
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
46
|
+
<table>
|
|
47
|
+
<tr>
|
|
48
|
+
<td width="50%"><img src="docs/assets/panel-cli-footer.jpg" alt="CLI panel footer with gate status, consensus, confirmed findings, advisories and per-reviewer lines"></td>
|
|
49
|
+
<td width="50%"><img src="docs/assets/panel-web-dashboard.jpg" alt="Web dashboard with live per-reviewer cards, token and tool counters"></td>
|
|
50
|
+
</tr>
|
|
51
|
+
<tr>
|
|
52
|
+
<td align="center"><sub>Panel footer in any terminal — gate, consensus, cost, per-reviewer status</sub></td>
|
|
53
|
+
<td align="center"><sub><code>--ui web</code> dashboard for hosts that buffer stdout</sub></td>
|
|
54
|
+
</tr>
|
|
55
|
+
</table>
|
|
128
56
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
pi-review uninstall-skill
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Update package + skill
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
pi-review update
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Updates the global npm package when a newer version is available, then refreshes the installed agent skill content (via `skills update pi-review`, with a reinstall / Claude + agy direct-copy fallback).
|
|
142
|
-
|
|
143
|
-
### From source
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
git clone https://github.com/ZephyrDeng/pi-review.git
|
|
147
|
-
cd pi-review
|
|
148
|
-
npm install && npm run build
|
|
149
|
-
npm link
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Quick Start
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
# Review a file
|
|
156
|
-
pi-review -- @src/foo.ts
|
|
157
|
-
|
|
158
|
-
# Review with a specific model
|
|
159
|
-
pi-review --model openai/gpt-5.5 -- @src/foo.ts
|
|
160
|
-
|
|
161
|
-
# Multi-lens plan review
|
|
162
|
-
pi-review --mode plan -- @docs/architecture.md
|
|
163
|
-
|
|
164
|
-
# Adversarial challenge review
|
|
165
|
-
pi-review --mode challenge -- @docs/design.md
|
|
166
|
-
|
|
167
|
-
# Bounded review-only gate (default: 3 rounds)
|
|
168
|
-
pi-review loop --max-rounds 3 -- @src
|
|
169
|
-
|
|
170
|
-
# List available models
|
|
171
|
-
pi-review models
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
From an agent host (Claude Code, Codex, Cursor, or **agy / Antigravity**), install the skill once, then ask the host to run a review — e.g. `/pi-review -- @src/foo.ts` or natural language that triggers the skill:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
npx @zephyrdeng/pi-review install-skill --agent agy
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Review Modes
|
|
181
|
-
|
|
182
|
-
| Mode | Description |
|
|
183
|
-
|------|-------------|
|
|
184
|
-
| `code` (default) | Code, diff, MR, file, and repository review. Focuses on correctness, regressions, security, concurrency, API contracts, edge cases, and missing tests. |
|
|
185
|
-
| `plan` | Broad plan/architecture review through multiple expert lenses: engineering, product, security, QA, operations, and DX. |
|
|
186
|
-
| `challenge` | Adversarial review that pressure-tests assumptions, dependencies, reversibility, failure modes, and migration paths. |
|
|
187
|
-
|
|
188
|
-
## Loop Review
|
|
189
|
-
|
|
190
|
-
`pi-review loop` runs a bounded sequence of full, isolated review runs against the current working tree:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
pi-review loop --max-rounds 3 -- @src
|
|
194
|
-
pi-review loop --until clean --max-rounds 10 -- @src
|
|
195
|
-
pi-review loop --mode challenge --max-rounds 2 -- @docs/design.md
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Each round is review-only. The process never edits, patches, waits for filesystem changes, or asks the child session to fix findings. It stops immediately on `clean`, `needs_human`, or `blocked`; otherwise it stops when the round budget is exhausted. Every round emits one `PI_REVIEW_META_JSON` line in order, and the final human summary lists each round's status, verdict, duration, and finding counts.
|
|
199
|
-
|
|
200
|
-
Each round's `PI_REVIEW_META_JSON` line is the same enriched schema documented under [Machine finding schema](#machine-finding-schema) — `metaVersion`, per-finding `details`/`recommendation`/`location`, and (for panel rounds) `sourceFindings`. A consumer that wants enriched findings for a given round reads that round's stderr line directly, in emission order; no Markdown scraping and no change to `LoopRoundSummary` are needed.
|
|
201
|
-
|
|
202
|
-
This is a **host-driven gate**: if findings remain, the host or human fixes only accepted in-scope findings and invokes `loop` again. For patch-by-patch agent closeout, `--max-rounds 1` gives the host a fix point after each review. For an explicit clean goal with a hard ceiling, use `--until clean` (default budget 10 when `--max-rounds` is omitted; never unlimited). Clean means no gate-blocking findings (single: no actionable findings; panel: no confirmed actionable clusters; advisories may remain). `loop` accepts normal review target/model/progress options but rejects `--keep-session`, `--continue`, and `--name` in v1.
|
|
203
|
-
|
|
204
|
-
**Cross-round comparison.** From round 2 onward each round is diffed against the previous round's actionable findings (`vs prev: =persisting · +new · -resolved` in the loop summary). Matching is deterministic first; with the Jev enhancement enabled, wording-drift pairs are adjudicated by Jev just like panel consensus. The comparison is advisory bookkeeping, never gate input, and a matcher failure degrades silently to no comparison. Under `--until clean`, when two consecutive rounds produce an identical actionable set (all persisting, nothing added or resolved), the loop stops early with `Stop: non_converging` — the tree does not change between rounds, so further rounds are dice rolls and the host should fix and re-invoke.
|
|
205
|
-
|
|
206
|
-
## Panel Review
|
|
207
|
-
|
|
208
|
-
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.
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
# Single panel review
|
|
212
|
-
pi-review --reviewers 3 --consensus quorum --min-agree 2 -- @src
|
|
213
|
-
# Expert preset (correctness, security, testing lenses)
|
|
214
|
-
pi-review --panel code-experts --consensus majority -- @src
|
|
215
|
-
# Panel loop review (up to reviewer_count × max-rounds reviewer runs + adjudication)
|
|
216
|
-
pi-review loop --reviewers 3 --consensus quorum --max-rounds 2 -- @src
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Consensus
|
|
220
|
-
|
|
221
|
-
A finding becomes a **confirmed finding** (gate-relevant) only when enough independent reviewers mark the issue **actionable**. Otherwise it stays a non-blocking **advisory**. 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.
|
|
222
|
-
|
|
223
|
-
| Policy | Threshold |
|
|
224
|
-
|--------|----------|
|
|
225
|
-
| `any` | one actionable reviewer confirms |
|
|
226
|
-
| `quorum` (default) | configured minimum agreement (default 2; `--min-agree`) |
|
|
227
|
-
| `majority` | `floor(reviewers / 2) + 1` |
|
|
228
|
-
| `unanimous` | every reviewer |
|
|
229
|
-
|
|
230
|
-
Singleton (uncorroborated) findings remain visible as **advisories** but do not change clean status or fail the gate. Confirmed actionable clusters produce `has_findings`; no confirmed clusters produce `clean`.
|
|
231
|
-
|
|
232
|
-
### Aggregation
|
|
233
|
-
|
|
234
|
-
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.
|
|
235
|
-
|
|
236
|
-
**Adjudication engine (Jev enhancement mode).** When `TYPESAFE_API_KEY` is present (or `{ "jev": true }` is set in the config file), the adjudication decision is routed to [TypeSafe Jev](https://typesafe.ai) — a System One model that returns typed probabilities — instead of spawning a review-only Pi child. Each ambiguous finding pair becomes one Noul question ("same underlying issue?"), fanned out in a single call; the pair probability is used as the merge confidence and flows through the same threshold and provenance validation as LLM merges. This replaces a full child session with one ~100 ms typed call.
|
|
237
|
-
|
|
238
|
-
- **Complete-Linkage Clustering**: Built-in complete-linkage algorithm ensures 100% clustering precision, eliminating false-merge chains across findings in the same function.
|
|
239
|
-
- **Cross-Round Loop Memory**: In multi-round reviews (`loop`), Jev maintains true state continuity across natural reviewer phrasing drift. On the standard fixture, Jev ON achieved **`=7 persisting · +0 new · -0 resolved`** (Gemini 3.8 Flash) and `=8~9 persisting` (mixed Flash fleet), whereas deterministic string matching resulted in complete amnesia (`=0 persisting · +6~11 new · -6~11 resolved`).
|
|
240
|
-
- **Quota Efficiency**: Adjudication runs on a dedicated lightweight System One pathway without consuming reviewer LLM token quota or context windows.
|
|
241
|
-
- **Cascade**: Pairs whose probability lands in the borderline band (0.3–0.7) are re-judged once by the Pi adjudicator in a single extra call — clear cases never pay for an LLM, uncertain ones get a second opinion, and a Pi failure safely keeps Jev's judgments. Explicit `--consensus-model` keeps the Pi adjudicator for everything; `PI_REVIEW_JEV=0` disables Jev for one run; any Jev failure falls back to the Pi adjudicator. See the [visual comparison report](docs/research/jev-comparison-report.html) and [adjudication case study](docs/research/jev-adjudication-case.md).
|
|
242
|
-
|
|
243
|
-
**Scope classification (`pi-review classify`).** The same Jev backend can classify a previous review's actionable findings against your frozen task baseline — the loop-closeout scope governor as a typed decision instead of a judgment call:
|
|
244
|
-
|
|
245
|
-
```bash
|
|
246
|
-
pi-review classify --baseline "fix the login crash; UI polish is out of scope" --meta /tmp/last-review-meta.txt
|
|
247
|
-
# or pipe the review output directly:
|
|
248
|
-
pi-review -- @src 2>&1 | pi-review classify --baseline "..."
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Each actionable finding gets one Choice question (`in_scope_blocker` | `follow_up` | `stop_and_escalate`), all fanned out in a single call. Output is an ASCII summary plus a `PI_REVIEW_CLASSIFY_JSON` machine line on stderr; findings below confidence 0.5 are flagged as low-confidence. Classify is advisory and host-invoked — it never edits, never blocks a gate by itself, and requires `TYPESAFE_API_KEY` (exit 4 without it).
|
|
252
|
-
|
|
253
|
-
**Gate-grade screening (`pi-review screen`).** Screen pushes Jev furthest left in the pipeline: instead of generating findings with an LLM reviewer (30s+ per round) and adjudicating them afterwards, it asks Jev typed questions about deterministically sliced code hunks and assembles findings from a defect-pattern catalog — no LLM prose on the critical path at all. Measured end-to-end on the [screening fixture](docs/research/jev-screening-case.md): **~1.2s wall time** for a 106-line service (12 hunks, 108 questions, one call), vs 32–53s for a full review round on the same file.
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
pi-review screen src/order-service.ts # or @file refs; exits 1 on findings, 0 when clean
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
The architecture, end to end:
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
files ─► 1. deterministic slice (local, ms — declaration-boundary hunks)
|
|
263
|
-
│
|
|
264
|
-
├─► 2. one Jev call (~1s — per hunk: 1 catch-all Noul
|
|
265
|
-
│ "any blocking defect?" + 1 Noul per catalog pattern;
|
|
266
|
-
│ fanned out in parallel, chunked past 480 questions)
|
|
267
|
-
│
|
|
268
|
-
└─► 3. template assembly (local, ms — pattern hit ⇒ finding
|
|
269
|
-
+ gate from catalog severity/title/fix;
|
|
270
|
-
catch-all hit without a pattern ⇒
|
|
271
|
-
"unmatched signal" finding, still
|
|
272
|
-
blocks — never silently dropped)
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
Who produces each `ReviewFinding` field: `id`/`path`/`location` come from the slicer (deterministic), `severity`/`summary`/`recommendation` come from the matched catalog pattern's template, `actionable` is the thresholded probability — the LLM's prose role shrinks to off-catalog novel defects and cross-hunk reasoning, which the unmatched-signal finding hands back to a full `pi-review` run. The catalog (`SCREEN_PATTERNS` in `src/screen.ts`) is the coverage knob: eight patterns ship today (off-by-one loops, fire-and-forget async, SQL injection, slice off-by-one, float money, float equality, cache aliasing, missing validation); add entries as history shows repeated unmatched signals. Output is an ASCII summary plus a `PI_REVIEW_SCREEN_JSON` machine line on stderr (status, findings, per-hunk probabilities, usage); exit codes mirror review (0 clean, 1 has_findings, 4 blocked/no key). Screen is a fast gate and a triage layer, not a replacement for evidence-backed review — measurements and honest limits are in [docs/research/jev-screening-case.md](docs/research/jev-screening-case.md).
|
|
276
|
-
|
|
277
|
-
### Cost and failure
|
|
278
|
-
|
|
279
|
-
Reviewer runs = `--reviewers <n>` × `--max-rounds` (loop); one adjudication call may run per round when `--consensus-model` is set. Use `--concurrency <n>` to bound provider/machine pressure (default: reviewer count, never exceeds it). Reviewer runtime failure → `blocked`; unstructured dirty output or unresolved clarification → `needs_human`; never silently clean. Panel review rejects `--keep-session`, `--continue`, and `--name` (reviewers run `--no-session`); the host agent remains the only editor.
|
|
280
|
-
|
|
281
|
-
When the panel finishes, the CLI appends a panel ASCII footer on **stdout** with gate status, health, consensus, confirmed/advisory counts, mixed model/thinking when reviewers differ, aggregate tokens/cost, adjudicator use, and a per-reviewer line:
|
|
282
|
-
|
|
283
|
-

|
|
284
|
-
|
|
285
|
-
### Machine output
|
|
286
|
-
|
|
287
|
-
A panel evaluation emits **one** aggregate `PI_REVIEW_META_JSON` record with additive fields: `strategy: "panel"`, `configuredReviewers`, `successfulReviewers`, `consensusPolicy`, `consensusThreshold`, `panelHealth`, `confirmedClusters`, `advisories`, and per-`reviewers` outcomes. Top-level `findings` contain confirmed clusters only; advisories remain separate. Existing single-review keys remain unchanged, so older consumers can ignore the new fields. The panel-level `model` is each reviewer's effective model (configured, else the provider-reported `responseModel`) when they all agree, and the literal sentinel `"mixed"` when reviewers ran on different models — machine consumers parsing `model` must expect that value; per-reviewer entries keep their own `model`/`responseModel`.
|
|
288
|
-
|
|
289
|
-
Panel machine metadata additionally carries `sourceFindings`: every contributing reviewer's raw findings, each tagged with its globally unique `id` (e.g. `"r1#F1"`) and `reviewerId`. This resolves every id referenced by `confirmedClusters[].sourceFindingIds` and `advisories[].sourceFindingIds` to its full enriched finding — including `details`/`recommendation`/`location` when the reviewer's Markdown supplied them (see [Machine finding schema](#machine-finding-schema)). Cluster-level summaries stay as they are today: `summary`/`severity`/`path` only, no enrichment fields.
|
|
290
|
-
|
|
291
|
-
### Live Pi progress and event replay
|
|
292
|
-
|
|
293
|
-
In Pi, slash commands select strategy only:
|
|
294
|
-
|
|
295
|
-
- `/rv <natural-language target>` → panel review via native `pi_review`
|
|
296
|
-
- `/rv-loop <natural-language target>` → loop closeout via shell CLI
|
|
297
|
-
- `/rv-models` → model catalog
|
|
298
|
-
|
|
299
|
-
Targets stay natural language as given. Path mentions like `@src` remain text; the CLI keeps directories as tool path targets and only attaches real files. Remaining strategy matching lives in the skill/CLI. In Pi, the user-facing tool name is **Pi Review Panel** (the API identifier remains `pi_review`); each reviewer renders as an independent live row with explicit `queued/running/completed/failed/cancelled` state, active tool, elapsed time, and token usage. Expand the tool result with `Ctrl+O` for bounded activity, final findings/provenance, duration, token totals, and cost.
|
|
300
|
-
|
|
301
|
-

|
|
302
|
-
|
|
303
|
-
Example: `pi-review --panel code-experts -- @src` (or `/rv` in Pi with the same panel strategy).
|
|
304
|
-
|
|
305
|
-
Renderer adapters can consume the stable, versioned event stream directly:
|
|
306
|
-
|
|
307
|
-
```bash
|
|
308
|
-
pi-review --panel code-experts --output-format events-jsonl -- @src
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
This mode writes only `ReviewEvent v1` JSONL to stdout. Events have one `runId`, monotonically increasing `seq`, bounded/redacted activity text, and end in exactly one `panel.completed` event containing the same `PanelReviewMeta` as the default CLI path. The reducer is exported as `createPanelViewState()` and `reducePanelEvent()` for deterministic live delivery and replay.
|
|
312
|
-
|
|
313
|
-
Panel reviewers use the hard allowlist `read,grep,find,ls`. Shell and mutation-capable tools are rejected before a reviewer starts. `Ctrl+C` cancels the reviewer and adjudicator process trees, emits cancellation lifecycle events, and produces one blocked final event.
|
|
314
|
-
|
|
315
|
-
### Live web dashboard
|
|
316
|
-
|
|
317
|
-
`--ui web` starts an opt-in, loopback-only dashboard for hosts without a native Pi renderer (Claude Code, Codex, plain terminals):
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
pi-review --reviewers 3 --consensus quorum --ui web -- @src
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-

|
|
324
|
-
|
|
325
|
-
The CLI prints `PI_REVIEW_UI_URL: http://127.0.0.1:<port>/run/<token>` to stderr and opens it in the default browser before reviewers start (`--no-ui-open` disables the auto-open). The dashboard shows live per-reviewer status, streaming activity, animated token/tool-call counters, and — once the run completes — the gate result, confirmed findings/advisories, and each reviewer's full report rendered from markdown. `--ui-url-file <path>` additionally writes the URL atomically for hosts that buffer stdout/stderr. The review process still exits with the normal panel exit code as soon as the run completes.
|
|
326
|
-
|
|
327
|
-
After completion the page shows a 60-second countdown, then closes itself and stops the dashboard server; any interaction (scroll, click, keypress, or the "Keep open" button) cancels the countdown, and closing the tab afterwards also stops the server. As a backstop, the server self-terminates after a bounded idle TTL (default 900s; override with `--ui-ttl <seconds>`) so a browser can reconnect after a refresh.
|
|
328
|
-
|
|
329
|
-
The dashboard binds only to `127.0.0.1`/`::1`, protects every run with a high-entropy capability URL, sends a restrictive CSP with no remote assets or CORS, and renders all reviewer/finding text through safe DOM writes (markdown is parsed by a built-in renderer; links are restricted to http/https, and nothing goes through innerHTML). It is view-only: cancellation stays with the invoking terminal/agent host (`Ctrl+C`). `--ui web` requires an active panel and cannot combine with `loop`.
|
|
330
|
-
|
|
331
|
-
## Output Format
|
|
332
|
-
|
|
333
|
-
Every review produces Markdown with these sections:
|
|
334
|
-
|
|
335
|
-
```
|
|
336
|
-
## Verdict
|
|
337
|
-
approve | request_changes | needs_clarification | blocked
|
|
338
|
-
|
|
339
|
-
## Summary
|
|
340
|
-
## Findings
|
|
341
|
-
### F1: <summary>
|
|
342
|
-
- Severity: critical | high | medium | low
|
|
343
|
-
- Path: <path or none>
|
|
344
|
-
- Lines: <line or line-range in Path, or none>
|
|
345
|
-
- Side: base | working (optional; defaults to working)
|
|
346
|
-
- Actionable: yes | no
|
|
347
|
-
- Evidence: <concrete evidence>
|
|
348
|
-
- Impact: <why it matters>
|
|
349
|
-
- Recommendation: <specific next step>
|
|
350
|
-
|
|
351
|
-
## Risks and Blind Spots
|
|
352
|
-
## Open Questions
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
The CLI appends a readable ASCII footer on **stdout**:
|
|
57
|
+
Every review ends with a structured report and a footer you can read at a glance:
|
|
356
58
|
|
|
357
59
|
```
|
|
358
60
|
── pi-review ────────────────────────────
|
|
@@ -361,198 +63,108 @@ The CLI appends a readable ASCII footer on **stdout**:
|
|
|
361
63
|
Mode code
|
|
362
64
|
Findings 1 actionable / 1 total
|
|
363
65
|
Model provider/model
|
|
364
|
-
|
|
365
|
-
Tokens in 17.6K · out 512 · cache 2.0K · reason 0 · total 18.2K
|
|
66
|
+
Tokens in 17.6K · out 512 · cache 2.0K · total 18.2K
|
|
366
67
|
Cost $0.05
|
|
367
68
|
Duration 42.3s
|
|
368
69
|
──────────────────────────────────────────
|
|
369
70
|
```
|
|
370
71
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
For scripts, parse **`PI_REVIEW_META_JSON:`** from **stderr**. Existing keys remain, with additive fields:
|
|
374
|
-
|
|
375
|
-
```json
|
|
376
|
-
{"metaVersion":1,"reviewMode":"code","verdict":"request_changes","verdictSource":"parsed","status":"has_findings","findings":[{"id":"F1","severity":"high","path":"src/cli.ts","summary":"Dirty reviews exit zero","actionable":true}],"actionableCount":1,"durationMs":42300,"model":"provider/model","thinking":"xhigh","usage":{"input":18031,"output":512,"cacheRead":2048,"cacheWrite":0,"reasoning":0,"totalTokens":18591,"costTotal":0.05}}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
`status` is one of `clean`, `has_findings`, `needs_human`, or `blocked`: `approve` with no actionable findings is `clean`; `request_changes` or actionable findings are `has_findings`; `needs_clarification` is `needs_human`; runtime/fatal failures are `blocked`. Each finding always has `summary` and `actionable`; `id`, `severity`, and `path` are present when parsed. `thinking` and `usage` are additive and present when reported by the child; `usage` includes token totals and may include `costTotal`. The line remains a single additive JSON record, so older consumers can ignore unknown keys. Set `PI_REVIEW_META_STDOUT=1` to emit it on stdout instead.
|
|
380
|
-
|
|
381
|
-
### Machine finding schema
|
|
382
|
-
|
|
383
|
-
`PI_REVIEW_META_JSON` carries a top-level `metaVersion` schema discriminator (currently `1`). JSON emitted by pi-review versions before this field existed has no `metaVersion` key at all — treat that absence as the original, pre-enrichment contract. Every field below is additive under `metaVersion: 1`; a future breaking change to this shape would bump it.
|
|
72
|
+
Scripts read `PI_REVIEW_META_JSON:` from stderr — findings carry `severity`, `path`, `location`, `details`, `recommendation`. No Markdown scraping. → [Output & integration](docs/guide/output-and-integration.md)
|
|
384
73
|
|
|
385
|
-
|
|
74
|
+
## Quick start
|
|
386
75
|
|
|
387
|
-
|
|
388
|
-
|-------|------|--------------|
|
|
389
|
-
| `details` | `string` | At least one of the reviewer's Evidence/Impact fields parsed. Joins them as `"Evidence: <...>"` and/or `"Impact: <...>"` paragraphs separated by a blank line (`\n\n`); a finding with only one of the two carries only that labeled paragraph. Never fabricated. |
|
|
390
|
-
| `recommendation` | `string` | The reviewer's Recommendation field parsed, verbatim and kept separate from `details`. |
|
|
391
|
-
| `location` | `{ startLine: number; endLine?: number; side?: "base" \| "working" }` | The reviewer's `Lines` field held one positive integer (`42`) or a non-inverted positive range (`42-58`). Non-numeric, zero/negative, or inverted (`endLine < startLine`) values are dropped rather than guessed, so `location` is simply absent. `side` is only ever `"base"` (before the change); every other case — absent, unrecognized, or explicitly `"working"` — omits `side`, which means `"working"` (after the change). |
|
|
76
|
+
**Prerequisite:** [Pi CLI](https://pi.dev) with at least one model provider configured.
|
|
392
77
|
|
|
393
|
-
|
|
78
|
+
```bash
|
|
79
|
+
# CLI
|
|
80
|
+
npm install -g @zephyrdeng/pi-review
|
|
394
81
|
|
|
395
|
-
|
|
396
|
-
|
|
82
|
+
# …or one shot: Pi package + skill for Claude Code / Codex / Cursor / Antigravity
|
|
83
|
+
npx @zephyrdeng/pi-review install
|
|
397
84
|
```
|
|
398
85
|
|
|
399
|
-
|
|
86
|
+
```bash
|
|
87
|
+
pi-review -- @src/foo.ts # single review
|
|
88
|
+
pi-review --mode plan -- @docs/architecture.md # multi-lens plan review
|
|
89
|
+
pi-review --reviewers 3 --consensus quorum -- @src # panel
|
|
90
|
+
pi-review loop --until clean --max-rounds 5 -- @src # bounded fix/re-review gate
|
|
91
|
+
pi-review screen src/order-service.ts # ~1s catalog screening
|
|
92
|
+
pi-review models # what can I run on?
|
|
93
|
+
```
|
|
400
94
|
|
|
401
|
-
|
|
95
|
+
In Pi: `/rv @src`, `/rv-loop fix until clean @src`, `/rv-models`. In other agent hosts, install the skill once and ask for a review in plain language.
|
|
402
96
|
|
|
403
|
-
|
|
97
|
+
→ [Installation options](docs/guide/installation.md) · [Pi `/rv` commands](docs/guide/pi-package.md)
|
|
404
98
|
|
|
405
|
-
|
|
406
|
-
|------|---------|
|
|
407
|
-
| `0` | Final status is `clean` |
|
|
408
|
-
| `1` | Final status is `has_findings` / loop budget exhausted |
|
|
409
|
-
| `2` | CLI usage or argument error |
|
|
410
|
-
| `3` | `needs_human` — clarification or a decision is required |
|
|
411
|
-
| `4` | `blocked` — child/runtime failure or review cannot proceed |
|
|
99
|
+
## How the panel decides
|
|
412
100
|
|
|
413
|
-
|
|
101
|
+
```
|
|
102
|
+
reviewers (isolated, read-only) ──► findings ──► deterministic match (path + summary)
|
|
103
|
+
│
|
|
104
|
+
ambiguous pairs ┴─► Jev typed adjudication (~100 ms)
|
|
105
|
+
│ borderline 0.3–0.7 → one Pi re-judge
|
|
106
|
+
▼
|
|
107
|
+
consensus threshold ──► confirmed (blocks) / advisory
|
|
108
|
+
```
|
|
414
109
|
|
|
415
|
-
|
|
416
|
-
# Keep a review session for follow-up
|
|
417
|
-
pi-review --mode challenge --keep-session -- @docs/design.md
|
|
110
|
+
Reviewer failure → `blocked`; unparseable output → `needs_human`; never a silent pass. Adjudication cannot invent, drop, or rewrite findings — it only clusters. → [Panel review in depth](docs/guide/panel-review.md) · [Loop review](docs/guide/loop-review.md)
|
|
418
111
|
|
|
419
|
-
|
|
420
|
-
pi-review --continue <sessionHandle> --mode challenge --model provider/model -- "expand finding 2"
|
|
421
|
-
```
|
|
112
|
+
## Partners
|
|
422
113
|
|
|
423
|
-
|
|
114
|
+
<table>
|
|
115
|
+
<tr>
|
|
116
|
+
<td width="50%" valign="top">
|
|
424
117
|
|
|
425
|
-
|
|
118
|
+
### [OrcaRouter](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
|
|
426
119
|
|
|
427
|
-
|
|
120
|
+
One key, every frontier model. `pi-review` ships a ready-made provider file — drop it into Pi and run cross-family panels without juggling vendor accounts.
|
|
428
121
|
|
|
429
|
-
|
|
122
|
+
[](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
|
|
430
123
|
|
|
431
|
-
|
|
432
|
-
# Optional: capture the event log for debugging (slimmed by default; add --progress-log-raw for verbatim)
|
|
433
|
-
pi-review --progress-log /tmp/pi-review.jsonl -- @src/foo.ts &
|
|
434
|
-
tail -f -n +1 /tmp/pi-review.jsonl | jq -c --unbuffered '
|
|
435
|
-
select(.type != "message_update" and .type != "tool_execution_update")
|
|
436
|
-
'
|
|
437
|
-
```
|
|
124
|
+
→ [Setup guide](docs/guide/providers.md)
|
|
438
125
|
|
|
439
|
-
|
|
126
|
+
</td>
|
|
127
|
+
<td width="50%" valign="top">
|
|
440
128
|
|
|
441
|
-
|
|
129
|
+
### [TypeSafe Jev](https://typesafe.ai)
|
|
442
130
|
|
|
443
|
-
|
|
444
|
-
pi-review [review] [options] -- <@files|text...>
|
|
445
|
-
pi-review loop [options] -- <@files|text...>
|
|
446
|
-
pi-review screen <@files|paths...>
|
|
447
|
-
pi-review classify --baseline <text|@file> [--meta <path>]
|
|
448
|
-
pi-review models [search]
|
|
449
|
-
```
|
|
131
|
+
A System One model that answers typed questions with probabilities in ~100 ms. Powers consensus adjudication, cross-round finding memory, scope `classify`, and the 1-second `screen` gate.
|
|
450
132
|
|
|
451
|
-
|
|
452
|
-
|--------|-------------|
|
|
453
|
-
| `--mode <name>` | Review mode (default: `code`) |
|
|
454
|
-
| `--model <provider/model[:thinking]>` | Model to use for the review |
|
|
455
|
-
| `--provider <name>` | Model provider |
|
|
456
|
-
| `--thinking <level>` | Thinking level: `off\|minimal\|low\|medium\|high\|xhigh` |
|
|
457
|
-
| `--skill <path>` | Load an extra Pi skill (repeatable) |
|
|
458
|
-
| `--tools <csv>` | Override allowed tools |
|
|
459
|
-
| `--keep-session` | Persist session for follow-up |
|
|
460
|
-
| `--continue <handle>` | Continue an existing session |
|
|
461
|
-
| `--name <name>` | Session name (with `--keep-session`) |
|
|
462
|
-
| `--no-stream` | Buffer child output until exit (default: stream live) |
|
|
463
|
-
| `--progress-log <path>` | Stream compact child `--mode json` events to this file (cannot combine with `--no-stream`) |
|
|
464
|
-
| `--progress-log-raw` | With `--progress-log`: tee the verbatim event stream (full message snapshots; much larger files) |
|
|
465
|
-
| `--max-rounds <n>` | Positive loop hard budget (default: `3`; with `--until clean` default: `10`; `loop` only) |
|
|
466
|
-
| `--until clean` | Loop goal: keep going until the clean gate (still hard-capped by `--max-rounds`; never unlimited) |
|
|
467
|
-
| `--reviewers <n>` | Panel: number of independent reviewers (2-8; activates panel mode) |
|
|
468
|
-
| `--panel <name>` | Panel: named expert-panel preset (cannot combine with `--reviewers`) |
|
|
469
|
-
| `--consensus <policy>` | Panel: `any \| quorum \| majority \| unanimous` (default: `quorum`) |
|
|
470
|
-
| `--min-agree <n>` | Panel: minimum reviewers for quorum (default: `2`; quorum only) |
|
|
471
|
-
| `--consensus-model <model>` | Panel: model for semantic consensus adjudication |
|
|
472
|
-
| `--concurrency <n>` | Panel: bounded reviewer concurrency (default: reviewer count) |
|
|
473
|
-
| `--output-format events-jsonl` | Panel: normalized `ReviewEvent v1` JSONL for renderer adapters |
|
|
474
|
-
|
|
475
|
-
### When to use each command & argument
|
|
476
|
-
|
|
477
|
-
- **`pi-review screen <paths>`** — Sub-second (~1.0–1.2s) gate screening without running an LLM generation loop. Use in CI/CD fast paths, pre-commit/pre-push hooks, or instant sanity checks to catch known defect patterns immediately.
|
|
478
|
-
- **`pi-review review [options] -- <target>`** — Single-reviewer code review. Use for routine local development and self-review where one model's prose recommendations are sufficient.
|
|
479
|
-
- **`pi-review --reviewers <n>` (2–8)** — Multi-reviewer panel review. Use for PR merge gates, security-sensitive changes, or cross-model verification where independent agreement matters.
|
|
480
|
-
- **`pi-review loop [--until clean]`** — Multi-round review loop. Use during automated agentic fix-verify loops to iteratively patch code and re-review until clean.
|
|
481
|
-
- **`--reviewer-model <id=model[:thinking]>`** — In panel mode, assigns specific models or thinking efforts to individual reviewers (e.g. `r1=openai/gpt-5:high`, `r2=zenmux/deepseek/deepseek-v4.1-flash:low`). Essential for cross-family heterogeneous panels.
|
|
482
|
-
- **`--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.
|
|
483
|
-
- **`--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.
|
|
484
|
-
- **`--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.
|
|
485
|
-
- **`--progress-log <path>`** — Streams compact JSON events to a file; essential for background runs in buffered-output hosts like Claude Code, Codex, or Cursor.
|
|
486
|
-
- **`--ui web`** — Starts a loopback browser dashboard for panel runs; recommended for visual inspection on agent hosts.
|
|
487
|
-
|
|
488
|
-
Session flags (`--keep-session`, `--continue`, `--name`) are unsupported by `loop` and panel in v1; invalid combinations print usage and exit `2`.
|
|
489
|
-
|
|
490
|
-
## Configuration
|
|
491
|
-
|
|
492
|
-
Persistent settings live in the review config file `~/.pi/pi-review/config.json` (override its location with `PI_REVIEW_CONFIG`). The config is advisory and forward-compatible: unknown keys are ignored, `null` counts as unset, and any other problem (wrong-typed value, invalid JSON) only prints a warning and falls back — the config never blocks core functionality, so a config written by a newer pi-review cannot brick an older one. In Pi, `/rv-config` shows the effective configuration (values, sources, warnings, resolved paths). There is deliberately no `/rv-config set` command — the preferred editor is your agent via the pi-review agent skill, which knows the config schema, keeps unknown keys, never overwrites invalid JSON, and never writes secrets (API keys stay environment variables, e.g. `TYPESAFE_API_KEY`; the config file holds flags only).
|
|
493
|
-
|
|
494
|
-
| Key | Type | Default | Description |
|
|
495
|
-
|-----|------|---------|-------------|
|
|
496
|
-
| `childExtensions` | boolean | `false` | Let review children load host Pi extensions so providers registered only through extensions are usable. Equivalent to per-run `PI_REVIEW_CHILD_EXTENSIONS=1`; `false` keeps children isolated with `--no-extensions` (issue #8). |
|
|
497
|
-
| `jev` | boolean | auto | Route panel consensus adjudication to TypeSafe Jev instead of a Pi adjudicator child. Default: enabled when `TYPESAFE_API_KEY` is set, disabled otherwise. Per-run override: `PI_REVIEW_JEV=1` / `=0`. An explicit `--consensus-model` always keeps the Pi adjudicator. |
|
|
498
|
-
|
|
499
|
-
Per-process overrides via environment variables (env wins over the config file):
|
|
500
|
-
|
|
501
|
-
| Variable | Description |
|
|
502
|
-
|----------|-------------|
|
|
503
|
-
| `PI_BIN` | Pi executable path (default: `pi`) |
|
|
504
|
-
| `PI_REVIEW_HOME` | Directory containing `review-presets.json` and `system-prompt.md` |
|
|
505
|
-
| `PI_REVIEW_PRESETS` | Path to presets JSON file |
|
|
506
|
-
| `PI_REVIEW_PANEL_PRESETS` | Path to panel presets JSON file |
|
|
507
|
-
| `PI_REVIEW_SYSTEM_PROMPT` | Path to system prompt file |
|
|
508
|
-
| `PI_REVIEW_SESSION_DIR` | Directory for persisted review sessions |
|
|
509
|
-
| `PI_REVIEW_META_STDOUT` | Set to `1`/`true` to print `PI_REVIEW_META_JSON` on stdout instead of stderr |
|
|
510
|
-
| `PI_REVIEW_JEV` | Per-run override for `jev`: `1`/`true`/`on` routes panel consensus adjudication to TypeSafe Jev, any other set value (e.g. `0`) keeps the Pi adjudicator. Connection: `TYPESAFE_API_KEY` (required), optional `TYPESAFE_BASE_URL` and `PI_REVIEW_JEV_MODEL` (default `jev-latest`) |
|
|
511
|
-
| `PI_REVIEW_CHILD_EXTENSIONS` | Per-run override for `childExtensions`: `1`/`true`/`keep` enables host extensions for this process, any other set value (e.g. `0`) forces isolation; an empty value counts as unset. Persistent equivalent: `{ "childExtensions": true }` in the config file. With an explicit `--provider`, pi-review first probes the model catalog and blocks with a hint if the provider only exists via extensions |
|
|
512
|
-
| `PI_REVIEW_CONFIG` | Path to the review config file (default: `~/.pi/pi-review/config.json`) |
|
|
513
|
-
|
|
514
|
-
## Pi Package Usage
|
|
515
|
-
|
|
516
|
-
After installing as a Pi package, use the `/rv` slash command:
|
|
133
|
+
Set `TYPESAFE_API_KEY` and it switches on.
|
|
517
134
|
|
|
518
|
-
|
|
519
|
-
/rv @src/foo.ts
|
|
520
|
-
/rv --mode challenge @docs/design.md
|
|
521
|
-
```
|
|
135
|
+
→ [Comparison report](docs/research/jev-comparison-report.html) · [Screening study](docs/research/jev-screening-case.md)
|
|
522
136
|
|
|
523
|
-
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</table>
|
|
524
140
|
|
|
525
|
-
|
|
526
|
-
/rv models
|
|
527
|
-
/rv @src/foo.ts
|
|
528
|
-
/rv --mode plan @docs/architecture.md
|
|
529
|
-
/rv --mode challenge --keep-session @docs/design.md
|
|
530
|
-
```
|
|
141
|
+
## Documentation
|
|
531
142
|
|
|
532
|
-
|
|
143
|
+
| Guide | What's inside |
|
|
144
|
+
|---|---|
|
|
145
|
+
| [Installation](docs/guide/installation.md) | CLI, Pi package, agent skills (Claude Code / Codex / Cursor / agy), updates, from source |
|
|
146
|
+
| [CLI reference](docs/guide/cli-reference.md) | Every flag, review modes, when to use which command |
|
|
147
|
+
| [Fast screening](docs/guide/screening.md) | The `screen` workflow, gate outcomes, machine output, and CI placement |
|
|
148
|
+
| [Panel review](docs/guide/panel-review.md) | Consensus policies, aggregation, Jev, `classify`, `screen`, live UI, web dashboard |
|
|
149
|
+
| [Loop review](docs/guide/loop-review.md) | Bounded rounds, `--until clean`, cross-round comparison, convergence stop |
|
|
150
|
+
| [Output & integration](docs/guide/output-and-integration.md) | Markdown shape, `PI_REVIEW_META_JSON` schema, exit codes, sessions, progress logs |
|
|
151
|
+
| [Configuration](docs/guide/configuration.md) | Config file, environment variables, security model |
|
|
152
|
+
| [Providers](docs/guide/providers.md) | OrcaRouter and other provider setup |
|
|
153
|
+
| [Research](docs/research/) | Jev architecture, screening measurements, adjudication case studies |
|
|
533
154
|
|
|
534
|
-
|
|
535
|
-
- **Thinking suffix** after `provider/model:` — only levels the chosen model actually supports.
|
|
536
|
-
- **Semantic phrases** (e.g. `code review` / 代码审核, `查看模型列表`) in addition to flags; orchestration prompts follow **session locale** (zh/en) for summaries.
|
|
537
|
-
- **Scene templates** at the top level (code / frontend / plan presets).
|
|
155
|
+
## Contributing
|
|
538
156
|
|
|
539
|
-
|
|
157
|
+
Issues and PRs welcome. Source is English-only; docs may be bilingual. Commits go through `ai-commit` via Husky (`npm install` sets up the hooks). See [installation → contributing](docs/guide/installation.md#contributing-language-policy).
|
|
540
158
|
|
|
541
|
-
|
|
159
|
+
## Star history
|
|
542
160
|
|
|
543
|
-
|
|
161
|
+
If `pi-review` caught a bug before your reviewer did, a ⭐ helps others find it.
|
|
544
162
|
|
|
545
|
-
|
|
546
|
-
- Default runs use `--no-session` — no child context is stored
|
|
547
|
-
- Children run isolated with `--no-extensions` by default so host usage HUDs / reload bridges cannot crash a reviewer via stale extension context after dispose (see issue #8). Enable host extension loading persistently with `{ "childExtensions": true }` in `~/.pi/pi-review/config.json`, or per run with `PI_REVIEW_CHILD_EXTENSIONS=1` — only when a custom provider truly must register inside the child.
|
|
548
|
-
- Before spawning, pi-review probes the Pi model catalog when an explicit provider is in effect (via `--provider` or the `provider/` prefix of `--model`): if the provider only exists with host extensions loaded, the run is blocked with an actionable hint (`verdictSource: "config_error"`, meta `extensionHint`; panel runs aggregate every affected provider into `extensionHints`) instead of failing with a confusing unknown-provider error — set `childExtensions: true` in the config file or re-run with `PI_REVIEW_CHILD_EXTENSIONS=1`. Catalog probes are cached only on success; a transient probe failure never blocks a review.
|
|
549
|
-
- On reviewer runtime failure, the panel footer and `reviewers[].runtimeError` keep a child stderr/stack tail for diagnosis
|
|
550
|
-
- `--keep-session` stores only the child review session for explicit follow-up
|
|
551
|
-
- The review session is read-only: no file edits, patches, commits, or deployments
|
|
163
|
+
[](https://star-history.com/#ZephyrDeng/pi-review&Date)
|
|
552
164
|
|
|
553
165
|
## Acknowledgments
|
|
554
166
|
|
|
555
|
-
|
|
167
|
+
System prompt structure inspired by [Codex-5.5-codex-instruct-5.5](https://github.com/yynxxxxx/Codex-5.5-codex-instruct-5.5) (MIT).
|
|
556
168
|
|
|
557
169
|
## License
|
|
558
170
|
|