@zephyrdeng/pi-review 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +61 -4
  2. package/README.zh-CN.md +57 -2
  3. package/dist/child-isolation.test.js +25 -7
  4. package/dist/child-isolation.test.js.map +1 -1
  5. package/dist/cli.js +7 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/extensions/review.d.ts +2 -0
  8. package/dist/extensions/review.js +22 -0
  9. package/dist/extensions/rv-prompts.d.ts +19 -0
  10. package/dist/extensions/rv-prompts.js +132 -0
  11. package/dist/index.d.ts +5 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/panel-cli.test.js +35 -0
  16. package/dist/panel-cli.test.js.map +1 -1
  17. package/dist/panel-config.d.ts +7 -0
  18. package/dist/panel-config.d.ts.map +1 -1
  19. package/dist/panel-config.js +12 -0
  20. package/dist/panel-config.js.map +1 -1
  21. package/dist/panel.d.ts +7 -1
  22. package/dist/panel.d.ts.map +1 -1
  23. package/dist/panel.js +44 -1
  24. package/dist/panel.js.map +1 -1
  25. package/dist/pi-config.d.ts +54 -0
  26. package/dist/pi-config.d.ts.map +1 -0
  27. package/dist/pi-config.js +87 -0
  28. package/dist/pi-config.js.map +1 -0
  29. package/dist/pi-config.test.d.ts +2 -0
  30. package/dist/pi-config.test.d.ts.map +1 -0
  31. package/dist/pi-config.test.js +78 -0
  32. package/dist/pi-config.test.js.map +1 -0
  33. package/dist/provider-probe.test.d.ts +2 -0
  34. package/dist/provider-probe.test.d.ts.map +1 -0
  35. package/dist/provider-probe.test.js +192 -0
  36. package/dist/provider-probe.test.js.map +1 -0
  37. package/dist/review.d.ts +58 -5
  38. package/dist/review.d.ts.map +1 -1
  39. package/dist/review.js +159 -9
  40. package/dist/review.js.map +1 -1
  41. package/dist/skill-protocol.test.js +13 -0
  42. package/dist/skill-protocol.test.js.map +1 -1
  43. package/dist/types.d.ts +25 -1
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/types.js.map +1 -1
  46. package/extensions/review.test.ts +8 -0
  47. package/extensions/review.ts +11 -0
  48. package/extensions/rv-config.test.ts +90 -0
  49. package/extensions/rv-config.ts +150 -0
  50. package/extensions/rv-prompts.ts +1 -1
  51. package/package.json +1 -1
  52. package/resources/providers/orcarouter.json +28 -0
  53. package/skills/pi-review/SKILL.md +14 -1
  54. package/skills/pi-review/references/codex-tools.md +2 -0
  55. package/skills/pi-review/references/model-selection.md +1 -1
package/README.md CHANGED
@@ -14,6 +14,55 @@ Works as a standalone CLI, a Pi package (extension + skill), or integrated into
14
14
 
15
15
  - [Pi CLI](https://pi.dev) installed and configured with at least one model provider
16
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), e.g.:
30
+
31
+ ```bash
32
+ # jq not required; the file also works as-is when models.json doesn't exist yet
33
+ cp resources/providers/orcarouter.json ~/.pi/agent/models.json
34
+ ```
35
+
36
+ ```json
37
+ {
38
+ "providers": {
39
+ "orcarouter": {
40
+ "baseUrl": "https://api.orcarouter.ai/v1",
41
+ "api": "openai-completions",
42
+ "apiKey": "ORCA_KEY",
43
+ "models": [
44
+ {
45
+ "id": "orcarouter/auto",
46
+ "name": "OrcaRouter Auto",
47
+ "reasoning": false,
48
+ "input": ["text"],
49
+ "contextWindow": 200000,
50
+ "maxTokens": 8192
51
+ }
52
+ ]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ 3. **Pick the model** when you run a review:
59
+
60
+ ```bash
61
+ pi-review --model orcarouter/orcarouter/auto -- @src/foo.ts
62
+ ```
63
+
64
+ [![Powered by OrcaRouter](https://img.shields.io/badge/Powered_by-OrcaRouter-2563eb)](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
65
+
17
66
  ## Features
18
67
 
19
68
  - **Isolated review sessions** — each review runs in a clean child process with no shared state
@@ -380,7 +429,13 @@ Session flags (`--keep-session`, `--continue`, `--name`) are unsupported by `loo
380
429
 
381
430
  ## Configuration
382
431
 
