@zephyrdeng/pi-review 0.7.0 → 0.8.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 (194) hide show
  1. package/README.md +51 -7
  2. package/README.zh-CN.md +45 -5
  3. package/dist/args.d.ts +4 -0
  4. package/dist/args.d.ts.map +1 -1
  5. package/dist/args.js +82 -5
  6. package/dist/args.js.map +1 -1
  7. package/dist/args.test.js +72 -1
  8. package/dist/args.test.js.map +1 -1
  9. package/dist/child-process.d.ts +6 -0
  10. package/dist/child-process.d.ts.map +1 -1
  11. package/dist/child-process.js +48 -0
  12. package/dist/child-process.js.map +1 -1
  13. package/dist/child-process.test.js +55 -1
  14. package/dist/child-process.test.js.map +1 -1
  15. package/dist/cli-exit.test.js +14 -5
  16. package/dist/cli-exit.test.js.map +1 -1
  17. package/dist/cli.js +8 -3
  18. package/dist/cli.js.map +1 -1
  19. package/dist/index.d.ts +13 -6
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +9 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/install-args.test.js +1 -1
  24. package/dist/install-args.test.js.map +1 -1
  25. package/dist/install.d.ts.map +1 -1
  26. package/dist/install.js +2 -3
  27. package/dist/install.js.map +1 -1
  28. package/dist/json-events.d.ts +34 -2
  29. package/dist/json-events.d.ts.map +1 -1
  30. package/dist/json-events.js +156 -49
  31. package/dist/json-events.js.map +1 -1
  32. package/dist/json-events.test.js +176 -4
  33. package/dist/json-events.test.js.map +1 -1
  34. package/dist/loop.d.ts +28 -2
  35. package/dist/loop.d.ts.map +1 -1
  36. package/dist/loop.js +45 -3
  37. package/dist/loop.js.map +1 -1
  38. package/dist/loop.test.js +24 -1
  39. package/dist/loop.test.js.map +1 -1
  40. package/dist/matcher.test.js +1 -1
  41. package/dist/matcher.test.js.map +1 -1
  42. package/dist/meta-footer.d.ts +4 -8
  43. package/dist/meta-footer.d.ts.map +1 -1
  44. package/dist/meta-footer.js +19 -5
  45. package/dist/meta-footer.js.map +1 -1
  46. package/dist/meta-footer.test.js +11 -4
  47. package/dist/meta-footer.test.js.map +1 -1
  48. package/dist/panel-aggregate.test.js +1 -1
  49. package/dist/panel-aggregate.test.js.map +1 -1
  50. package/dist/panel-cancellation.test.d.ts +2 -0
  51. package/dist/panel-cancellation.test.d.ts.map +1 -0
  52. package/dist/panel-cancellation.test.js +55 -0
  53. package/dist/panel-cancellation.test.js.map +1 -0
  54. package/dist/panel-cli-ui.test.d.ts +2 -0
  55. package/dist/panel-cli-ui.test.d.ts.map +1 -0
  56. package/dist/panel-cli-ui.test.js +91 -0
  57. package/dist/panel-cli-ui.test.js.map +1 -0
  58. package/dist/panel-cli.test.js +76 -27
  59. package/dist/panel-cli.test.js.map +1 -1
  60. package/dist/panel-config.d.ts +38 -0
  61. package/dist/panel-config.d.ts.map +1 -1
  62. package/dist/panel-config.js +137 -4
  63. package/dist/panel-config.js.map +1 -1
  64. package/dist/panel-config.test.js +84 -4
  65. package/dist/panel-config.test.js.map +1 -1
  66. package/dist/panel-loop.test.js +1 -1
  67. package/dist/panel-loop.test.js.map +1 -1
  68. package/dist/panel-tools.test.d.ts +2 -0
  69. package/dist/panel-tools.test.d.ts.map +1 -0
  70. package/dist/panel-tools.test.js +12 -0
  71. package/dist/panel-tools.test.js.map +1 -0
  72. package/dist/panel-ui.d.ts +20 -0
  73. package/dist/panel-ui.d.ts.map +1 -0
  74. package/dist/panel-ui.js +84 -0
  75. package/dist/panel-ui.js.map +1 -0
  76. package/dist/panel-ui.test.d.ts +2 -0
  77. package/dist/panel-ui.test.d.ts.map +1 -0
  78. package/dist/panel-ui.test.js +122 -0
  79. package/dist/panel-ui.test.js.map +1 -0
  80. package/dist/panel-usage.d.ts +6 -0
  81. package/dist/panel-usage.d.ts.map +1 -0
  82. package/dist/panel-usage.js +21 -0
  83. package/dist/panel-usage.js.map +1 -0
  84. package/dist/panel-view.d.ts +42 -0
  85. package/dist/panel-view.d.ts.map +1 -0
  86. package/dist/panel-view.js +124 -0
  87. package/dist/panel-view.js.map +1 -0
  88. package/dist/panel-view.test.d.ts +2 -0
  89. package/dist/panel-view.test.d.ts.map +1 -0
  90. package/dist/panel-view.test.js +112 -0
  91. package/dist/panel-view.test.js.map +1 -0
  92. package/dist/panel.d.ts +22 -2
  93. package/dist/panel.d.ts.map +1 -1
  94. package/dist/panel.js +184 -60
  95. package/dist/panel.js.map +1 -1
  96. package/dist/prompt.d.ts +2 -0
  97. package/dist/prompt.d.ts.map +1 -1
  98. package/dist/prompt.js +34 -3
  99. package/dist/prompt.js.map +1 -1
  100. package/dist/prompt.test.js +21 -2
  101. package/dist/prompt.test.js.map +1 -1
  102. package/dist/review-events.d.ts +70 -0
  103. package/dist/review-events.d.ts.map +1 -0
  104. package/dist/review-events.js +52 -0
  105. package/dist/review-events.js.map +1 -0
  106. package/dist/review-events.test.d.ts +2 -0
  107. package/dist/review-events.test.d.ts.map +1 -0
  108. package/dist/review-events.test.js +47 -0
  109. package/dist/review-events.test.js.map +1 -0
  110. package/dist/review-result.test.js +1 -1
  111. package/dist/review-result.test.js.map +1 -1
  112. package/dist/review.js +3 -3
  113. package/dist/review.js.map +1 -1
  114. package/dist/review.meta.test.js +1 -1
  115. package/dist/review.meta.test.js.map +1 -1
  116. package/dist/skill-protocol.test.js +1 -1
  117. package/dist/skill-protocol.test.js.map +1 -1
  118. package/dist/skill-update.test.d.ts +2 -0
  119. package/dist/skill-update.test.d.ts.map +1 -0
  120. package/dist/skill-update.test.js +23 -0
  121. package/dist/skill-update.test.js.map +1 -0
  122. package/dist/skill.d.ts +22 -0
  123. package/dist/skill.d.ts.map +1 -1
  124. package/dist/skill.js +109 -22
  125. package/dist/skill.js.map +1 -1
  126. package/dist/types.d.ts +28 -2
  127. package/dist/types.d.ts.map +1 -1
  128. package/dist/types.js +2 -0
  129. package/dist/types.js.map +1 -1
  130. package/dist/ui-client.d.ts +13 -0
  131. package/dist/ui-client.d.ts.map +1 -0
  132. package/dist/ui-client.js +161 -0
  133. package/dist/ui-client.js.map +1 -0
  134. package/dist/ui-client.test.d.ts +2 -0
  135. package/dist/ui-client.test.d.ts.map +1 -0
  136. package/dist/ui-client.test.js +48 -0
  137. package/dist/ui-client.test.js.map +1 -0
  138. package/dist/ui-html.d.ts +7 -0
  139. package/dist/ui-html.d.ts.map +1 -0
  140. package/dist/ui-html.js +52 -0
  141. package/dist/ui-html.js.map +1 -0
  142. package/dist/ui-html.test.d.ts +2 -0
  143. package/dist/ui-html.test.d.ts.map +1 -0
  144. package/dist/ui-html.test.js +26 -0
  145. package/dist/ui-html.test.js.map +1 -0
  146. package/dist/ui-server-main.d.ts +3 -0
  147. package/dist/ui-server-main.d.ts.map +1 -0
  148. package/dist/ui-server-main.js +128 -0
  149. package/dist/ui-server-main.js.map +1 -0
  150. package/dist/ui-server-main.test.d.ts +2 -0
  151. package/dist/ui-server-main.test.d.ts.map +1 -0
  152. package/dist/ui-server-main.test.js +123 -0
  153. package/dist/ui-server-main.test.js.map +1 -0
  154. package/dist/ui-server.d.ts +42 -0
  155. package/dist/ui-server.d.ts.map +1 -0
  156. package/dist/ui-server.js +233 -0
  157. package/dist/ui-server.js.map +1 -0
  158. package/dist/ui-server.test.d.ts +2 -0
  159. package/dist/ui-server.test.d.ts.map +1 -0
  160. package/dist/ui-server.test.js +236 -0
  161. package/dist/ui-server.test.js.map +1 -0
  162. package/dist/update.d.ts.map +1 -1
  163. package/dist/update.js +48 -19
  164. package/dist/update.js.map +1 -1
  165. package/extensions/panel-tool.test.ts +388 -0
  166. package/extensions/panel-tool.ts +390 -0
  167. package/extensions/review.test.ts +79 -0
  168. package/extensions/review.ts +191 -45
  169. package/extensions/rv-completions.test.ts +177 -18
  170. package/extensions/rv-completions.ts +490 -60
  171. package/extensions/rv-interactive.test.ts +562 -0
  172. package/extensions/rv-interactive.ts +616 -0
  173. package/extensions/rv-locale.test.ts +12 -4
  174. package/extensions/rv-locale.ts +44 -11
  175. package/extensions/rv-model-picker.test.ts +172 -0
  176. package/extensions/rv-model-picker.ts +313 -0
  177. package/extensions/rv-model-priorities.test.ts +29 -9
  178. package/extensions/rv-model-priorities.ts +23 -8
  179. package/extensions/rv-prompts.test.ts +281 -2
  180. package/extensions/rv-prompts.ts +480 -32
  181. package/extensions/rv-resolve.test.ts +189 -0
  182. package/extensions/rv-resolve.ts +313 -0
  183. package/extensions/rv-semantic.test.ts +1 -1
  184. package/extensions/rv-semantic.ts +38 -4
  185. package/package.json +18 -6
  186. package/resources/review-presets.json +2 -2
  187. package/resources/rv-model-priorities.json +18 -9
  188. package/skills/pi-review/SKILL.md +84 -60
  189. package/skills/pi-review/references/codex-tools.md +18 -11
  190. package/skills/pi-review/references/model-selection.md +49 -28
  191. package/dist/extensions/review.d.ts +0 -2
  192. package/dist/extensions/review.js +0 -22
  193. package/dist/extensions/rv-prompts.d.ts +0 -19
  194. package/dist/extensions/rv-prompts.js +0 -132
