@zephyrdeng/pi-review 0.16.0 → 0.17.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.
package/README.md CHANGED
@@ -1,353 +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
  [![npm version](https://img.shields.io/npm/v/@zephyrdeng/pi-review.svg)](https://www.npmjs.com/package/@zephyrdeng/pi-review)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
+ [![npm downloads](https://img.shields.io/npm/dm/@zephyrdeng/pi-review.svg)](https://www.npmjs.com/package/@zephyrdeng/pi-review)
9
+ [![GitHub stars](https://img.shields.io/github/stars/ZephyrDeng/pi-review?style=flat&logo=github)](https://github.com/ZephyrDeng/pi-review/stargazers)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
11
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-green.svg)](https://nodejs.org)
6
12
 
7
- **Isolated AI-powered code and plan reviews from the command line.**
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
- [![Powered by OrcaRouter](https://img.shields.io/badge/Powered_by-OrcaRouter-2563eb)](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
- - **Isolated review sessions** — each review runs in a clean child process with no shared state
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
- ## Language policy
17
+ ---
82
18
 
83
- - **Source code** (CLI, extensions, presets, prompts, TUI strings emitted from code): **English only**.
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
- ### One-shot (Pi + other agents)
98
-
99
- ```bash
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, ...)
114
-
115
- ```bash
116
- npx @zephyrdeng/pi-review install-skill
117
- ```
118
-
119
- This uses the [skills CLI](https://www.npmjs.com/package/skills) when available — it will prompt you to choose which agents to install to. Falls back to a direct copy into Claude Code (`~/.claude/skills`) and agy / Antigravity (`~/.gemini/config/skills`, discovered by AGY / AGY CLI / AGY IDE) if `skills` is not found.
120
-
121
- You can also specify agents directly. `agy` is accepted as a shorthand for the skills CLI ids `antigravity` + `antigravity-cli`:
122
-
123
- ```bash
124
- pi-review install-skill --agent claude-code codex cursor agy
125
- # or only Antigravity:
126
- pi-review install-skill --agent agy
127
- ```
128
-
129
- To remove:
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. **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 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 and is recorded as `adjudicationFallbackNote` in the meta (escalations are noted there too). The aggregate meta carries `adjudicationEngine: "jev" | "pi"` whenever adjudication ran, and `/rv-config` shows the effective setting and key presence. A measured comparison of Jev, the Pi adjudicator, and the shipped cascade across single/multi-round loops and 1/3 reviewers is recorded in [docs/research/jev-adjudication-case.md](docs/research/jev-adjudication-case.md).
237
-
238
- **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:
239
-
240
- ```bash
241
- pi-review classify --baseline "fix the login crash; UI polish is out of scope" --meta /tmp/last-review-meta.txt
242
- # or pipe the review output directly:
243
- pi-review -- @src 2>&1 | pi-review classify --baseline "..."
244
- ```
245
-
246
- 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).
247
-
248
- **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.
249
-
250
- ```bash
251
- pi-review screen src/order-service.ts # or @file refs; exits 1 on findings, 0 when clean
252
- ```
253
-
254
- The architecture, end to end:
255
-
256
- ```
257
- files ─► 1. deterministic slice (local, ms — declaration-boundary hunks)
258
- │
259
- ├─► 2. one Jev call (~1s — per hunk: 1 catch-all Noul
260
- │ "any blocking defect?" + 1 Noul per catalog pattern;
261
- │ fanned out in parallel, chunked past 480 questions)
262
- │
263
- └─► 3. template assembly (local, ms — pattern hit ⇒ finding
264
- + gate from catalog severity/title/fix;
265
- catch-all hit without a pattern ⇒
266
- "unmatched signal" finding, still
267
- blocks — never silently dropped)
268
- ```
269
-
270
- 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).
271
-
272
- ### Cost and failure
273
-
274
- 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.
275
-
276
- 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:
277
-
278
- ![CLI panel footer: NEEDS HUMAN gate with 2/3 successful reviewers, quorum consensus, confirmed findings, advisories, mixed models, and per-reviewer status](docs/assets/panel-cli-footer.jpg)
279
-
280
- ### Machine output
281
-
282
- 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`.
283
-
284
- 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.
285
-
286
- ### Live Pi progress and event replay
287
-
288
- In Pi, slash commands select strategy only:
289
-
290
- - `/rv <natural-language target>` → panel review via native `pi_review`
291
- - `/rv-loop <natural-language target>` → loop closeout via shell CLI
292
- - `/rv-models` → model catalog
293
-
294
- 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.
295
-
296
- ![Pi Review Panel live progress: code-experts panel with correctness, security, and testing reviewers, each showing status, model, thinking level, tokens, and cost](docs/assets/panel-live-pi.jpg)
297
-
298
- Example: `pi-review --panel code-experts -- @src` (or `/rv` in Pi with the same panel strategy).
299
-
300
- Renderer adapters can consume the stable, versioned event stream directly:
301
-
302
- ```bash
303
- pi-review --panel code-experts --output-format events-jsonl -- @src
304
- ```
305
-
306
- 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.
307
-
308
- 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.
309
-
310
- ### Live web dashboard
311
-
312
- `--ui web` starts an opt-in, loopback-only dashboard for hosts without a native Pi renderer (Claude Code, Codex, plain terminals):
313
-
314
- ```bash
315
- pi-review --reviewers 3 --consensus quorum --ui web -- @src
316
- ```
317
-
318
- ![Web dashboard while reviewing: aggregate reviewer/elapsed/token/tool counters and per-reviewer cards with RUNNING status, model, thinking level, and live activity](docs/assets/panel-web-dashboard.jpg)
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>
319
30
 
320
- 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.
31
+ ## Why pi-review
321
32
 
322
- 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.
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. |
323
43
 
324
- 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`.
44
+ ## See it work
325
45
 
326
- ## Output Format
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>
327
56
 
328
- Every review produces Markdown with these sections:
329
-
330
- ```
331
- ## Verdict
332
- approve | request_changes | needs_clarification | blocked
333
-
334
- ## Summary
335
- ## Findings
336
- ### F1: <summary>
337
- - Severity: critical | high | medium | low
338
- - Path: <path or none>
339
- - Lines: <line or line-range in Path, or none>
340
- - Side: base | working (optional; defaults to working)
341
- - Actionable: yes | no
342
- - Evidence: <concrete evidence>
343
- - Impact: <why it matters>
344
- - Recommendation: <specific next step>
345
-
346
- ## Risks and Blind Spots
347
- ## Open Questions
348
- ```
349
-
350
- 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:
351
58
 
352
59
  ```
353
60
  ── pi-review ────────────────────────────
@@ -356,185 +63,108 @@ The CLI appends a readable ASCII footer on **stdout**:
356
63
  Mode code
357
64
  Findings 1 actionable / 1 total
358
65
  Model provider/model
359
- Thinking xhigh
360
- 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
361
67
  Cost $0.05
362
68
  Duration 42.3s
363
69
  ──────────────────────────────────────────
364
70
  ```
365
71
 
366
- `Thinking` shows the requested thinking level when set; `Tokens` shows the child session's token usage (`in`/`out`/`cache`/`reason` plus total) parsed from the `--mode json` event stream. `Cost` shows the provider-reported total, or `n/a` when the provider does not report one. Both are collected during normal streaming; `--progress-log` is not required.
367
-
368
- For scripts, parse **`PI_REVIEW_META_JSON:`** from **stderr**. Existing keys remain, with additive fields:
369
-
370
- ```json
371
- {"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}}
372
- ```
373
-
374
- `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.
375
-
376
- ### Machine finding schema
377
-
378
- `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)
379
73
 
380
- Each finding gains three optional fields alongside the existing `{ id?, severity?, path?, summary, actionable }` shape:
74
+ ## Quick start
381
75
 
382
- | Field | Type | Present when |
383
- |-------|------|--------------|
384
- | `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. |
385
- | `recommendation` | `string` | The reviewer's Recommendation field parsed, verbatim and kept separate from `details`. |
386
- | `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.
387
77
 
388
- Example with all three populated:
78
+ ```bash
79
+ # CLI
80
+ npm install -g @zephyrdeng/pi-review
389
81
 
390
- ```json
391
- {"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,"details":"Evidence: runReview forwards the child exit code.\n\nImpact: A review gate passes with actionable findings.","recommendation":"Map structured status to a stable exit code.","location":{"startLine":42,"endLine":58}}],"actionableCount":1,"durationMs":42300,"model":"provider/model"}
82
+ # …or one shot: Pi package + skill for Claude Code / Codex / Cursor / Antigravity
83
+ npx @zephyrdeng/pi-review install
392
84
  ```
393
85
 
394
- All three finding-level fields and `metaVersion` are additive: existing consumers reading only `{ id?, severity?, path?, summary, actionable }` are unaffected, and a file-level finding with no reliable line data simply omits `location` while `details`/`recommendation` still populate when Evidence/Impact/Recommendation parsed. This machine schema — including the panel `sourceFindings` fields documented under [Panel Review § Machine output](#machine-output) and the per-round stream documented under [Loop Review](#loop-review) — is a **supported integration surface**: renderers should read `PI_REVIEW_META_JSON` directly and never need to scrape review Markdown for Evidence/Impact/Recommendation/line data.
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
+ ```
395
94
 
396
- The parser prefers the exact `### F1` shape above but also accepts legacy `###` headings and top-level finding lists. When `Actionable` is missing, findings under `request_changes` default to actionable and other verdicts default to non-actionable. A missing/unrecognized verdict falls back to `needs_clarification` / `needs_human` and includes `parseError`; runtime failures always remain `blocked`.
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.
397
96
 
398
- ### Exit codes
97
+ → [Installation options](docs/guide/installation.md) · [Pi `/rv` commands](docs/guide/pi-package.md)
399
98
 
400
- | Code | Meaning |
401
- |------|---------|
402
- | `0` | Final status is `clean` |
403
- | `1` | Final status is `has_findings` / loop budget exhausted |
404
- | `2` | CLI usage or argument error |
405
- | `3` | `needs_human` — clarification or a decision is required |
406
- | `4` | `blocked` — child/runtime failure or review cannot proceed |
99
+ ## How the panel decides
407
100
 
408
- ## Session Management
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
+ ```
409
109
 
410
- ```bash
411
- # Keep a review session for follow-up
412
- 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)
413
111
 
414
- # Continue a previous session (same optional flags as an initial run)
415
- pi-review --continue <sessionHandle> --mode challenge --model provider/model -- "expand finding 2"
416
- ```
112
+ ## Partners
417
113
 
418
- ## Live Progress and Token Usage
114
+ <table>
115
+ <tr>
116
+ <td width="50%" valign="top">
419
117
 
420
- `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** to stderr — `pi-review: review started`, `pi-review: tool <name> started/finished`, `pi-review: review finished`. Token usage (`input`/`output`/`cache`/`reasoning`) is accumulated by default and shown in the ASCII footer and `PI_REVIEW_META_JSON` — **no `--progress-log` required**.
118
+ ### [OrcaRouter](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
421
119
 
422
- Agent hosts like Claude Code, Cursor, Codex, and agy typically buffer a Bash tool's stdout until the command exits. The stderr milestone notices give you progress signals without tailing a file. The final Markdown review + ASCII footer arrive on stdout when the process exits.
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.
423
121
 
424
- `--progress-log <path>` is now an **optional** convenience for fine-grained debugging: it tees the `--mode json` event stream to a file. By default the tee is **slimmed** — each `message_update` line reduces its cumulative message snapshots (`assistantMessageEvent.partial` and the duplicate top-level `message`) to their `usage` field. A verbatim tee repeats the entire message-so-far plus provider metadata on every delta, growing the file quadratically with message length (real reviews measured a ~1600x byte amplification). Deltas and message boundaries (`message_end`, `turn_end`, `agent_end`) keep the complete record, so the slimmed log still reconstructs the review and replays through pi-review's own event parser with no feature loss. Add `--progress-log-raw` when you need the verbatim stream. `--progress-log` no longer gates token visibility. Details: [`skills/pi-review/SKILL.md`](skills/pi-review/SKILL.md) and [`skills/pi-review/references/codex-tools.md`](skills/pi-review/references/codex-tools.md).
122
+ [![Powered by OrcaRouter](https://img.shields.io/badge/Powered_by-OrcaRouter-2563eb)](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
425
123
 
426
- ```bash
427
- # Optional: capture the event log for debugging (slimmed by default; add --progress-log-raw for verbatim)
428
- pi-review --progress-log /tmp/pi-review.jsonl -- @src/foo.ts &
429
- tail -f -n +1 /tmp/pi-review.jsonl | jq -c --unbuffered '
430
- select(.type != "message_update" and .type != "tool_execution_update")
431
- '
432
- ```
124
+ → [Setup guide](docs/guide/providers.md)
433
125
 
434
- The JSON event schema is pi CLI's own internal format, not a contract `pi-review` guarantees — it may change between pi versions. `pi-review` parses it defensively (unparseable lines are skipped, missing events degrade to a diagnostic `parseError`) and still prints the same clean Markdown + ASCII footer to stdout once the child exits.
126
+ </td>
127
+ <td width="50%" valign="top">
435
128
 
436
- ## CLI Reference
129
+ ### [TypeSafe Jev](https://typesafe.ai)
437
130
 
438
- ```
439
- pi-review [review] [options] -- <@files|text...>
440
- pi-review loop [options] -- <@files|text...>
441
- pi-review screen <@files|paths...>
442
- pi-review classify --baseline <text|@file> [--meta <path>]
443
- pi-review models [search]
444
- ```
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.
445
132
 
446
- | Option | Description |
447
- |--------|-------------|
448
- | `--mode <name>` | Review mode (default: `code`) |
449
- | `--model <provider/model[:thinking]>` | Model to use for the review |
450
- | `--provider <name>` | Model provider |
451
- | `--thinking <level>` | Thinking level: `off\|minimal\|low\|medium\|high\|xhigh` |
452
- | `--skill <path>` | Load an extra Pi skill (repeatable) |
453
- | `--tools <csv>` | Override allowed tools |
454
- | `--keep-session` | Persist session for follow-up |
455
- | `--continue <handle>` | Continue an existing session |
456
- | `--name <name>` | Session name (with `--keep-session`) |
457
- | `--no-stream` | Buffer child output until exit (default: stream live) |
458
- | `--progress-log <path>` | Stream compact child `--mode json` events to this file (cannot combine with `--no-stream`) |
459
- | `--progress-log-raw` | With `--progress-log`: tee the verbatim event stream (full message snapshots; much larger files) |
460
- | `--max-rounds <n>` | Positive loop hard budget (default: `3`; with `--until clean` default: `10`; `loop` only) |
461
- | `--until clean` | Loop goal: keep going until the clean gate (still hard-capped by `--max-rounds`; never unlimited) |
462
- | `--reviewers <n>` | Panel: number of independent reviewers (2-8; activates panel mode) |
463
- | `--panel <name>` | Panel: named expert-panel preset (cannot combine with `--reviewers`) |
464
- | `--consensus <policy>` | Panel: `any \| quorum \| majority \| unanimous` (default: `quorum`) |
465
- | `--min-agree <n>` | Panel: minimum reviewers for quorum (default: `2`; quorum only) |
466
- | `--consensus-model <model>` | Panel: model for semantic consensus adjudication |
467
- | `--concurrency <n>` | Panel: bounded reviewer concurrency (default: reviewer count) |
468
- | `--output-format events-jsonl` | Panel: normalized `ReviewEvent v1` JSONL for renderer adapters |
469
-
470
- Session flags (`--keep-session`, `--continue`, `--name`) are unsupported by `loop` and panel in v1; invalid combinations print usage and exit `2`.
471
-
472
- ## Configuration
473
-
474
- 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).
475
-
476
- | Key | Type | Default | Description |
477
- |-----|------|---------|-------------|
478
- | `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). |
479
- | `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. |
480
-
481
- Per-process overrides via environment variables (env wins over the config file):
482
-
483
- | Variable | Description |
484
- |----------|-------------|
485
- | `PI_BIN` | Pi executable path (default: `pi`) |
486
- | `PI_REVIEW_HOME` | Directory containing `review-presets.json` and `system-prompt.md` |
487
- | `PI_REVIEW_PRESETS` | Path to presets JSON file |
488
- | `PI_REVIEW_PANEL_PRESETS` | Path to panel presets JSON file |
489
- | `PI_REVIEW_SYSTEM_PROMPT` | Path to system prompt file |
490
- | `PI_REVIEW_SESSION_DIR` | Directory for persisted review sessions |
491
- | `PI_REVIEW_META_STDOUT` | Set to `1`/`true` to print `PI_REVIEW_META_JSON` on stdout instead of stderr |
492
- | `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`) |
493
- | `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 |
494
- | `PI_REVIEW_CONFIG` | Path to the review config file (default: `~/.pi/pi-review/config.json`) |
495
-
496
- ## Pi Package Usage
497
-
498
- After installing as a Pi package, use the `/rv` slash command:
133
+ Set `TYPESAFE_API_KEY` and it switches on.
499
134
 
500
- ```
501
- /rv @src/foo.ts
502
- /rv --mode challenge @docs/design.md
503
- ```
135
+ → [Comparison report](docs/research/jev-comparison-report.html) · [Screening study](docs/research/jev-screening-case.md)
504
136
 
505
- Slash commands inject a task message for the parent agent. Strategy is selected by the command (`/rv`, `/rv-loop`, `/rv-models`); the remainder is the natural-language target. `/rv-config` is read-only: it shows the effective configuration (config file, env overrides, resolved paths). Use plain `/rv @src`, `/rv review the auth changes`, or `/rv-loop fix until clean @src` in Pi — no extra streaming flags needed for panel runs. `--continue`, `--keep-session`, loop, and explicit `--no-stream` retain the shell CLI path.
137
+ </td>
138
+ </tr>
139
+ </table>
506
140
 
507
- ```
508
- /rv models
509
- /rv @src/foo.ts
510
- /rv --mode plan @docs/architecture.md
511
- /rv --mode challenge --keep-session @docs/design.md
512
- ```
141
+ ## Documentation
513
142
 
514
- Argument completions are context-aware. After the host session starts, `/rv` reads the live model registry and offers:
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 |
515
154
 
516
- - **Model list** after `--model `: candidates come from the live Pi registry; order follows **`resources/rv-model-priorities.json`** (override with `PI_REVIEW_RV_PRIORITIES`). Presets match registry ids by substring and prefer newer version strings (e.g. kimi `2.7`, `claude-opus-4-8`). Profiles: **code / fast** (claude-sonnet-5, deepseek-v4-flash, glm-5.2, minimax-m3, grok-4.5, gpt-5.6-terra/luna), **frontend / vision** (claude → gpt → kimi-2.7 → minimax-m3), **plan / complex** (gpt-5.6-sol max, claude-opus-4.8 xhigh, claude-fable-5 max cautious, glm-5.2 / deepseek-v4-pro / grok-4.5 max).
517
- - **Thinking suffix** after `provider/model:` — only levels the chosen model actually supports.
518
- - **Semantic phrases** (e.g. `code review` / 代码审核, `查看模型列表`) in addition to flags; orchestration prompts follow **session locale** (zh/en) for summaries.
519
- - **Scene templates** at the top level (code / frontend / plan presets).
155
+ ## Contributing
520
156
 
521
- **Claude Code / Codex / Cursor / agy:** the bundled skill includes **[skills/pi-review/references/model-selection.md](skills/pi-review/references/model-selection.md)** — same presets as `/rv` for choosing `--model` after `pi-review models`.
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).
522
158
 
523
- Completions are a hint layer only; execution remains skill-driven. When the model registry is unavailable (e.g. non-TUI mode), `/rv` falls back to the static hint list.
159
+ ## Star history
524
160
 
525
- ## Security
161
+ If `pi-review` caught a bug before your reviewer did, a ⭐ helps others find it.
526
162
 
527
- - Each review and every loop round runs in an isolated child Pi session
528
- - Default runs use `--no-session` — no child context is stored
529
- - 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.
530
- - 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.
531
- - On reviewer runtime failure, the panel footer and `reviewers[].runtimeError` keep a child stderr/stack tail for diagnosis
532
- - `--keep-session` stores only the child review session for explicit follow-up
533
- - The review session is read-only: no file edits, patches, commits, or deployments
163
+ [![Star History Chart](https://api.star-history.com/svg?repos=ZephyrDeng/pi-review&type=Date)](https://star-history.com/#ZephyrDeng/pi-review&Date)
534
164
 
535
165
  ## Acknowledgments
536
166
 
537
- The system prompt structure draws inspiration from [Codex-5.5-codex-instruct-5.5](https://github.com/yynxxxxx/Codex-5.5-codex-instruct-5.5) by li lingbo, licensed under the [MIT License](https://github.com/yynxxxxx/Codex-5.5-codex-instruct-5.5/blob/main/LICENSE).
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).
538
168
 
539
169
  ## License
540
170