@zephyrdeng/pi-review 0.6.2 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -14
- package/README.zh-CN.md +79 -4
- package/dist/args.d.ts +8 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +167 -28
- package/dist/args.js.map +1 -1
- package/dist/args.test.d.ts +2 -0
- package/dist/args.test.d.ts.map +1 -0
- package/dist/args.test.js +125 -0
- package/dist/args.test.js.map +1 -0
- package/dist/child-process.d.ts +3 -0
- package/dist/child-process.d.ts.map +1 -1
- package/dist/child-process.js +26 -0
- package/dist/child-process.js.map +1 -1
- package/dist/child-process.test.js +13 -0
- package/dist/child-process.test.js.map +1 -1
- package/dist/cli-exit.test.d.ts +2 -0
- package/dist/cli-exit.test.d.ts.map +1 -0
- package/dist/cli-exit.test.js +84 -0
- package/dist/cli-exit.test.js.map +1 -0
- package/dist/cli.js +16 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.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 +22 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -6
- package/dist/index.js.map +1 -1
- package/dist/json-events.d.ts +71 -0
- package/dist/json-events.d.ts.map +1 -1
- package/dist/json-events.js +250 -0
- package/dist/json-events.js.map +1 -1
- package/dist/json-events.test.js +217 -1
- package/dist/json-events.test.js.map +1 -1
- package/dist/loop.d.ts +36 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +73 -0
- package/dist/loop.js.map +1 -0
- package/dist/loop.test.d.ts +2 -0
- package/dist/loop.test.d.ts.map +1 -0
- package/dist/loop.test.js +83 -0
- package/dist/loop.test.js.map +1 -0
- package/dist/matcher.d.ts +74 -0
- package/dist/matcher.d.ts.map +1 -0
- package/dist/matcher.js +202 -0
- package/dist/matcher.js.map +1 -0
- package/dist/matcher.test.d.ts +2 -0
- package/dist/matcher.test.d.ts.map +1 -0
- package/dist/matcher.test.js +161 -0
- package/dist/matcher.test.js.map +1 -0
- package/dist/meta-footer.d.ts +15 -1
- package/dist/meta-footer.d.ts.map +1 -1
- package/dist/meta-footer.js +108 -0
- package/dist/meta-footer.js.map +1 -1
- package/dist/meta-footer.test.js +43 -1
- package/dist/meta-footer.test.js.map +1 -1
- package/dist/panel-aggregate.d.ts +18 -0
- package/dist/panel-aggregate.d.ts.map +1 -0
- package/dist/panel-aggregate.js +247 -0
- package/dist/panel-aggregate.js.map +1 -0
- package/dist/panel-aggregate.test.d.ts +2 -0
- package/dist/panel-aggregate.test.d.ts.map +1 -0
- package/dist/panel-aggregate.test.js +461 -0
- package/dist/panel-aggregate.test.js.map +1 -0
- package/dist/panel-cancellation.test.d.ts +2 -0
- package/dist/panel-cancellation.test.d.ts.map +1 -0
- package/dist/panel-cancellation.test.js +24 -0
- package/dist/panel-cancellation.test.js.map +1 -0
- package/dist/panel-cli.test.d.ts +2 -0
- package/dist/panel-cli.test.d.ts.map +1 -0
- package/dist/panel-cli.test.js +239 -0
- package/dist/panel-cli.test.js.map +1 -0
- package/dist/panel-config.d.ts +19 -0
- package/dist/panel-config.d.ts.map +1 -0
- package/dist/panel-config.js +115 -0
- package/dist/panel-config.js.map +1 -0
- package/dist/panel-config.test.d.ts +2 -0
- package/dist/panel-config.test.d.ts.map +1 -0
- package/dist/panel-config.test.js +94 -0
- package/dist/panel-config.test.js.map +1 -0
- package/dist/panel-loop.test.d.ts +2 -0
- package/dist/panel-loop.test.d.ts.map +1 -0
- package/dist/panel-loop.test.js +118 -0
- package/dist/panel-loop.test.js.map +1 -0
- package/dist/panel-tools.test.d.ts +2 -0
- package/dist/panel-tools.test.d.ts.map +1 -0
- package/dist/panel-tools.test.js +12 -0
- package/dist/panel-tools.test.js.map +1 -0
- package/dist/panel-usage.d.ts +6 -0
- package/dist/panel-usage.d.ts.map +1 -0
- package/dist/panel-usage.js +21 -0
- package/dist/panel-usage.js.map +1 -0
- package/dist/panel-view.d.ts +41 -0
- package/dist/panel-view.d.ts.map +1 -0
- package/dist/panel-view.js +90 -0
- package/dist/panel-view.js.map +1 -0
- package/dist/panel-view.test.d.ts +2 -0
- package/dist/panel-view.test.d.ts.map +1 -0
- package/dist/panel-view.test.js +45 -0
- package/dist/panel-view.test.js.map +1 -0
- package/dist/panel.d.ts +20 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +393 -0
- package/dist/panel.js.map +1 -0
- package/dist/presets.d.ts +2 -1
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +10 -0
- package/dist/presets.js.map +1 -1
- package/dist/prompt.d.ts +14 -1
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +61 -15
- package/dist/prompt.js.map +1 -1
- package/dist/prompt.test.d.ts +2 -0
- package/dist/prompt.test.d.ts.map +1 -0
- package/dist/prompt.test.js +37 -0
- package/dist/prompt.test.js.map +1 -0
- package/dist/review-events.d.ts +70 -0
- package/dist/review-events.d.ts.map +1 -0
- package/dist/review-events.js +52 -0
- package/dist/review-events.js.map +1 -0
- package/dist/review-events.test.d.ts +2 -0
- package/dist/review-events.test.d.ts.map +1 -0
- package/dist/review-events.test.js +47 -0
- package/dist/review-events.test.js.map +1 -0
- package/dist/review-result.d.ts +5 -0
- package/dist/review-result.d.ts.map +1 -0
- package/dist/review-result.js +98 -0
- package/dist/review-result.js.map +1 -0
- package/dist/review-result.test.d.ts +2 -0
- package/dist/review-result.test.d.ts.map +1 -0
- package/dist/review-result.test.js +196 -0
- package/dist/review-result.test.js.map +1 -0
- package/dist/review.d.ts +10 -4
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +82 -20
- package/dist/review.js.map +1 -1
- package/dist/review.meta.test.js +2 -2
- package/dist/review.meta.test.js.map +1 -1
- package/dist/skill-protocol.test.d.ts +2 -0
- package/dist/skill-protocol.test.d.ts.map +1 -0
- package/dist/skill-protocol.test.js +35 -0
- package/dist/skill-protocol.test.js.map +1 -0
- package/dist/types.d.ts +151 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -1
- package/extensions/panel-tool.test.ts +30 -0
- package/extensions/panel-tool.ts +169 -0
- package/extensions/review.ts +3 -1
- package/extensions/rv-prompts.test.ts +8 -1
- package/extensions/rv-prompts.ts +6 -4
- package/package.json +14 -5
- package/resources/panel-presets.json +21 -0
- package/resources/review-presets.json +2 -2
- package/resources/system-prompt.md +11 -1
- package/skills/pi-review/SKILL.md +93 -15
- package/skills/pi-review/references/codex-tools.md +19 -6
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { formatLoopSummary, runReviewLoop } from "./loop.js";
|
|
4
|
+
function cluster(summary, opts = {}) {
|
|
5
|
+
const support = opts.support ?? 1;
|
|
6
|
+
return {
|
|
7
|
+
id: "C1",
|
|
8
|
+
summary,
|
|
9
|
+
confirmed: opts.confirmed ?? false,
|
|
10
|
+
supportCount: support,
|
|
11
|
+
actionableSupportCount: opts.actionableSupport ?? support,
|
|
12
|
+
supportingReviewerIds: opts.reviewers ?? ["r1"],
|
|
13
|
+
sourceFindingIds: ["r1#F1"],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function panelMeta(status, opts = {}) {
|
|
17
|
+
const confirmed = opts.confirmed ?? [];
|
|
18
|
+
const advisories = opts.advisories ?? [];
|
|
19
|
+
const verdict = status === "clean" ? "approve" : status === "has_findings" ? "request_changes" : status === "needs_human" ? "needs_clarification" : "blocked";
|
|
20
|
+
return {
|
|
21
|
+
strategy: "panel",
|
|
22
|
+
reviewMode: "code",
|
|
23
|
+
verdict,
|
|
24
|
+
verdictSource: "parsed",
|
|
25
|
+
status,
|
|
26
|
+
findings: confirmed.map((c) => ({ id: c.id, summary: c.summary, actionable: true })),
|
|
27
|
+
actionableCount: confirmed.length,
|
|
28
|
+
durationMs: opts.durationMs ?? 100,
|
|
29
|
+
model: null,
|
|
30
|
+
configuredReviewers: opts.configured ?? 3,
|
|
31
|
+
successfulReviewers: opts.successful ?? opts.configured ?? 3,
|
|
32
|
+
consensusPolicy: (opts.policy ?? "quorum"),
|
|
33
|
+
consensusThreshold: opts.threshold ?? 2,
|
|
34
|
+
panelHealth: (opts.health ?? (status === "blocked" ? "blocked" : status === "needs_human" ? "needs_human" : "healthy")),
|
|
35
|
+
confirmedClusters: confirmed,
|
|
36
|
+
advisories,
|
|
37
|
+
reviewers: [],
|
|
38
|
+
adjudicationUsed: false,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const confirmedFinding = [cluster("Off-by-one", { confirmed: true, support: 2, actionableSupport: 2, reviewers: ["r1", "r2"] })];
|
|
42
|
+
test("panel loop stops after a clean first panel", async () => {
|
|
43
|
+
let calls = 0;
|
|
44
|
+
const result = await runReviewLoop(3, async () => {
|
|
45
|
+
calls += 1;
|
|
46
|
+
return { meta: panelMeta("clean"), exitCode: 0 };
|
|
47
|
+
});
|
|
48
|
+
assert.equal(calls, 1);
|
|
49
|
+
assert.equal(result.stopReason, "clean");
|
|
50
|
+
assert.equal(result.exitCode, 0);
|
|
51
|
+
assert.equal(result.rounds[0].panel?.confirmedCount, 0);
|
|
52
|
+
});
|
|
53
|
+
test("panel loop stops when a later panel becomes clean", async () => {
|
|
54
|
+
const sequence = [
|
|
55
|
+
{ meta: panelMeta("has_findings", { confirmed: confirmedFinding }), exitCode: 1 },
|
|
56
|
+
{ meta: panelMeta("clean"), exitCode: 0 },
|
|
57
|
+
];
|
|
58
|
+
const result = await runReviewLoop(3, async (i) => sequence[i - 1]);
|
|
59
|
+
assert.equal(result.stopReason, "clean");
|
|
60
|
+
assert.deepEqual(result.rounds.map((r) => r.status), ["has_findings", "clean"]);
|
|
61
|
+
assert.equal(result.rounds[0].panel?.confirmedCount, 1);
|
|
62
|
+
assert.equal(result.rounds[1].panel?.confirmedCount, 0);
|
|
63
|
+
});
|
|
64
|
+
test("panel loop exhausts the budget while confirmed findings remain", async () => {
|
|
65
|
+
let calls = 0;
|
|
66
|
+
const result = await runReviewLoop(2, async () => {
|
|
67
|
+
calls += 1;
|
|
68
|
+
return { meta: panelMeta("has_findings", { confirmed: confirmedFinding }), exitCode: 1 };
|
|
69
|
+
});
|
|
70
|
+
assert.equal(calls, 2);
|
|
71
|
+
assert.equal(result.stopReason, "budget_exhausted");
|
|
72
|
+
assert.equal(result.exitCode, 1);
|
|
73
|
+
});
|
|
74
|
+
test("panel loop escalates blocked and needs-human panels immediately", async () => {
|
|
75
|
+
for (const scenario of [
|
|
76
|
+
{ status: "blocked", exit: 4, health: "blocked" },
|
|
77
|
+
{ status: "needs_human", exit: 3, health: "needs_human" },
|
|
78
|
+
]) {
|
|
79
|
+
let calls = 0;
|
|
80
|
+
const result = await runReviewLoop(3, async () => {
|
|
81
|
+
calls += 1;
|
|
82
|
+
return { meta: panelMeta(scenario.status, { health: scenario.health }), exitCode: scenario.exit };
|
|
83
|
+
});
|
|
84
|
+
assert.equal(calls, 1);
|
|
85
|
+
assert.equal(result.stopReason, scenario.status);
|
|
86
|
+
assert.equal(result.exitCode, scenario.exit);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
test("panel loop execution count: reviewer runs scale with executed rounds and early stop reduces runs", async () => {
|
|
90
|
+
const reviewerCount = 3;
|
|
91
|
+
let calls = 0;
|
|
92
|
+
await runReviewLoop(5, async () => {
|
|
93
|
+
calls += 1;
|
|
94
|
+
return { meta: panelMeta("clean"), exitCode: 0 };
|
|
95
|
+
});
|
|
96
|
+
assert.equal(calls, 1);
|
|
97
|
+
assert.equal(calls * reviewerCount, reviewerCount);
|
|
98
|
+
let budgetCalls = 0;
|
|
99
|
+
await runReviewLoop(2, async () => {
|
|
100
|
+
budgetCalls += 1;
|
|
101
|
+
return { meta: panelMeta("has_findings", { confirmed: confirmedFinding, configured: reviewerCount }), exitCode: 1 };
|
|
102
|
+
});
|
|
103
|
+
assert.equal(budgetCalls, 2);
|
|
104
|
+
assert.equal(budgetCalls * reviewerCount, 6);
|
|
105
|
+
});
|
|
106
|
+
test("panel loop summary reports per-round support and consensus details", async () => {
|
|
107
|
+
const sequence = [
|
|
108
|
+
{ meta: panelMeta("has_findings", { confirmed: confirmedFinding, advisories: [cluster("Typo")], configured: 3, successful: 3, policy: "quorum", threshold: 2, health: "healthy", durationMs: 1200 }), exitCode: 1 },
|
|
109
|
+
{ meta: panelMeta("clean", { configured: 3, successful: 3, policy: "quorum", threshold: 2, durationMs: 800 }), exitCode: 0 },
|
|
110
|
+
];
|
|
111
|
+
const result = await runReviewLoop(3, async (i) => sequence[i - 1]);
|
|
112
|
+
const summary = formatLoopSummary(result);
|
|
113
|
+
assert.match(summary, /pi-review loop/);
|
|
114
|
+
assert.match(summary, /Round 1.*panel 3\/3.*1 confirmed \/ 1 advisory.*quorum≥2.*HEALTHY/);
|
|
115
|
+
assert.match(summary, /Round 2.*panel 3\/3.*0 confirmed \/ 0 advisory/);
|
|
116
|
+
assert.match(summary, /Stop.*clean/);
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=panel-loop.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-loop.test.js","sourceRoot":"","sources":["../src/panel-loop.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG7D,SAAS,OAAO,CAAC,OAAe,EAAE,OAAoG,EAAE;IACtI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;IAClC,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK;QAClC,YAAY,EAAE,OAAO;QACrB,sBAAsB,EAAE,IAAI,CAAC,iBAAiB,IAAI,OAAO;QACzD,qBAAqB,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC;QAC/C,gBAAgB,EAAE,CAAC,OAAO,CAAC;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAChB,MAAoB,EACpB,OASI,EAAE;IAEN,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACzC,MAAM,OAAO,GACX,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC;IAChJ,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,UAAU,EAAE,MAAM;QAClB,OAAO;QACP,aAAa,EAAE,QAAQ;QACvB,MAAM;QACN,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,eAAe,EAAE,SAAS,CAAC,MAAM;QACjC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,GAAG;QAClC,KAAK,EAAE,IAAI;QACX,mBAAmB,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;QACzC,mBAAmB,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC;QAC5D,eAAe,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAuC;QAChF,kBAAkB,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC;QACvC,WAAW,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAmC;QACzJ,iBAAiB,EAAE,SAAS;QAC5B,UAAU;QACV,SAAS,EAAE,EAAE;QACb,gBAAgB,EAAE,KAAK;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAEjI,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;IAC5D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE;QAC/C,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,QAAQ,GAAG;QACf,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;QACjF,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;KAC1C,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACrE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IAChF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE;QAC/C,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IACjF,KAAK,MAAM,QAAQ,IAAI;QACrB,EAAE,MAAM,EAAE,SAAkB,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE;QAC1D,EAAE,MAAM,EAAE,aAAsB,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KACnE,EAAE,CAAC;QACF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE;YAC/C,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpG,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kGAAkG,EAAE,KAAK,IAAI,EAAE;IAClH,MAAM,aAAa,GAAG,CAAC,CAAC;IACxB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE;QAChC,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,aAAa,EAAE,aAAa,CAAC,CAAC;IAEnD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE;QAChC,WAAW,IAAI,CAAC,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACtH,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;IACpF,MAAM,QAAQ,GAAG;QACf,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;QACnN,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;KAC7H,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,mEAAmE,CAAC,CAAC;IAC3F,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,gDAAgD,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-tools.test.d.ts","sourceRoot":"","sources":["../src/panel-tools.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { PANEL_READ_ONLY_TOOLS, resolvePanelReviewerTools } from "./panel.js";
|
|
4
|
+
test("panel reviewers default to the hard read-only allowlist", () => {
|
|
5
|
+
assert.equal(resolvePanelReviewerTools(undefined), PANEL_READ_ONLY_TOOLS.join(","));
|
|
6
|
+
});
|
|
7
|
+
test("panel reviewers reject shell and mutation-capable tools at the boundary", () => {
|
|
8
|
+
for (const tool of ["bash", "edit", "write", "apply_patch"]) {
|
|
9
|
+
assert.throws(() => resolvePanelReviewerTools(`read,${tool}`), /panel reviewers only allow/);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=panel-tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-tools.test.js","sourceRoot":"","sources":["../src/panel-tools.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE9E,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACtF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE;IACnF,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,yBAAyB,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,4BAA4B,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-usage.d.ts","sourceRoot":"","sources":["../src/panel-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,GAAG,UAAU,GAAG,SAAS,CAcxF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combine final usage from independent reviewer sessions.
|
|
3
|
+
*/
|
|
4
|
+
export function sumPanelUsage(usages) {
|
|
5
|
+
const present = usages.filter((usage) => Boolean(usage));
|
|
6
|
+
if (present.length === 0)
|
|
7
|
+
return undefined;
|
|
8
|
+
const total = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 0 };
|
|
9
|
+
for (const usage of present) {
|
|
10
|
+
total.input += usage.input;
|
|
11
|
+
total.cacheRead += usage.cacheRead;
|
|
12
|
+
total.cacheWrite += usage.cacheWrite;
|
|
13
|
+
total.output += usage.output;
|
|
14
|
+
total.reasoning += usage.reasoning;
|
|
15
|
+
total.totalTokens += usage.totalTokens;
|
|
16
|
+
if (typeof usage.costTotal === "number")
|
|
17
|
+
total.costTotal = (total.costTotal ?? 0) + usage.costTotal;
|
|
18
|
+
}
|
|
19
|
+
return total;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=panel-usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-usage.js","sourceRoot":"","sources":["../src/panel-usage.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAuB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,KAAK,GAAe,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAC7G,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;QAC3B,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;QACnC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;QACrC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QAC7B,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;QACnC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC;QACvC,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;YAAE,KAAK,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IACtG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PanelReviewMeta, ReviewerSubmission, TokenUsage } from "./types.js";
|
|
2
|
+
import type { ReviewEvent, ReviewerIdentity } from "./review-events.js";
|
|
3
|
+
export type ReviewerViewStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
4
|
+
export type PanelPhase = "idle" | "running" | "aggregating" | "completed";
|
|
5
|
+
export interface PanelReviewerView extends ReviewerIdentity {
|
|
6
|
+
status: ReviewerViewStatus;
|
|
7
|
+
activeTool?: string;
|
|
8
|
+
activityAt?: number;
|
|
9
|
+
startedAt?: number;
|
|
10
|
+
completedAt?: number;
|
|
11
|
+
turns: number;
|
|
12
|
+
usage?: TokenUsage;
|
|
13
|
+
recentActivity: string[];
|
|
14
|
+
submission?: ReviewerSubmission;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface PanelViewState {
|
|
18
|
+
runId?: string;
|
|
19
|
+
lastSeq: number;
|
|
20
|
+
target?: string;
|
|
21
|
+
mode?: string;
|
|
22
|
+
panelPreset?: string;
|
|
23
|
+
startedAt?: number;
|
|
24
|
+
completedAt?: number;
|
|
25
|
+
phase: PanelPhase;
|
|
26
|
+
reviewers: Record<string, PanelReviewerView>;
|
|
27
|
+
aggregate: {
|
|
28
|
+
total: number;
|
|
29
|
+
queued: number;
|
|
30
|
+
running: number;
|
|
31
|
+
completed: number;
|
|
32
|
+
failed: number;
|
|
33
|
+
cancelled: number;
|
|
34
|
+
usage?: TokenUsage;
|
|
35
|
+
};
|
|
36
|
+
meta?: PanelReviewMeta;
|
|
37
|
+
}
|
|
38
|
+
export declare function createPanelViewState(): PanelViewState;
|
|
39
|
+
/** Unknown, duplicate, out-of-order, and other-run events leave state intact. */
|
|
40
|
+
export declare function reducePanelEvent(state: PanelViewState, event: ReviewEvent): PanelViewState;
|
|
41
|
+
//# sourceMappingURL=panel-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-view.d.ts","sourceRoot":"","sources":["../src/panel-view.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAC7F,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC;IACxI,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAID,wBAAgB,oBAAoB,IAAI,cAAc,CAOrD;AA2BD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,cAAc,CAsD1F"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Pure state reducer shared by the Pi renderer and future event consumers.
|
|
2
|
+
import { sumPanelUsage } from "./panel-usage.js";
|
|
3
|
+
const ACTIVITY_LIMIT = 8;
|
|
4
|
+
export function createPanelViewState() {
|
|
5
|
+
return {
|
|
6
|
+
lastSeq: 0,
|
|
7
|
+
phase: "idle",
|
|
8
|
+
reviewers: {},
|
|
9
|
+
aggregate: { total: 0, queued: 0, running: 0, completed: 0, failed: 0, cancelled: 0 },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function addActivity(reviewer, activity) {
|
|
13
|
+
return { ...reviewer, recentActivity: [...reviewer.recentActivity, activity].slice(-ACTIVITY_LIMIT) };
|
|
14
|
+
}
|
|
15
|
+
function fallbackReviewer(reviewerId) {
|
|
16
|
+
return { reviewerId, role: reviewerId, model: null, status: "queued", turns: 0, recentActivity: [] };
|
|
17
|
+
}
|
|
18
|
+
function withAggregate(state) {
|
|
19
|
+
const statuses = Object.values(state.reviewers).map((reviewer) => reviewer.status);
|
|
20
|
+
const usage = sumPanelUsage(Object.values(state.reviewers).map((reviewer) => reviewer.usage));
|
|
21
|
+
return {
|
|
22
|
+
...state,
|
|
23
|
+
aggregate: {
|
|
24
|
+
total: statuses.length,
|
|
25
|
+
queued: statuses.filter((status) => status === "queued").length,
|
|
26
|
+
running: statuses.filter((status) => status === "running").length,
|
|
27
|
+
completed: statuses.filter((status) => status === "completed").length,
|
|
28
|
+
failed: statuses.filter((status) => status === "failed").length,
|
|
29
|
+
cancelled: statuses.filter((status) => status === "cancelled").length,
|
|
30
|
+
...(usage ? { usage } : {}),
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Unknown, duplicate, out-of-order, and other-run events leave state intact. */
|
|
35
|
+
export function reducePanelEvent(state, event) {
|
|
36
|
+
const knownTypes = new Set([
|
|
37
|
+
"panel.started", "reviewer.queued", "reviewer.started", "reviewer.turn.started", "reviewer.tool.started", "reviewer.tool.finished", "reviewer.text.delta", "reviewer.usage", "reviewer.completed", "reviewer.failed", "reviewer.cancelled", "aggregation.started", "panel.completed",
|
|
38
|
+
]);
|
|
39
|
+
if (!knownTypes.has(event.type) || event.seq <= state.lastSeq || (state.runId && event.runId !== state.runId))
|
|
40
|
+
return state;
|
|
41
|
+
let next = { ...state, runId: event.runId, lastSeq: event.seq };
|
|
42
|
+
if (event.type === "panel.started") {
|
|
43
|
+
const reviewers = Object.fromEntries(event.reviewers.map((identity) => [identity.reviewerId, { ...identity, status: "queued", turns: 0, recentActivity: [] }]));
|
|
44
|
+
return withAggregate({ ...next, target: event.target, mode: event.mode, ...(event.panelPreset ? { panelPreset: event.panelPreset } : {}), startedAt: event.at, phase: "running", reviewers });
|
|
45
|
+
}
|
|
46
|
+
if (event.type === "aggregation.started")
|
|
47
|
+
return withAggregate({ ...next, phase: "aggregating" });
|
|
48
|
+
if (event.type === "panel.completed") {
|
|
49
|
+
const completed = withAggregate({ ...next, phase: "completed", completedAt: event.at, meta: event.meta });
|
|
50
|
+
return { ...completed, aggregate: { ...completed.aggregate, ...(event.meta.usage ? { usage: event.meta.usage } : {}) } };
|
|
51
|
+
}
|
|
52
|
+
const reviewerId = event.reviewerId;
|
|
53
|
+
const previous = state.reviewers[reviewerId] ?? fallbackReviewer(reviewerId);
|
|
54
|
+
let reviewer = previous;
|
|
55
|
+
switch (event.type) {
|
|
56
|
+
case "reviewer.queued":
|
|
57
|
+
reviewer = { ...previous, status: "queued", activityAt: event.at };
|
|
58
|
+
break;
|
|
59
|
+
case "reviewer.started":
|
|
60
|
+
reviewer = addActivity({ ...previous, status: "running", startedAt: event.at, activityAt: event.at }, "review started");
|
|
61
|
+
break;
|
|
62
|
+
case "reviewer.turn.started":
|
|
63
|
+
reviewer = addActivity({ ...previous, status: "running", turns: event.turn, activityAt: event.at }, `turn ${event.turn}`);
|
|
64
|
+
break;
|
|
65
|
+
case "reviewer.tool.started":
|
|
66
|
+
reviewer = addActivity({ ...previous, status: "running", activeTool: event.tool, activityAt: event.at }, `tool ${event.tool}${event.summary ? `: ${event.summary}` : ""}`);
|
|
67
|
+
break;
|
|
68
|
+
case "reviewer.tool.finished":
|
|
69
|
+
reviewer = addActivity({ ...previous, status: "running", activeTool: undefined, activityAt: event.at }, `tool ${event.tool} finished${event.summary ? `: ${event.summary}` : ""}`);
|
|
70
|
+
break;
|
|
71
|
+
case "reviewer.text.delta":
|
|
72
|
+
reviewer = addActivity({ ...previous, status: "running", activityAt: event.at }, event.text);
|
|
73
|
+
break;
|
|
74
|
+
case "reviewer.usage":
|
|
75
|
+
reviewer = { ...previous, usage: event.usage, activityAt: event.at };
|
|
76
|
+
break;
|
|
77
|
+
case "reviewer.completed":
|
|
78
|
+
reviewer = addActivity({ ...previous, status: "completed", activeTool: undefined, completedAt: event.at, activityAt: event.at, usage: event.submission.usage ?? previous.usage, submission: event.submission }, "review completed");
|
|
79
|
+
break;
|
|
80
|
+
case "reviewer.failed":
|
|
81
|
+
reviewer = addActivity({ ...previous, status: "failed", activeTool: undefined, completedAt: event.at, activityAt: event.at, error: event.message }, event.message);
|
|
82
|
+
break;
|
|
83
|
+
case "reviewer.cancelled":
|
|
84
|
+
reviewer = addActivity({ ...previous, status: "cancelled", activeTool: undefined, completedAt: event.at, activityAt: event.at, ...(event.message ? { error: event.message } : {}) }, event.message ?? "review cancelled");
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
next = { ...next, reviewers: { ...state.reviewers, [reviewerId]: reviewer } };
|
|
88
|
+
return withAggregate(next);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=panel-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-view.js","sourceRoot":"","sources":["../src/panel-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-view.test.d.ts","sourceRoot":"","sources":["../src/panel-view.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { createPanelViewState, reducePanelEvent } from "./panel-view.js";
|
|
4
|
+
function event(type, seq, payload) {
|
|
5
|
+
return { v: 1, runId: "run-1", seq, at: 1000 + seq, type, ...payload };
|
|
6
|
+
}
|
|
7
|
+
test("panel reducer produces the same final state during live delivery and replay", () => {
|
|
8
|
+
const events = [
|
|
9
|
+
event("panel.started", 1, { target: "@src", mode: "code", reviewers: [{ reviewerId: "security", role: "Security", model: "openai/gpt", thinking: "high" }] }),
|
|
10
|
+
event("reviewer.queued", 2, { reviewerId: "security" }),
|
|
11
|
+
event("reviewer.started", 3, { reviewerId: "security" }),
|
|
12
|
+
event("reviewer.tool.started", 4, { reviewerId: "security", tool: "read", summary: "src/panel.ts" }),
|
|
13
|
+
event("reviewer.usage", 5, { reviewerId: "security", usage: { input: 10, output: 4, cacheRead: 0, cacheWrite: 0, reasoning: 2, totalTokens: 14 } }),
|
|
14
|
+
event("reviewer.completed", 6, { reviewerId: "security", submission: { reviewerId: "security", role: "Security", model: "openai/gpt", durationMs: 20, result: { status: "clean", verdict: "approve", verdictSource: "parsed", findings: [], actionableCount: 0 } } }),
|
|
15
|
+
event("aggregation.started", 7, {}),
|
|
16
|
+
];
|
|
17
|
+
const live = events.reduce(reducePanelEvent, createPanelViewState());
|
|
18
|
+
const replay = events.reduce(reducePanelEvent, createPanelViewState());
|
|
19
|
+
assert.deepEqual(replay, live);
|
|
20
|
+
assert.equal(live.reviewers.security?.status, "completed");
|
|
21
|
+
assert.equal(live.reviewers.security?.activeTool, undefined);
|
|
22
|
+
assert.equal(live.aggregate.completed, 1);
|
|
23
|
+
assert.equal(live.phase, "aggregating");
|
|
24
|
+
});
|
|
25
|
+
test("terminal panel usage reuses the CLI aggregation semantics", () => {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
let state = reducePanelEvent(createPanelViewState(), {
|
|
28
|
+
v: 1, runId: "run-usage", seq: 1, at: now, type: "panel.started", target: "@src", mode: "code",
|
|
29
|
+
reviewers: [{ reviewerId: "r1", role: "one", model: null }, { reviewerId: "r2", role: "two", model: null }],
|
|
30
|
+
});
|
|
31
|
+
state = reducePanelEvent(state, { v: 1, runId: "run-usage", seq: 2, at: now, type: "reviewer.usage", reviewerId: "r1", usage: { input: 100, output: 10, cacheRead: 20, cacheWrite: 0, reasoning: 5, totalTokens: 110 } });
|
|
32
|
+
state = reducePanelEvent(state, { v: 1, runId: "run-usage", seq: 3, at: now, type: "reviewer.usage", reviewerId: "r2", usage: { input: 80, output: 30, cacheRead: 10, cacheWrite: 0, reasoning: 7, totalTokens: 110 } });
|
|
33
|
+
assert.deepEqual(state.aggregate.usage, { input: 180, output: 40, cacheRead: 30, cacheWrite: 0, reasoning: 12, totalTokens: 220 });
|
|
34
|
+
});
|
|
35
|
+
test("panel reducer ignores duplicates, unknown events, and out-of-order delivery", () => {
|
|
36
|
+
const started = event("panel.started", 1, { target: "@src", mode: "code", reviewers: [] });
|
|
37
|
+
const state = reducePanelEvent(createPanelViewState(), started);
|
|
38
|
+
const duplicate = reducePanelEvent(state, started);
|
|
39
|
+
const unknown = reducePanelEvent(duplicate, { v: 1, runId: "run-1", seq: 2, at: 1002, type: "future.event" });
|
|
40
|
+
const later = reducePanelEvent(unknown, event("aggregation.started", 3, {}));
|
|
41
|
+
const outOfOrder = reducePanelEvent(later, event("aggregation.started", 2, {}));
|
|
42
|
+
assert.equal(outOfOrder.lastSeq, 3);
|
|
43
|
+
assert.equal(outOfOrder.phase, "aggregating");
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=panel-view.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-view.test.js","sourceRoot":"","sources":["../src/panel-view.test.ts"],"names":[],"mappings":"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"}
|
package/dist/panel.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ParsedArgs, PanelReviewMeta } from "./types.js";
|
|
2
|
+
export { PANEL_READ_ONLY_TOOLS } from "./types.js";
|
|
3
|
+
import { type ReviewEventListener } from "./review-events.js";
|
|
4
|
+
/** Emit the aggregate panel footer (ASCII + JSON) like a single review. */
|
|
5
|
+
export declare function emitPanelFooter(meta: PanelReviewMeta): void;
|
|
6
|
+
/** Resolve reviewer tools through the hard allowlist; rejected requests cannot silently widen access. */
|
|
7
|
+
export declare function resolvePanelReviewerTools(tools: string | string[] | undefined): string;
|
|
8
|
+
export interface PanelRunOptions {
|
|
9
|
+
onEvent?: ReviewEventListener;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
emitFooter?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Run one complete panel evaluation and return the aggregate result (no exit). */
|
|
14
|
+
export declare function runPanelReviewOnce(parsed: ParsedArgs, stdinText?: string, options?: PanelRunOptions): Promise<{
|
|
15
|
+
meta: PanelReviewMeta;
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}>;
|
|
18
|
+
/** CLI-compatible panel review entrypoint. */
|
|
19
|
+
export declare function runPanelReview(parsed: ParsedArgs): Promise<never>;
|
|
20
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAIhB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgBnD,OAAO,EAAiG,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE7J,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAa3D;AAWD,yGAAyG;AACzG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAStF;AAqPD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAmBD,mFAAmF;AACnF,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,UAAU,EAClB,SAAS,SAAoB,EAC7B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAuGtD;AAED,8CAA8C;AAC9C,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CASvE"}
|