383
- Override defaults via environment variables:
432
+ 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).
433
+
434
+ | Key | Type | Default | Description |
435
+ |-----|------|---------|-------------|
436
+ | `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). |
437
+
438
+ Per-process overrides via environment variables (env wins over the config file):
384
439
 
385
440
  | Variable | Description |
386
441
  |----------|-------------|
@@ -391,7 +446,8 @@ Override defaults via environment variables:
391
446
  | `PI_REVIEW_SYSTEM_PROMPT` | Path to system prompt file |
392
447
  | `PI_REVIEW_SESSION_DIR` | Directory for persisted review sessions |
393
448
  | `PI_REVIEW_META_STDOUT` | Set to `1`/`true` to print `PI_REVIEW_META_JSON` on stdout instead of stderr |
394
- | `PI_REVIEW_CHILD_EXTENSIONS` | Set to `1`/`true`/`keep` to let review children load host Pi extensions (default: children run with `--no-extensions`) |
449
+ | `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 |
450
+ | `PI_REVIEW_CONFIG` | Path to the review config file (default: `~/.pi/pi-review/config.json`) |
395
451
 
396
452
  ## Pi Package Usage
397
453
 
@@ -402,7 +458,7 @@ After installing as a Pi package, use the `/rv` slash command:
402
458
  /rv --mode challenge @docs/design.md
403
459
  ```
404
460
 
405
- 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. 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.
461
+ 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.
406
462
 
407
463
  ```
408
464
  /rv models
@@ -426,7 +482,8 @@ Completions are a hint layer only; execution remains skill-driven. When the mode
426
482
 
427
483
  - Each review and every loop round runs in an isolated child Pi session
428
484
  - Default runs use `--no-session` — no child context is stored
