@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.
- package/README.md +61 -4
- package/README.zh-CN.md +57 -2
- package/dist/child-isolation.test.js +25 -7
- package/dist/child-isolation.test.js.map +1 -1
- package/dist/cli.js +7 -0
- 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/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/panel-cli.test.js +35 -0
- package/dist/panel-cli.test.js.map +1 -1
- package/dist/panel-config.d.ts +7 -0
- package/dist/panel-config.d.ts.map +1 -1
- package/dist/panel-config.js +12 -0
- package/dist/panel-config.js.map +1 -1
- package/dist/panel.d.ts +7 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +44 -1
- package/dist/panel.js.map +1 -1
- package/dist/pi-config.d.ts +54 -0
- package/dist/pi-config.d.ts.map +1 -0
- package/dist/pi-config.js +87 -0
- package/dist/pi-config.js.map +1 -0
- package/dist/pi-config.test.d.ts +2 -0
- package/dist/pi-config.test.d.ts.map +1 -0
- package/dist/pi-config.test.js +78 -0
- package/dist/pi-config.test.js.map +1 -0
- package/dist/provider-probe.test.d.ts +2 -0
- package/dist/provider-probe.test.d.ts.map +1 -0
- package/dist/provider-probe.test.js +192 -0
- package/dist/provider-probe.test.js.map +1 -0
- package/dist/review.d.ts +58 -5
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +159 -9
- package/dist/review.js.map +1 -1
- package/dist/skill-protocol.test.js +13 -0
- package/dist/skill-protocol.test.js.map +1 -1
- package/dist/types.d.ts +25 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/extensions/review.test.ts +8 -0
- package/extensions/review.ts +11 -0
- package/extensions/rv-config.test.ts +90 -0
- package/extensions/rv-config.ts +150 -0
- package/extensions/rv-prompts.ts +1 -1
- package/package.json +1 -1
- package/resources/providers/orcarouter.json +28 -0
- package/skills/pi-review/SKILL.md +14 -1
- package/skills/pi-review/references/codex-tools.md +2 -0
- 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
|
+
[](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
|
-
|
|
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` |
|
|
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
|
-
-
|
|
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
|
+
[](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
|
-
|
|
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
|
-
-
|
|
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":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,EAClB,wBAAwB,
|
|
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":";AACA,OAAO,EAAE,aAAa,EAAuB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,IAAI,aAAa,CAAC,MAAM,CAAC;IAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAEpC,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;IACvC,SAAS,EAAE,CAAC;AACd,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;IACxC,UAAU,CAAC;QACT,EAAE,EAAE,MAAM,CAAC,SAAS,KAAK,KAAK;QAC9B,MAAM,EAAE,MAAM,CAAC,aAAa,KAAK,KAAK;QACtC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;KAClC,CAAC,CAAC;AACL,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;IAC9C,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,EAAE,CAAC;IAChD,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;KAAM,IAAI,MAAM,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QAClC,CAAC,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC7C,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,aAAa,CAChC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAU,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAClF,MAAM,CACP,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;KAAM,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;KAAM,CAAC;IACN,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/panel-cli.test.js
CHANGED
|
@@ -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);
|