@@ -0,0 +1,55 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "vitest";
3
+ import { runPanelReviewOnce, shouldPreserveSubmissionOnAbort } from "./panel.js";
4
+ test("an already-aborted panel emits deterministic reviewer cancellations and one final event", async () => {
5
+ const controller = new AbortController();
6
+ controller.abort();
7
+ const events = [];
8
+ const parsed = {
9
+ command: "review",
10
+ mode: "code",
11
+ skills: [],
12
+ payload: ["@src"],
13
+ keepSession: false,
14
+ stream: true,
15
+ reviewers: 2,
16
+ };
17
+ const result = await runPanelReviewOnce(parsed, "", { signal: controller.signal, onEvent: (event) => events.push(event), emitFooter: false });
18
+ assert.equal(result.exitCode, 4);
19
+ assert.equal(result.meta.status, "blocked");
20
+ assert.equal(events.filter((event) => event.type === "reviewer.cancelled").length, 2);
21
+ assert.equal(events.filter((event) => event.type === "panel.completed").length, 1);
22
+ assert.equal(events.at(-1)?.type, "panel.completed");
23
+ });
24
+ test("panel abort preserves already-finished reviewer submissions instead of rewriting them as cancelled", () => {
25
+ const finished = {
26
+ reviewerId: "security",
27
+ role: "Security",
28
+ model: "openai/gpt",
29
+ durationMs: 1200,
30
+ result: {
31
+ status: "has_findings",
32
+ verdict: "request_changes",
33
+ verdictSource: "parsed",
34
+ findings: [{ summary: "Auth bypass", actionable: true }],
35
+ actionableCount: 1,
36
+ },
37
+ };
38
+ const interrupted = {
39
+ reviewerId: "correctness",
40
+ role: "Correctness",
41
+ model: "openai/gpt",
42
+ durationMs: 400,
43
+ result: {
44
+ status: "blocked",
45
+ verdict: "blocked",
46
+ verdictSource: "runtime_error",
47
+ parseError: "child pi terminated by signal SIGTERM",
48
+ findings: [],
49
+ actionableCount: 0,
50
+ },
51
+ };
52
+ assert.equal(shouldPreserveSubmissionOnAbort(finished), true);
53
+ assert.equal(shouldPreserveSubmissionOnAbort(interrupted), false);
54
+ });
55
+ //# sourceMappingURL=panel-cancellation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-cancellation.test.js","sourceRoot":"","sources":["../src/panel-cancellation.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAGjF,IAAI,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;IACzG,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,UAAU,CAAC,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAe;QACzB,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,WAAW,EAAE,KAAK;QAClB,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,CAAC;KACb,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9I,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oGAAoG,EAAE,GAAG,EAAE;IAC9G,MAAM,QAAQ,GAAuB;QACnC,UAAU,EAAE,UAAU;QACtB,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,YAAY;QACnB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE;YACN,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,iBAAiB;YAC1B,aAAa,EAAE,QAAQ;YACvB,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;YACxD,eAAe,EAAE,CAAC;SACnB;KACF,CAAC;IACF,MAAM,WAAW,GAAuB;QACtC,UAAU,EAAE,aAAa;QACzB,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,YAAY;QACnB,UAAU,EAAE,GAAG;QACf,MAAM,EAAE;YACN,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,SAAS;YAClB,aAAa,EAAE,eAAe;YAC9B,UAAU,EAAE,uCAAuC;YACnD,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,CAAC;SACnB;KACF,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=panel-cli-ui.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-cli-ui.test.d.ts","sourceRoot":"","sources":["../src/panel-cli-ui.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import assert from "node:assert/strict";
2
+ import fs from "node:fs";
3
+ import http from "node:http";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { execSync, spawnSync } from "node:child_process";
7
+ import { fileURLToPath } from "node:url";
8
+ import { test, afterEach } from "vitest";
9
+ // End-to-end coverage for the `--ui web` CLI wiring (args -> cli.ts dispatch
10
+ // -> panel-ui.ts launcher -> detached ui-server-main.js). Spawns the
11
+ // compiled dist/cli.js directly (not tsx-from-source) because the detached
12
+ // server reads its sibling static assets from its own compiled location;
13
+ // `npm test` builds first, run `npm run build` before this file standalone.
14
+ function distCliPath() {
15
+ return fileURLToPath(new URL("../dist/cli.js", import.meta.url));
16
+ }
17
+ function repoRoot() {
18
+ return path.dirname(fileURLToPath(new URL("../package.json", import.meta.url)));
19
+ }
20
+ function writeFakePi(tempDir) {
21
+ const fakePi = path.join(tempDir, "fake-pi");
22
+ fs.writeFileSync(fakePi, `#!/usr/bin/env node
23
+ function line(obj) { process.stdout.write(JSON.stringify(obj) + "\\n"); }
24
+ const text = "## Verdict\\napprove\\n\\n## Summary\\n- Fixture.\\n\\n## Findings\\nNo material findings.\\n\\n## Risks and Blind Spots\\nNone.\\n\\n## Open Questions\\nNone.\\n";
25
+ line({ type: "session", version: 3, id: "s1" });
26
+ line({ type: "agent_start" });
27
+ line({ type: "turn_start" });
28
+ line({ type: "message_start", message: { role: "user", content: [{ type: "text", text: "review" }] } });
29
+ line({ type: "message_end", message: { role: "user", content: [{ type: "text", text: "review" }] } });
30
+ line({ type: "message_start", message: { role: "assistant", content: [], model: "fake/model", usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 15 } } });
31
+ line({ type: "message_update", assistantMessageEvent: { type: "text_delta", delta: text, partial: { role: "assistant" } } });
32
+ line({ type: "message_end", message: { role: "assistant", content: [{ type: "text", text }], model: "fake/model", usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 15 }, stopReason: "stop" } });
33
+ line({ type: "turn_end", message: { role: "assistant", content: [{ type: "text", text }], usage: { input: 10, output: 5, totalTokens: 15 } } });
34
+ line({ type: "agent_end", messages: [{ role: "user", content: [{ type: "text", text: "review" }] }, { role: "assistant", content: [{ type: "text", text }], responseModel: "fake/model" }] });
35
+ process.exit(0);
36
+ `);
37
+ fs.chmodSync(fakePi, 0o755);
38
+ return fakePi;
39
+ }
40
+ function httpGet(port, requestPath) {
41
+ return new Promise((resolve, reject) => {
42
+ const req = http.request({ host: "127.0.0.1", port, path: requestPath, headers: { Host: `127.0.0.1:${port}` } }, (res) => {
43
+ let body = "";
44
+ res.on("data", (c) => (body += c));
45
+ res.on("end", () => resolve({ status: res.statusCode ?? 0, body }));
46
+ });
47
+ req.on("error", reject);
48
+ req.end();
49
+ });
50
+ }
51
+ let tempDir = "";
52
+ let dashboardPort;
53
+ afterEach(() => {
54
+ if (dashboardPort !== undefined) {
55
+ try {
56
+ const pid = execSync(`lsof -ti tcp:${dashboardPort} -sTCP:LISTEN`).toString().trim();
57
+ if (pid)
58
+ process.kill(Number(pid), "SIGTERM");
59
+ }
60
+ catch {
61
+ /* lsof unavailable or nothing listening anymore; best-effort cleanup only */
62
+ }
63
+ dashboardPort = undefined;
64
+ }
65
+ if (tempDir)
66
+ fs.rmSync(tempDir, { recursive: true, force: true });
67
+ tempDir = "";
68
+ });
69
+ test("pi-review --reviewers N --ui web prints a reachable dashboard URL and preserves the panel exit code", () => {
70
+ assert.ok(fs.existsSync(distCliPath()), "dist/cli.js is missing — run `npm run build` before this test");
71
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-ui-cli-"));
72
+ const fakePi = writeFakePi(tempDir);
73
+ const urlFile = path.join(tempDir, "url.txt");
74
+ const result = spawnSync(process.execPath, [distCliPath(), "--reviewers", "2", "--ui", "web", "--ui-url-file", urlFile, "--", "@src"], {
75
+ cwd: repoRoot(),
76
+ env: { ...process.env, PI_BIN: fakePi },
77
+ encoding: "utf8",
78
+ timeout: 30_000,
79
+ });
80
+ assert.equal(result.status, 0, result.stderr);
81
+ const urlLine = result.stderr.split("\n").find((line) => line.startsWith("PI_REVIEW_UI_URL: "));
82
+ assert.ok(urlLine, result.stderr);
83
+ const url = new URL(urlLine.slice("PI_REVIEW_UI_URL: ".length));
84
+ dashboardPort = Number(url.port);
85
+ assert.equal(fs.readFileSync(urlFile, "utf8").trim(), url.toString());
86
+ return httpGet(dashboardPort, url.pathname).then((page) => {
87
+ assert.equal(page.status, 200);
88
+ assert.match(page.body, /pi-review panel/);
89
+ });
90
+ }, 15_000);
91
+ //# sourceMappingURL=panel-cli-ui.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-cli-ui.test.js","sourceRoot":"","sources":["../src/panel-cli-ui.test.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,18 @@ import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { spawnSync } from "node:child_process";
6
6
  import { fileURLToPath } from "node:url";