429
- - Default runs also pass `--no-extensions` so host usage HUDs / reload bridges cannot crash a reviewer via stale extension context after dispose (see issue #8). Opt out with `PI_REVIEW_CHILD_EXTENSIONS=1` only when a custom provider truly must register inside the child.
485
+ - 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.
486
+ - 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.
430
487
  - On reviewer runtime failure, the panel footer and `reviewers[].runtimeError` keep a child stderr/stack tail for diagnosis
431
488
  - `--keep-session` stores only the child review session for explicit follow-up
432
489
  - The review session is read-only: no file edits, patches, commits, or deployments
package/README.zh-CN.md CHANGED
@@ -21,6 +21,54 @@
21
21
 
22
22
  - 已安装并配置好 [Pi CLI](https://pi.dev),且至少有一个可用模型
23
23
 
24
+ ## 用 OrcaRouter 运行审查
25
+
26
+ `pi-review` 与模型无关——它运行在你 [Pi](https://pi.dev) 中配置的任意模型服务商之上。若要
27
+ 把 [OrcaRouter](https://www.orcarouter.ai) 作为审查背后的服务商:
28
+
29
+ 1. **获取 key**——还没有账号?**用我们的推荐链接注册** <https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36>(下方徽章亦可)。已有 key?直接下一步。
30
+
31
+ ```bash
32
+ export ORCA_KEY="sk-orca-..."
33
+ ```
34
+
35
+ 2. **注册服务商**——把 [`resources/providers/orcarouter.json`](./resources/providers/orcarouter.json) 合并进 `~/.pi/agent/models.json`(OpenAI 兼容):
36
+
37
+ ```bash
38
+ # models.json 不存在时可以直接整个使用;已有内容时用 jq 或手工合并
39
+ cp resources/providers/orcarouter.json ~/.pi/agent/models.json
40
+ ```
41
+
42
+ ```json
43
+ {
44
+ "providers": {
45
+ "orcarouter": {
46
+ "baseUrl": "https://api.orcarouter.ai/v1",
47
+ "api": "openai-completions",
48
+ "apiKey": "ORCA_KEY",
49
+ "models": [
50
+ {
51
+ "id": "orcarouter/auto",
52
+ "name": "OrcaRouter Auto",
53
+ "reasoning": false,
54
+ "input": ["text"],
55
+ "contextWindow": 200000,
56
+ "maxTokens": 8192
57
+ }
58
+ ]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ 3. **选择模型**运行审查:
65
+
66
+ ```bash
67
+ pi-review --model orcarouter/orcarouter/auto -- @src/foo.ts
68
+ ```
69
+
70
+ [![Powered by OrcaRouter](https://img.shields.io/badge/Powered_by-OrcaRouter-2563eb)](https://www.orcarouter.ai/ref/ref_07ca74b3e41670e5ff36)
71
+
24
72
  ## 安装
25
73
 
26
74
  ```bash
@@ -208,13 +256,20 @@ CLI 会在 reviewer 启动前把 `PI_REVIEW_UI_URL: http://127.0.0.1:<port>/run/
208
256
 
209
257
  提交代码:`npm install` 后会启用 **Husky** 钩子(`.husky/` → `ai-commit` 的 prepare-commit-msg / commit-msg / pre-commit)。也可 `git add` 后直接 `ai-commit commit`。配置见 `.ai-commit.yaml`(英文、`ai_footer: off`,需本机安装 ai-commit ≥ v0.1.45)。
210
258
 
211
- 可通过 `PI_REVIEW_HOME`、`PI_REVIEW_PRESETS`、`PI_REVIEW_SYSTEM_PROMPT` 等环境变量覆盖预设与系统提示词路径。预设与审查指令文件内容均为英文。
259
+ 持久化设置在评审配置文件 `~/.pi/pi-review/config.json`(可用 `PI_REVIEW_CONFIG` 覆盖其位置)中。配置是建议性的、向前兼容的:未知键被忽略,`null` 视为未设置,其它任何问题(类型错误、无效 JSON)只打印警告并回落——配置绝不阻塞核心功能,新版本写的配置不会弄坏旧版本。在 Pi 中用 `/rv-config` 查看生效配置(取值、来源、警告、解析路径)。
260
+
261
+ | 键 | 类型 | 默认 | 说明 |
262
+ |-----|------|---------|-------------|
263
+ | `childExtensions` | boolean | `false` | 是否让评审子进程加载宿主 Pi 扩展,以使用仅由扩展注册的 provider。等价于单次运行 `PI_REVIEW_CHILD_EXTENSIONS=1`;`false` 保持子进程隔离(`--no-extensions`,issue #8)。 |
264
+
265
+ 环境变量提供单次进程级覆盖(env 优先于配置文件):`PI_REVIEW_HOME`、`PI_REVIEW_PRESETS`、`PI_REVIEW_PANEL_PRESETS`、`PI_REVIEW_SYSTEM_PROMPT`、`PI_REVIEW_SESSION_DIR`、`PI_REVIEW_META_STDOUT`、`PI_REVIEW_CHILD_EXTENSIONS`(`1`/`true`/`keep` 开启、其它已设值如 `0` 强制隔离、空值视为未设置;持久化等价写法为配置文件里 `{ "childExtensions": true }`)、`PI_REVIEW_CONFIG`。预设与审查指令文件内容均为英文。
212
266
 
213
267
  ## 安全
214
268
 
215
269
  - 每次审查在隔离子进程中运行
216
270
  - 默认不保留子会话;`--keep-session` 仅用于显式跟进
217
- - 默认还会传 `--no-extensions`,避免宿主 usage HUD / reload bridge 在 dispose 后触 stale extension ctx 搞崩 reviewer(见 issue #8)。仅当自定义 provider 必须在子进程内注册时,才用 `PI_REVIEW_CHILD_EXTENSIONS=1` 退出隔离
271
+ - 默认子进程以 `--no-extensions` 隔离运行,避免宿主 usage HUD / reload bridge 在 dispose 后触 stale extension ctx 搞崩 reviewer(见 issue #8)。需要自定义 provider 在子进程内注册时,可在 `~/.pi/pi-review/config.json` 里持久化 `{ "childExtensions": true }`,或单次运行用 `PI_REVIEW_CHILD_EXTENSIONS=1`
272
+ - 显式指定 provider(`--provider` 或 `--model` 的 `provider/` 前缀)时,spawn 前会先探测 Pi 模型目录:若该 provider 仅在加载宿主扩展后才存在,则直接以可执行的提示阻塞运行(`verdictSource: "config_error"`,meta 带 `extensionHint`;panel 运行会把所有受影响的 provider 聚合到 `extensionHints`),而不是抛一个令人困惑的 unknown-provider 错误——在配置文件中设置 `childExtensions: true` 或重跑时加 `PI_REVIEW_CHILD_EXTENSIONS=1`。目录探测仅在成功时缓存,瞬时探测失败不会阻塞审查
218
273
  - reviewer 运行时失败时,panel footer 与 `reviewers[].runtimeError` 会保留子进程 stderr/stack 尾部便于诊断
219
274
  - 审查会话只读,不编辑、不部署
220
275
 
@@ -1,16 +1,34 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { test } from "vitest";
3
- import { CHILD_STDERR_DIAGNOSTIC_LIMIT, childIsolationArgs, formatChildRuntimeDetail, } from "./review.js";
3
+ import { CHILD_STDERR_DIAGNOSTIC_LIMIT, childIsolationArgs, formatChildRuntimeDetail, modelsArgs, } from "./review.js";
4
4
  import { buildReviewerArgs } from "./panel.js";
5
5
  test("childIsolationArgs defaults to --no-extensions for host isolation", () => {
6
- assert.deepEqual(childIsolationArgs({}), ["--no-extensions"]);
7
- assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "" }), ["--no-extensions"]);
8
- assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "0" }), ["--no-extensions"]);
6
+ assert.deepEqual(childIsolationArgs({}, {}), ["--no-extensions"]);
7
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "" }, {}), ["--no-extensions"]);
8
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "0" }, {}), ["--no-extensions"]);
9
9
  });
10
10
  test("childIsolationArgs can opt back into host extensions", () => {
11
- assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "1" }), []);
12
- assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "true" }), []);
13
- assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "KEEP" }), []);
11
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "1" }, {}), []);
12
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "true" }, {}), []);
13
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "KEEP" }, {}), []);
14
+ });
15
+ test("childIsolationArgs honors the persistent config childExtensions key", () => {
16
+ assert.deepEqual(childIsolationArgs({}, { childExtensions: true }), []);
17
+ assert.deepEqual(childIsolationArgs({}, { childExtensions: false }), ["--no-extensions"]);
18
+ });
19
+ test("childIsolationArgs: env overrides the persistent config in both directions", () => {
20
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "0" }, { childExtensions: true }), ["--no-extensions"]);
21
+ assert.deepEqual(childIsolationArgs({ PI_REVIEW_CHILD_EXTENSIONS: "1" }, { childExtensions: false }), []);
22
+ });
23
+ test("modelsArgs applies the same effective isolation as review children", () => {
24
+ assert.deepEqual(modelsArgs(["openai"], {}, {}), ["--list-models", "--no-extensions", "openai"]);
25
+ assert.deepEqual(modelsArgs(["openai"], {}, { childExtensions: true }), ["--list-models", "openai"]);
26
+ assert.deepEqual(modelsArgs(["openai"], { PI_REVIEW_CHILD_EXTENSIONS: "1" }, {}), ["--list-models", "openai"]);
27
+ assert.deepEqual(modelsArgs(["openai"], { PI_REVIEW_CHILD_EXTENSIONS: "0" }, { childExtensions: true }), [
28
+ "--list-models",
29
+ "--no-extensions",
30
+ "openai",
31
+ ]);
14
32
  });
15
33
  test("formatChildRuntimeDetail preserves a multi-line child stack tail", () => {
16
34
  const stack = [
@@ -1 +1 @@
1
- {"version":3,"file":"child-isolation.test.js","sourceRoot":"","sources":["../src/child-isolation.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"child-isolation.test.js","sourceRoot":"","sources":["../src/child-isolation.test.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -5,12 +5,19 @@ import { readReviewStdin, runModels, runReview, runReviewOnce } from "./review.j
5
5
  import { formatLoopSummary, runReviewLoop } from "./loop.js";
6
6
  import { runPanelReview, runPanelReviewOnce, runPanelReviewWithUi } from "./panel.js";
7
7
  import { resolveConfig } from "./config.js";
8
+ import { currentConfig } from "./pi-config.js";
8
9
  import { installSkill, uninstallSkill } from "./skill.js";
9
10
  import { runUpdate } from "./update.js";
10
11
  import { runInstall } from "./install.js";
11
12
  const parsed = parseArgs(process.argv.slice(2));
12
13
  if (isInstallHelp(parsed))
13
14
  usage(0);
15
+ // The config file is advisory: warn about leniently-ignored values but never
16
+ // block core functionality — a config written by a newer pi-review must not
17
+ // brick an older one.
18
+ for (const warning of currentConfig().warnings) {
19
+ process.stderr.write(`pi-review: config warning: ${warning}\n`);
20
+ }
14
21
  if (parsed.command === "models") {
15
22
  const config = resolveConfig();
16
23
  runModels(config.piBin, parsed.search || []);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ export default function piReviewExtension(pi: ExtensionAPI): void;
@@ -0,0 +1,22 @@
1
+ import { buildRvOrchestrationPrompt, parseRvArgs, RV_COMPLETIONS } from "./rv-prompts.js";
2
+ export default function piReviewExtension(pi) {
3
+ pi.registerCommand("rv", {
4
+ description: "Delegate pi-review to the agent (English prompts). Usage: /rv [--mode plan|challenge] [--model id] [--keep-session] @file-or-text | models",
5
+ getArgumentCompletions: (prefix) => {
6
+ const filtered = RV_COMPLETIONS.filter((item) => item.value.startsWith(prefix));
7
+ return filtered.length
8
+ ? filtered.map(({ value, hint }) => ({ value, label: value, description: hint }))
9
+ : null;
10
+ },
11
+ handler: async (rawArgs, ctx) => {
12
+ const trimmed = rawArgs.trim();
13
+ const parsed = parseRvArgs(trimmed);
14
+ const prompt = buildRvOrchestrationPrompt(parsed);
15
+ if (!trimmed && !parsed.modelsOnly) {
16
+ ctx.ui.notify("/rv needs a target or `models`. Try: /rv @path or /rv models", "warning");
17
+ return;
18
+ }
19
+ pi.sendUserMessage(prompt);
20
+ },
21
+ });
22
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * English orchestration prompts for /rv — parent Pi agent runs pi-review per skill.
3
+ * Child review sessions use presets in resources/review-presets.json (also English).
4
+ */
5
+ export type RvParsed = {
6
+ mode: "code" | "plan" | "challenge";
7
+ model?: string;
8
+ keepSession: boolean;
9
+ continueHandle?: string;
10
+ modelsOnly: boolean;
11
+ target: string;
12
+ };
13
+ export declare function parseRvArgs(raw: string): RvParsed;
14
+ export declare function buildRvOrchestrationPrompt(parsed: RvParsed): string;
15
+ /** Short labels for TUI completions (English). */
16
+ export declare const RV_COMPLETIONS: {
17
+ value: string;
18
+ hint: string;
19
+ }[];
@@ -0,0 +1,132 @@
1
+ /**
2
+ * English orchestration prompts for /rv — parent Pi agent runs pi-review per skill.
3
+ * Child review sessions use presets in resources/review-presets.json (also English).
4
+ */
5
+ export function parseRvArgs(raw) {
6
+ const tokens = raw.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) ?? [];
7
+ const cleaned = tokens.map((t) => t.replace(/^['"]|['"]$/g, ""));
8
+ let mode = "code";
9
+ let model;
10
+ let keepSession = false;
11
+ let continueHandle;
12
+ let modelsOnly = false;
13
+ const rest = [];
14
+ for (let i = 0; i < cleaned.length; i++) {
15
+ const t = cleaned[i];
16
+ if (t === "models" && rest.length === 0 && i === cleaned.length - 1) {
17
+ modelsOnly = true;
18
+ continue;
19
+ }
20
+ if (t === "--keep-session") {
21
+ keepSession = true;
22
+ continue;
23
+ }
24
+ if (t === "--mode" && cleaned[i + 1]) {
25
+ const m = cleaned[++i];
26
+ if (m === "plan" || m === "challenge" || m === "code")
27
+ mode = m;
28
+ continue;
29
+ }
30
+ if (t === "--model" && cleaned[i + 1]) {
31
+ model = cleaned[++i];
32
+ continue;
33
+ }
34
+ if (t === "--continue" && cleaned[i + 1]) {
35
+ continueHandle = cleaned[++i];
36
+ continue;
37
+ }
38
+ rest.push(t);
39
+ }
40
+ return {
41
+ mode,
42
+ model,
43
+ keepSession,
44
+ continueHandle,
45
+ modelsOnly,
46
+ target: rest.join(" ").trim(),
47
+ };
48
+ }
49
+ function baseRules() {
50
+ return [
51
+ "Follow the pi-review skill.",
52
+ "Run pi-review in an isolated child session; return only the review conclusion.",
53
+ "Do not edit, patch, commit, or implement findings unless the user asks separately.",
54
+ "Preserve the final PI_REVIEW_META line from pi-review output.",
55
+ ].join(" ");
56
+ }
57
+ export function buildRvOrchestrationPrompt(parsed) {
58
+ if (parsed.modelsOnly) {
59
+ return [
60
+ "Run the pi-review model catalog step.",
61
+ baseRules(),
62
+ "Execute: pi-review models",
63
+ "Present a short English summary: how many providers, suggest 2–3 IDs suited for code review vs plan/challenge.",
64
+ "Do not start a review until the user supplies a target (@path or text).",
65
+ ].join("\n\n");
66
+ }
67
+ if (parsed.continueHandle) {
68
+ return [
69
+ "Continue a prior pi-review session.",
70
+ baseRules(),
71
+ `Execute: pi-review --continue ${parsed.continueHandle} -- ${parsed.target || "follow up on the previous review"}`,
72
+ "Answer the follow-up in English; keep the same review-only scope.",
73
+ ].join("\n\n");
74
+ }
75
+ if (!parsed.target) {
76
+ return [
77
+ "The /rv command needs a review target.",
78
+ "Tell the user (in English): usage is /rv [--mode code|plan|challenge] [--model provider/model] [--keep-session] -- @files-or-brief",
79
+ "Examples: /rv @src/foo.ts | /rv --mode challenge @docs/design.md | /rv models",
80
+ ].join("\n\n");
81
+ }
82
+ const modeBlock = {
83
+ code: [
84
+ "Mode: code (default).",
85
+ "Focus: correctness, regressions, security, concurrency, API contracts, edge cases, tests.",
86
+ "Use read-only inspection via pi-review; no file mutations.",
87
+ ].join(" "),
88
+ plan: [
89
+ "Mode: plan.",
90
+ "Review architecture, design, or strategy through engineering, product, security, QA, ops, and DX lenses.",
91
+ "Identify fatal flaws, trade-offs, sequencing risks, and minimal changes to de-risk the plan.",
92
+ ].join(" "),
93
+ challenge: [
94
+ "Mode: challenge (adversarial).",
95
+ "Pressure-test assumptions, boundaries, dependencies, failure modes, migration, and missing evidence.",
96
+ "One-shot conclusion; do not run a live Q&A interview.",
97
+ ].join(" "),
98
+ };
99
+ const cliParts = ["pi-review"];
100
+ if (parsed.mode !== "code")
101
+ cliParts.push(`--mode ${parsed.mode}`);
102
+ if (parsed.model)
103
+ cliParts.push(`--model ${parsed.model}`);
104
+ if (parsed.keepSession)
105
+ cliParts.push("--keep-session");
106
+ cliParts.push("--", parsed.target);
107
+ const modelStep = parsed.model
108
+ ? `Use model exactly as given: ${parsed.model} (must appear in pi-review models output).`
109
+ : "Run pi-review models first if needed; pick a suitable listed ID or omit --model for Pi default.";
110
+ return [
111
+ "Run pi-review for the target below.",
112
+ baseRules(),
113
+ modeBlock[parsed.mode],
114
+ modelStep,
115
+ parsed.keepSession
116
+ ? "Use --keep-session so the user can follow up with /rv --continue <handle>."
117
+ : "",
118
+ `Execute:\n${cliParts.join(" ")}`,
119
+ ]
120
+ .filter(Boolean)
121
+ .join("\n\n");
122
+ }
123
+ /** Short labels for TUI completions (English). */
124
+ export const RV_COMPLETIONS = [
125
+ { value: "@", hint: "file path after @ (e.g. @src/foo.ts)" },
126
+ { value: "models", hint: "list pi-review models only" },
127
+ { value: "--mode code", hint: "code / diff / MR review" },
128
+ { value: "--mode plan", hint: "architecture or plan review" },
129
+ { value: "--mode challenge", hint: "adversarial plan review" },
130
+ { value: "--model ", hint: "provider/model from pi-review models" },
131
+ { value: "--keep-session", hint: "persist session for follow-up" },
132
+ ];
package/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@ export { resolveConfig } from "./config.js";
3
3
  export type { Config } from "./config.js";
4
4
  export { loadPresets, loadPanelPresets, loadSystemPrompt } from "./presets.js";
5
5
  export { splitPayload, normalizePayloadRefs, buildPrompt, buildReviewerPrompt, buildAdjudicatorPrompt } from "./prompt.js";
6
- export { childEnv, childIsolationArgs, childRuntimeError, formatChildRuntimeDetail, readReviewStdin, runModels, runReview, runReviewOnce, CHILD_STDERR_DIAGNOSTIC_LIMIT, } from "./review.js";
7
- export { buildReviewerArgs, runPanelReview, runPanelReviewOnce, emitPanelFooter, shouldPreserveSubmissionOnAbort, resolvePanelReviewerTools, } from "./panel.js";
6
+ export { childEnv, childIsolationArgs, childRuntimeError, modelsArgs, configBlockForProvider, extensionOnlyHintText, formatChildRuntimeDetail, parseModelCatalog, probeProviderAvailability, readReviewStdin, runModels, runReview, runReviewOnce, unknownProviderHintText, CHILD_STDERR_DIAGNOSTIC_LIMIT, } from "./review.js";
7
+ export { buildReviewerArgs, collectPanelExtensionHints, runPanelReview, runPanelReviewOnce, emitPanelFooter, shouldPreserveSubmissionOnAbort, resolvePanelReviewerTools, } from "./panel.js";
8
8
  export { spawnStreamingChild } from "./child-process.js";
9
9
  export { createPanelViewState, reducePanelEvent } from "./panel-view.js";
10
10
  export type { PanelViewState, PanelReviewerView, PanelPhase, ReviewerViewStatus } from "./panel-view.js";
@@ -20,7 +20,7 @@ export type { FindingMatcher, MatchResult, SemanticAdjudicator, AdjudicationRequ
20
20
  export { resolvePanelConfig } from "./panel-config.js";
21
21
  export type { ResolvedPanelConfig } from "./panel-config.js";
22
22
  export { makeRunSessionDir, newestJsonl } from "./session.js";
23
- export type { Verdict, ReviewStatus, ReviewFinding, FindingLocation, ParsedArgs, ReviewPreset, VerdictInfo, StructuredReviewResult, ReviewMeta, ReviewRunResult, SplitPayload, ConsensusPolicy, SourceFinding, FindingCluster, PanelHealth, ReviewerOutcome, PanelFields, PanelAggregationResult, PanelReviewMeta, ReviewerSubmission, PanelReviewerSpec, PanelPreset, TokenUsage, } from "./types.js";
23
+ export type { Verdict, ReviewStatus, ReviewFinding, FindingLocation, ParsedArgs, ReviewPreset, VerdictInfo, StructuredReviewResult, ReviewMeta, ReviewRunResult, SplitPayload, ExtensionHint, ConsensusPolicy, SourceFinding, FindingCluster, PanelHealth, ReviewerOutcome, PanelFields, PanelAggregationResult, PanelReviewMeta, ReviewerSubmission, PanelReviewerSpec, PanelPreset, TokenUsage, } from "./types.js";
24
24
  export { REVIEW_STATUSES, VERDICTS, CONSENSUS_POLICIES, MAX_REVIEWERS, PANEL_READ_ONLY_TOOLS, DEFAULT_PANEL_MIN_AGREE, REVIEW_META_VERSION, } from "./types.js";
25
25
  export { fail, hasPathSeparator, expandMaybeHome, normalizeTools } from "./utils.js";
26
26
  export { parseVerdict } from "./verdict.js";
@@ -28,4 +28,6 @@ export { parseReviewResult, reviewExitCode } from "./review-result.js";
28
28
  export { formatCost, formatDurationMs, formatTokens, formatUsage, formatReviewMetaAscii, formatReviewMetaJsonLine, formatPanelMetaAscii, formatPanelFindingsMarkdown } from "./meta-footer.js";
29
29
  export { DEFAULT_AGENT_SKILL_ARGS, DEFAULT_SKILL_AGENTS, expandSkillAgentArgs, installSkill, listDirectSkillInstallTargets, resolveDirectSkillInstallTargets, runInstallSkill, runUninstallSkill, runUpdateSkill, selectedSkillAgents, uninstallSkill, } from "./skill.js";
30
30
  export type { DirectSkillInstallTarget, SkillMethod, SkillOpResult } from "./skill.js";
31
+ export { DEFAULT_CONFIG_PATH, configFilePath, currentConfig, loadReviewConfigFile, parseReviewConfig, resolveChildExtensions, } from "./pi-config.js";
32
+ export type { PiReviewConfig, ConfigSource, ChildExtensionsDecision, ReviewConfigLoad } from "./pi-config.js";
31
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ export { ArgsParseError, DEFAULT_MAX_ROUNDS, isPanelActive, parseArgs, parseRevi
2
2
  export { resolveConfig } from "./config.js";
3
3
  export { loadPresets, loadPanelPresets, loadSystemPrompt } from "./presets.js";
4
4
  export { splitPayload, normalizePayloadRefs, buildPrompt, buildReviewerPrompt, buildAdjudicatorPrompt } from "./prompt.js";
5
- export { childEnv, childIsolationArgs, childRuntimeError, formatChildRuntimeDetail, readReviewStdin, runModels, runReview, runReviewOnce, CHILD_STDERR_DIAGNOSTIC_LIMIT, } from "./review.js";
6
- export { buildReviewerArgs, runPanelReview, runPanelReviewOnce, emitPanelFooter, shouldPreserveSubmissionOnAbort, resolvePanelReviewerTools, } from "./panel.js";
5
+ export { childEnv, childIsolationArgs, childRuntimeError, modelsArgs, configBlockForProvider, extensionOnlyHintText, formatChildRuntimeDetail, parseModelCatalog, probeProviderAvailability, readReviewStdin, runModels, runReview, runReviewOnce, unknownProviderHintText, CHILD_STDERR_DIAGNOSTIC_LIMIT, } from "./review.js";
6
+ export { buildReviewerArgs, collectPanelExtensionHints, runPanelReview, runPanelReviewOnce, emitPanelFooter, shouldPreserveSubmissionOnAbort, resolvePanelReviewerTools, } from "./panel.js";
7
7
  export { spawnStreamingChild } from "./child-process.js";
8
8
  export { createPanelViewState, reducePanelEvent } from "./panel-view.js";
9
9
  export { createReviewEventEmitter, redactReviewEventPayload, redactReviewEventText, REVIEW_EVENT_VERSION, REVIEW_EVENT_TEXT_LIMIT } from "./review-events.js";
@@ -19,4 +19,5 @@ export { parseVerdict } from "./verdict.js";
19
19
  export { parseReviewResult, reviewExitCode } from "./review-result.js";
20
20
  export { formatCost, formatDurationMs, formatTokens, formatUsage, formatReviewMetaAscii, formatReviewMetaJsonLine, formatPanelMetaAscii, formatPanelFindingsMarkdown } from "./meta-footer.js";
21
21
  export { DEFAULT_AGENT_SKILL_ARGS, DEFAULT_SKILL_AGENTS, expandSkillAgentArgs, installSkill, listDirectSkillInstallTargets, resolveDirectSkillInstallTargets, runInstallSkill, runUninstallSkill, runUpdateSkill, selectedSkillAgents, uninstallSkill, } from "./skill.js";
22
+ export { DEFAULT_CONFIG_PATH, configFilePath, currentConfig, loadReviewConfigFile, parseReviewConfig, resolveChildExtensions, } from "./pi-config.js";
22
23
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACzI,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC3H,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EACf,SAAS,EACT,SAAS,EACT,aAAa,EACb,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,+BAA+B,EAC/B,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE9J,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AA0B9D,OAAO,EACL,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/L,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,6BAA6B,EAC7B,gCAAgC,EAChC,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACzI,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC3H,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,SAAS,EACT,SAAS,EACT,aAAa,EACb,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,+BAA+B,EAC/B,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE9J,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AA2B9D,OAAO,EACL,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/L,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,6BAA6B,EAC7B,gCAAgC,EAChC,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
@@ -36,6 +36,15 @@ function repoRoot() {
36
36
  function writeFakePi(tempDir) {
37
37
  const fakePi = path.join(tempDir, "fake-pi");
38
38
  fs.writeFileSync(fakePi, `#!/usr/bin/env node
39
+ if (process.argv.includes("--list-models")) {
40
+ // "configured" is available both with and without extensions; "extonly"
41
+ // only appears once host extensions are loaded (issue #8 probe fixture).
42
+ const isolated = process.argv.includes("--no-extensions");
43
+ const rows = ["provider model", "configured explicit-model"];
44
+ if (!isolated) rows.push("extonly anything");
45
+ process.stdout.write(rows.join("\\n") + "\\n");
46
+ process.exit(0);
47
+ }
39
48
  const prompt = process.argv[process.argv.length - 1] || "";
40
49
  const scenario = process.env.FAKE_PANEL_SCENARIO || "agree-bug";
41
50
  const idMatch = prompt.match(/Reviewer ID:\\s*(\\S+)/);
@@ -177,6 +186,32 @@ test("panel review keeps an explicitly configured reviewer model even when the p
177
186
  // The sentinel also reaches the human-readable ASCII footer Model line.
178
187
  assert.match(result.stdout, /Model\s+mixed/);
179
188
  });
189
+ test("panel review blocks extension-only providers with structured extensionHints (issue #8 probe)", () => {
190
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
191
+ const fakePi = writeFakePi(tempDir);
192
+ const result = runPanelCli(fakePi, "agree-bug", [
193
+ "--reviewers", "3",
194
+ "--consensus", "quorum", "--min-agree", "2",
195
+ "--reviewer-model", "r1=extonly/anything",
196
+ ]);
197
+ // A blocked reviewer leaves panel health blocked (exit 4) even though the
198
+ // healthy reviewers still ran; the remaining finding only reached advisory
199
+ // support (1 < quorum 2), so it cannot confirm.
200
+ assert.equal(result.status, 4, result.stderr);
201
+ const meta = metaRecord(result);
202
+ assert.ok(meta, result.stderr);
203
+ assert.equal(meta.panelHealth, "blocked");
204
+ const reviewerMetas = meta.reviewers;
205
+ const r1 = reviewerMetas.find((r) => r.reviewerId === "r1");
206
+ assert.equal(r1.verdictSource, "config_error");
207
+ assert.match(r1.parseError ?? "", /PI_REVIEW_CHILD_EXTENSIONS=1/);
208
+ // The machine-readable hint survives aggregation so the host agent can
209
+ // programmatically decide to re-run with PI_REVIEW_CHILD_EXTENSIONS=1.
210
+ assert.deepEqual(meta.extensionHints, [{ provider: "extonly", availableViaExtension: true }]);
211
+ // Healthy reviewers were not probed and still ran.
212
+ const r2 = reviewerMetas.find((r) => r.reviewerId === "r2");
213
+ assert.notEqual(r2.verdictSource, "config_error");
214
+ });
180
215
  test("panel review where all reviewers approve is clean and exits 0", () => {
181
216
  tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
182
217
  const fakePi = writeFakePi(tempDir);