7
- import { test } from "node:test";
7
+ import { test, afterEach } from "vitest";
8
+ let tempDir = "";
9
+ afterEach(() => {
10
+ if (tempDir)
11
+ fs.rmSync(tempDir, { recursive: true, force: true });
12
+ tempDir = "";
13
+ });
8
14
  function tsxLoaderArgs() {
15
+ // Reuse an already-loaded tsx loader when present (e.g. running tests via
16
+ // `npx tsx --test`), so we don't double-register. Under vitest the worker's
17
+ // execArgv has no tsx, so fall back to the project-local tsx package which
18
+ // Node resolves from node_modules via `--import tsx`.
9
19
  const args = [];
10
20
  for (let index = 0; index < process.execArgv.length - 1; index += 1) {
11
21
  const flag = process.execArgv[index];
@@ -15,7 +25,7 @@ function tsxLoaderArgs() {
15
25
  index += 1;
16
26
  }
17
27
  }
18
- return args;
28
+ return args.length ? args : ["--import", "tsx"];
19
29
  }
20
30
  function cliPath() {
21
31
  return fileURLToPath(new URL("./cli.ts", import.meta.url));
@@ -31,6 +41,7 @@ const scenario = process.env.FAKE_PANEL_SCENARIO || "agree-bug";
31
41
  const idMatch = prompt.match(/Reviewer ID:\\s*(\\S+)/);
32
42
  const reviewerId = idMatch ? idMatch[1] : "r1";
33
43
  const bug = "### F1: Off-by-one in loop\\n- Severity: high\\n- Path: src/cli.ts\\n- Actionable: yes\\n- Evidence: x\\n- Impact: y\\n- Recommendation: z";
44
+ const longBug = "### F1: " + "x".repeat(700) + "\\n- Severity: high\\n- Path: src/cli.ts\\n- Actionable: yes\\n- Evidence: x\\n- Impact: y\\n- Recommendation: z";
34
45
  function emit(text) {
35
46
  function line(obj) { process.stdout.write(JSON.stringify(obj) + "\\n"); }
36
47
  line({ type: "session", version: 3, id: "s1" });
@@ -54,6 +65,8 @@ if (scenario === "agree-bug") {
54
65
  else out("approve", "No material findings.");
55
66
  } else if (scenario === "all-clean") {
56
67
  out("approve", "No material findings.");
68
+ } else if (scenario === "long-finding") {
69
+ out("request_changes", longBug);
57
70
  } else if (scenario === "singleton") {
58
71
  if (reviewerId === "r1" || reviewerId === "correctness") out("request_changes", bug);
59
72
  else out("approve", "No material findings.");
@@ -78,9 +91,8 @@ function metaRecord(result) {
78
91
  return undefined;
79
92
  return JSON.parse(metaLine.slice("PI_REVIEW_META_JSON: ".length));
80
93
  }
81
- test("panel review with two corroborating reviewers confirms one finding and exits 1", (t) => {
82
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
83
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
94
+ test("panel review with two corroborating reviewers confirms one finding and exits 1", () => {
95
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
84
96
  const fakePi = writeFakePi(tempDir);
85
97
  const result = runPanelCli(fakePi, "agree-bug", ["--reviewers", "3", "--consensus", "quorum", "--min-agree", "2"]);
86
98
  assert.equal(result.error, undefined);
@@ -97,9 +109,8 @@ test("panel review with two corroborating reviewers confirms one finding and exi
97
109
  assert.equal(meta.reviewers.length, 3);
98
110
  assert.equal(meta.confirmedClusters[0].supportCount, 2);
99
111
  });
100
- test("panel review where all reviewers approve is clean and exits 0", (t) => {
101
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
102
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
112
+ test("panel review where all reviewers approve is clean and exits 0", () => {
113
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
103
114
  const fakePi = writeFakePi(tempDir);
104
115
  const result = runPanelCli(fakePi, "all-clean", ["--reviewers", "3"]);
105
116
  assert.equal(result.status, 0, result.stderr);
@@ -109,9 +120,8 @@ test("panel review where all reviewers approve is clean and exits 0", (t) => {
109
120
  assert.equal(meta.confirmedClusters.length, 0);
110
121
  assert.equal(meta.advisories.length, 0);
111
122
  });
112
- test("panel review with a singleton finding keeps it advisory and stays clean under quorum", (t) => {
113
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
114
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
123
+ test("panel review with a singleton finding keeps it advisory and stays clean under quorum", () => {
124
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
115
125
  const fakePi = writeFakePi(tempDir);
116
126
  const result = runPanelCli(fakePi, "singleton", ["--reviewers", "3", "--consensus", "quorum", "--min-agree", "2"]);
117
127
  assert.equal(result.status, 0, result.stderr);
@@ -122,9 +132,8 @@ test("panel review with a singleton finding keeps it advisory and stays clean un
122
132
  assert.equal(meta.advisories.length, 1);
123
133
  assert.equal(meta.advisories[0].supportCount, 1);
124
134
  });
125
- test("panel review with a reviewer runtime failure is blocked and exits 4", (t) => {
126
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
127
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
135
+ test("panel review with a reviewer runtime failure is blocked and exits 4", () => {
136
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
128
137
  const fakePi = writeFakePi(tempDir);
129
138
  const result = runPanelCli(fakePi, "runtime-fail", ["--reviewers", "3"]);
130
139
  assert.equal(result.status, 4, result.stderr);
@@ -134,9 +143,8 @@ test("panel review with a reviewer runtime failure is blocked and exits 4", (t)
134
143
  assert.equal(meta.panelHealth, "blocked");
135
144
  assert.equal(meta.confirmedClusters.length, 0);
136
145
  });
137
- test("panel review emits exactly one aggregate metadata record", (t) => {
138
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
139
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
146
+ test("panel review emits exactly one aggregate metadata record", () => {
147
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
140
148
  const fakePi = writeFakePi(tempDir);
141
149
  const result = runPanelCli(fakePi, "agree-bug", ["--reviewers", "3"]);
142
150
  const allLines = [...result.stderr.split("\n"), ...result.stdout.split("\n")];
@@ -144,24 +152,22 @@ test("panel review emits exactly one aggregate metadata record", (t) => {
144
152
  assert.equal(metaLines.length, 1, `expected one aggregate meta record, got ${metaLines.length}`);
145
153
  });
146
154
  test("panel rejects session reuse flags with usage exit 2", () => {
147
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
155
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
148
156
  fs.rmSync(tempDir, { recursive: true, force: true });
149
157
  const result = runPanelCli("pi", "agree-bug", ["--reviewers", "3", "--keep-session"]);
150
158
  assert.equal(result.status, 2);
151
159
  assert.match(result.stderr, /panel cannot be used with/);
152
160
  });
153
- test("panel loop runs one full panel per round and reports a panel summary", (t) => {
154
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
155
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
161
+ test("panel loop runs one full panel per round and reports a panel summary", () => {
162
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
156
163
  const fakePi = writeFakePi(tempDir);
157
164
  const result = spawnSync(process.execPath, [...tsxLoaderArgs(), cliPath(), "loop", "--reviewers", "3", "--max-rounds", "1", "--", "@src"], { cwd: repoRoot(), env: { ...process.env, PI_BIN: fakePi, FAKE_PANEL_SCENARIO: "agree-bug" }, encoding: "utf8", timeout: 30_000 });
158
165
  assert.equal(result.status, 1, result.stderr);
159
166
  assert.match(result.stdout, /pi-review loop/);
160
167
  assert.match(result.stdout, /panel 3\/3/);
161
168
  });
162
- test("named panel preset propagates panelPreset to metadata and output", (t) => {
163
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
164
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
169
+ test("named panel preset propagates panelPreset to metadata and output", () => {
170
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
165
171
  const fakePi = writeFakePi(tempDir);
166
172
  const result = runPanelCli(fakePi, "agree-bug", ["--panel", "code-experts", "--consensus", "quorum", "--min-agree", "2"]);
167
173
  assert.equal(result.status, 1, result.stderr);
@@ -175,9 +181,8 @@ test("named panel preset propagates panelPreset to metadata and output", (t) =>
175
181
  assert.equal(meta.confirmedClusters[0].supportCount, 2);
176
182
  assert.match(result.stdout, /Panel\s+code-experts/);
177
183
  });
178
- test("named panel preset reviewer ids appear in supporting reviewer ids", (t) => {
179
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
180
- t.after(() => fs.rmSync(tempDir, { recursive: true, force: true }));
184
+ test("named panel preset reviewer ids appear in supporting reviewer ids", () => {
185
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
181
186
  const fakePi = writeFakePi(tempDir);
182
187
  const result = runPanelCli(fakePi, "agree-bug", ["--panel", "code-experts", "--consensus", "quorum", "--min-agree", "2"]);
183
188
  const meta = metaRecord(result);
@@ -185,4 +190,48 @@ test("named panel preset reviewer ids appear in supporting reviewer ids", (t) =>
185
190
  const cluster = meta.confirmedClusters[0];
186
191
  assert.deepEqual(cluster.supportingReviewerIds.sort(), ["correctness", "security"]);
187
192
  });
193
+ test("panel events-jsonl emits only normalized lifecycle events and carries the final metadata", () => {
194
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
195
+ const fakePi = writeFakePi(tempDir);
196
+ const result = runPanelCli(fakePi, "agree-bug", ["--reviewers", "3", "--output-format", "events-jsonl"]);
197
+ assert.equal(result.status, 1, result.stderr);
198
+ const events = result.stdout.trim().split("\n").map((line) => JSON.parse(line));
199
+ assert.equal(events[0]?.type, "panel.started");
200
+ assert.deepEqual(events.map((event) => event.seq), events.map((_, index) => index + 1));
201
+ assert.equal(events.at(-1)?.type, "panel.completed");
202
+ assert.equal(events.at(-1)?.meta?.status, "has_findings");
203
+ assert.doesNotMatch(result.stdout, /PI_REVIEW_META_JSON|── pi-review/);
204
+ });
205
+ test("panel events-jsonl keeps the default CLI gate metadata semantics", () => {
206
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
207
+ const fakePi = writeFakePi(tempDir);
208
+ const args = ["--reviewers", "3", "--consensus", "quorum", "--min-agree", "2"];
209
+ const human = runPanelCli(fakePi, "agree-bug", args);
210
+ const eventStream = runPanelCli(fakePi, "agree-bug", [...args, "--output-format", "events-jsonl"]);
211
+ const humanMeta = metaRecord(human);
212
+ const eventMeta = JSON.parse(eventStream.stdout.trim().split("\n").at(-1)).meta;
213
+ assert.equal(eventStream.status, human.status);
214
+ assert.equal(eventMeta.status, humanMeta.status);
215
+ assert.deepEqual(eventMeta.confirmedClusters, humanMeta.confirmedClusters);
216
+ assert.deepEqual(eventMeta.advisories, humanMeta.advisories);
217
+ assert.equal(eventMeta.panelHealth, humanMeta.panelHealth);
218
+ });
219
+ test("panel keeps full redacted findings for the CLI while bounding renderer events", () => {
220
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
221
+ const fakePi = writeFakePi(tempDir);
222
+ const args = ["--reviewers", "2", "--consensus", "quorum", "--min-agree", "2"];
223
+ const human = runPanelCli(fakePi, "long-finding", args);
224
+ const events = runPanelCli(fakePi, "long-finding", [...args, "--output-format", "events-jsonl"]);
225
+ assert.match(human.stdout, /x{700}/);
226
+ const completed = JSON.parse(events.stdout.trim().split("\n").at(-1));
227
+ assert.ok(completed.meta.confirmedClusters[0].summary.length <= 512);
228
+ });
229
+ test("panel rejects disallowed tools before writing a partial event stream", () => {
230
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-review-panel-cli-"));
231
+ const fakePi = writeFakePi(tempDir);
232
+ const result = runPanelCli(fakePi, "agree-bug", ["--reviewers", "2", "--tools", "bash", "--output-format", "events-jsonl"]);
233
+ assert.equal(result.status, 2);
234
+ assert.equal(result.stdout, "");
235
+ assert.match(result.stderr, /panel reviewers only allow/);
236
+ });
188
237
  //# sourceMappingURL=panel-cli.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"panel-cli.test.js","sourceRoot":"","sources":["../src/panel-cli.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"panel-cli.test.js","sourceRoot":"","sources":["../src/panel-cli.test.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,44 @@ export interface ResolvedPanelConfig {
10
10
  /** True when a consensus model enables semantic adjudication. */
11
11
  semanticEnabled: boolean;
12
12
  }
13
+ /**
14
+ * Pick `count` distinct-looking roles from the persona pool.
15
+ * Shuffles each call so successive runs don't always show the same order;
16
+ * when count > pool size, suffixes with 2/3… to keep labels unique.
17
+ */
18
+ export declare function assignGenericReviewerRoles(count: number): string[];
19
+ /**
20
+ * Split a trailing `:thinking` suffix from a model token.
21
+ * Preserves provider colons such as `px:openai/agnes-2.0-flash:low` →
22
+ * model=`px:openai/agnes-2.0-flash`, thinking=`low`.
23
+ */
24
+ export declare function splitModelThinking(value: string): {
25
+ model: string;
26
+ thinking?: string;
27
+ };
28
+ export type ReviewerModelOverride = {
29
+ model: string;
30
+ thinking?: string;
31
+ };
32
+ /** Parse `id=provider/model[:thinking]` overrides; last write wins for duplicate ids. */
33
+ export declare function parseReviewerModelOverrides(values: string[] | undefined): Map<string, ReviewerModelOverride>;
34
+ /**
35
+ * Resolve the effective model + thinking for a reviewer.
36
+ * - Strips a trailing `:thinking` suffix from the model token (so display and
37
+ * child args never show `model:low · high`).
38
+ * - Preference: per-reviewer thinking field → `:suffix` on per-reviewer model →
39
+ * shared thinking → `:suffix` on shared model.
40
+ */
41
+ export declare function resolveReviewerModelThinking(reviewer: {
42
+ model?: string;
43
+ thinking?: string;
44
+ }, shared?: {
45
+ model?: string;
46
+ thinking?: string;
47
+ }): {
48
+ model?: string;
49
+ thinking?: string;
50
+ };
13
51
  /**
14
52
  * Resolve a panel configuration. `panelPresets` is supplied by the caller (the
15
53
  * orchestrator loads the file), so this function stays pure and testable with
@@ -1 +1 @@
1
- {"version":3,"file":"panel-config.d.ts","sourceRoot":"","sources":["../src/panel-config.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAUD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACxC,mBAAmB,CAiHrB"}
1
+ {"version":3,"file":"panel-config.d.ts","sourceRoot":"","sources":["../src/panel-config.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,eAAe,EAAE,OAAO,CAAC;CAC1B;AA6CD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAalE;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAOtF;AAED,MAAM,MAAM,qBAAqB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAe5G;AA2BD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/C,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAcvC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACxC,mBAAmB,CAuHrB"}
@@ -11,6 +11,134 @@ function isPolicy(value) {
11
11
  function defaultMinAgree(policy) {
12
12
  return policy === "quorum" ? DEFAULT_PANEL_MIN_AGREE : undefined;
13
13
  }
14
+ /**
15
+ * Persona labels for anonymous `--reviewers N` panels.
16
+ * Mix of rappers, AI-circle KOLs, and sports stars — distinct at a glance,
17
+ * shuffled per run so successive panels don't always look the same.
18
+ */
19
+ const GENERIC_REVIEWER_ROLES = [
20
+ // Rappers
21
+ "Kendrick Lamar",
22
+ "Drake",
23
+ "J. Cole",
24
+ "Travis Scott",
25
+ "Eminem",
26
+ "Nas",
27
+ "Jay-Z",
28
+ "Tyler, the Creator",
29
+ // AI KOLs
30
+ "Andrej Karpathy",
31
+ "Sam Altman",
32
+ "Demis Hassabis",
33
+ "Yann LeCun",
34
+ "Fei-Fei Li",
35
+ "Andrew Ng",
36
+ "Ilya Sutskever",
37
+ "Jim Fan",
38
+ // Sports stars
39
+ "LeBron James",
40
+ "Stephen Curry",
41
+ "Lionel Messi",
42
+ "Cristiano Ronaldo",
43
+ "Kobe Bryant",
44
+ "Serena Williams",
45
+ "Yao Ming",
46
+ "Shohei Ohtani",
47
+ ];
48
+ /**
49
+ * Pick `count` distinct-looking roles from the persona pool.
50
+ * Shuffles each call so successive runs don't always show the same order;
51
+ * when count > pool size, suffixes with 2/3… to keep labels unique.
52
+ */
53
+ export function assignGenericReviewerRoles(count) {
54
+ const pool = [...GENERIC_REVIEWER_ROLES];
55
+ for (let i = pool.length - 1; i > 0; i--) {
56
+ const j = Math.floor(Math.random() * (i + 1));
57
+ const a = pool[i];
58
+ pool[i] = pool[j];
59
+ pool[j] = a;
60
+ }
61
+ return Array.from({ length: count }, (_, index) => {
62
+ const base = pool[index % pool.length];
63
+ const cycle = Math.floor(index / pool.length);
64
+ return cycle === 0 ? base : `${base} ${cycle + 1}`;
65
+ });
66
+ }
67
+ const THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
68
+ /**
69
+ * Split a trailing `:thinking` suffix from a model token.
70
+ * Preserves provider colons such as `px:openai/agnes-2.0-flash:low` →
71
+ * model=`px:openai/agnes-2.0-flash`, thinking=`low`.
72
+ */
73
+ export function splitModelThinking(value) {
74
+ const idx = value.lastIndexOf(":");
75
+ if (idx <= 0)
76
+ return { model: value };
77
+ const after = value.slice(idx + 1).trim().toLowerCase();
78
+ // Thinking suffixes are bare levels, never path-like fragments containing `/`.
79
+ if (!after || after.includes("/") || !THINKING_LEVELS.has(after))
80
+ return { model: value };
81
+ return { model: value.slice(0, idx), thinking: after };
82
+ }
83
+ /** Parse `id=provider/model[:thinking]` overrides; last write wins for duplicate ids. */
84
+ export function parseReviewerModelOverrides(values) {
85
+ const map = new Map();
86
+ for (const raw of values ?? []) {
87
+ const eq = raw.indexOf("=");
88
+ if (eq <= 0 || eq === raw.length - 1) {
89
+ throw new ArgsParseError(`--reviewer-model must look like id=provider/model[:thinking]; got ${raw}`);
90
+ }
91
+ const id = raw.slice(0, eq).trim();
92
+ const token = raw.slice(eq + 1).trim();
93
+ if (!/^[A-Za-z0-9_.-]+$/.test(id) || !token) {
94
+ throw new ArgsParseError(`--reviewer-model must look like id=provider/model[:thinking]; got ${raw}`);
95
+ }
96
+ map.set(id, splitModelThinking(token));
97
+ }
98
+ return map;
99
+ }
100
+ function applyReviewerModelOverrides(reviewers, overrides) {
101
+ if (overrides.size === 0)
102
+ return reviewers;
103
+ const known = new Set(reviewers.map((reviewer) => reviewer.id));
104
+ for (const id of overrides.keys()) {
105
+ if (!known.has(id)) {
106
+ throw new ArgsParseError(`--reviewer-model unknown reviewer id "${id}"; expected one of ${[...known].join(", ")}`);
107
+ }
108
+ }
109
+ return reviewers.map((reviewer) => {
110
+ const override = overrides.get(reviewer.id);
111
+ if (!override)
112
+ return reviewer;
113
+ // Per-reviewer :thinking must win over shared --thinking / preset thinking.
114
+ return {
115
+ ...reviewer,
116
+ model: override.model,
117
+ ...(override.thinking ? { thinking: override.thinking } : {}),
118
+ };
119
+ });
120
+ }
121
+ /**
122
+ * Resolve the effective model + thinking for a reviewer.
123
+ * - Strips a trailing `:thinking` suffix from the model token (so display and
124
+ * child args never show `model:low · high`).
125
+ * - Preference: per-reviewer thinking field → `:suffix` on per-reviewer model →
126
+ * shared thinking → `:suffix` on shared model.
127
+ */
128
+ export function resolveReviewerModelThinking(reviewer, shared = {}) {
129
+ const raw = reviewer.model ?? shared.model;
130
+ const fromRaw = raw ? splitModelThinking(raw) : {};
131
+ const fromReviewerModel = reviewer.model ? splitModelThinking(reviewer.model) : {};
132
+ const fromSharedModel = !reviewer.model && shared.model ? splitModelThinking(shared.model) : {};
133
+ const thinking = reviewer.thinking ??
134
+ fromReviewerModel.thinking ??
135
+ shared.thinking ??
136
+ fromSharedModel.thinking;
137
+ return {
138
+ ...(fromRaw.model ? { model: fromRaw.model } : {}),
139
+ ...(thinking ? { thinking } : {}),
140
+ };
141
+ }
14
142
  /**
15
143
  * Resolve a panel configuration. `panelPresets` is supplied by the caller (the
16
144
  * orchestrator loads the file), so this function stays pure and testable with
@@ -33,8 +161,8 @@ export function resolvePanelConfig(parsed, panelPresets) {
33
161
  if (!preset) {
34
162
  throw new ArgsParseError(`unknown panel preset: ${parsed.panel}. Available: ${Object.keys(panelPresets).join(", ") || "(none)"}`);
35
163
  }
36
- if (!Array.isArray(preset.reviewers) || preset.reviewers.length < 1) {
37
- throw new ArgsParseError(`panel preset ${parsed.panel} must define at least one reviewer`);
164
+ if (!Array.isArray(preset.reviewers) || preset.reviewers.length < 2) {
165
+ throw new ArgsParseError(`panel preset ${parsed.panel} must define at least two reviewers`);
38
166
  }
39
167
  if (preset.reviewers.length > MAX_REVIEWERS) {
40
168
  throw new ArgsParseError(`panel preset ${parsed.panel} defines ${preset.reviewers.length} reviewers (max ${MAX_REVIEWERS})`);
@@ -72,17 +200,22 @@ export function resolvePanelConfig(parsed, panelPresets) {
72
200
  concurrency = parsed.concurrency ?? preset.concurrency;
73
201
  }
74
202
  else {
75
- // Generic same-model panel: --reviewers N (parser guarantees N in 2..MAX).
203
+ // Generic panel: --reviewers N (parser guarantees N in 2..MAX). Shared
204
+ // --model is the default; --reviewer-model rK=... overrides individuals.
205
+ // Roles are distinct persona names (not all "Independent reviewer") so the
206
+ // live panel / dashboard can tell reviewers apart at a glance.
76
207
  const count = parsed.reviewers;
208
+ const roles = assignGenericReviewerRoles(count);
77
209
  reviewers = Array.from({ length: count }, (_, index) => ({
78
210
  id: `r${index + 1}`,
79
- role: "Independent reviewer",
211
+ role: roles[index],
80
212
  }));
81
213
  consensus = (explicitConsensus ?? "quorum");
82
214
  minAgree = parsed.minAgree ?? defaultMinAgree(consensus);
83
215
  consensusModel = parsed.consensusModel;
84
216
  concurrency = parsed.concurrency;
85
217
  }
218
+ reviewers = applyReviewerModelOverrides(reviewers, parseReviewerModelOverrides(parsed.reviewerModels));
86
219
  if (minAgree !== undefined) {
87
220
  if (!Number.isSafeInteger(minAgree) || minAgree < 1) {
88
221
  throw new ArgsParseError("--min-agree must be a positive integer");