@mrclrchtr/supi-review 2.7.0 → 3.0.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 (49) hide show
  1. package/README.md +75 -163
  2. package/node_modules/@mrclrchtr/supi-core/README.md +1 -1
  3. package/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  4. package/node_modules/@mrclrchtr/supi-core/src/api.ts +2 -0
  5. package/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +40 -0
  6. package/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +1 -0
  7. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +14 -0
  8. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +31 -14
  9. package/node_modules/@mrclrchtr/supi-core/src/settings.ts +1 -0
  10. package/package.json +3 -3
  11. package/src/config.ts +64 -0
  12. package/src/git-command.ts +78 -0
  13. package/src/git.ts +306 -505
  14. package/src/history/collect.ts +43 -120
  15. package/src/model.ts +35 -0
  16. package/src/review-path.ts +85 -0
  17. package/src/review-result.ts +43 -92
  18. package/src/review.ts +154 -288
  19. package/src/session/review-plan-store.ts +20 -51
  20. package/src/target/packet.ts +46 -369
  21. package/src/tool/agent-review-schemas.ts +101 -104
  22. package/src/tool/agent-review-tools.ts +269 -301
  23. package/src/tool/child-failure-diagnostics.ts +1 -1
  24. package/src/tool/child-resource-loader.ts +37 -0
  25. package/src/tool/child-session-runner.ts +83 -0
  26. package/src/tool/output-page.ts +47 -0
  27. package/src/tool/planner-runner.ts +69 -0
  28. package/src/tool/review-runner.ts +42 -257
  29. package/src/tool/review-system-prompt.ts +12 -110
  30. package/src/tool/review-tools.ts +119 -0
  31. package/src/tool/review-workflow.ts +309 -0
  32. package/src/tool/runner-helpers.ts +3 -8
  33. package/src/tool/schemas.ts +75 -62
  34. package/src/tui/common.ts +175 -0
  35. package/src/tui/prepare.ts +132 -0
  36. package/src/tui/run.ts +160 -0
  37. package/src/types.ts +153 -275
  38. package/src/history/synthesize.ts +0 -121
  39. package/src/tool/agent-review-workflow.ts +0 -398
  40. package/src/tool/brief-runner.ts +0 -180
  41. package/src/tool/guidance.ts +0 -21
  42. package/src/tool/review-handlers.ts +0 -314
  43. package/src/tool/snapshot-tools.ts +0 -117
  44. package/src/ui/flow.ts +0 -189
  45. package/src/ui/format-content.ts +0 -143
  46. package/src/ui/renderer.ts +0 -274
  47. package/src/ui/review-plan-inspector.ts +0 -391
  48. package/src/ui/review-tool-format.ts +0 -138
  49. package/src/ui/review-tool-renderer.ts +0 -234
@@ -1,234 +0,0 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { Container, Spacer, Text } from "@earendil-works/pi-tui";
3
- import type { PrepareAgentReviewInput, RunAgentReviewInput } from "../tool/agent-review-schemas.ts";
4
- import {
5
- formatChildFailureCopy,
6
- formatChildFailureDiagnostics,
7
- } from "../tool/child-failure-diagnostics.ts";
8
- import type {
9
- AgentReviewBatchDetails,
10
- PreparedAgentReviewDetails,
11
- ReviewProgress,
12
- } from "../types.ts";
13
- import { formatBrief, formatCritique } from "./review-tool-format.ts";
14
-
15
- type ReviewTheme = Parameters<Parameters<ExtensionAPI["registerMessageRenderer"]>[1]>[2];
16
-
17
- interface ToolResultLike {
18
- content: Array<{ type: string; text?: string }>;
19
- details?: unknown;
20
- }
21
-
22
- /** Partial tool-result details used while synthesis or reviewer sessions are active. */
23
- export interface AgentReviewProgressDetails {
24
- kind: "review-progress";
25
- phase: "prepare" | "review";
26
- completed: number;
27
- total: number;
28
- reviewers?: Record<string, ReviewProgress>;
29
- }
30
-
31
- export function renderPrepareReviewCall(args: PrepareAgentReviewInput, theme: ReviewTheme): Text {
32
- const target = args.target?.kind ?? "working-tree";
33
- const ref = args.target?.base ?? args.target?.sha;
34
- const suffix = ref ? ` (${ref})` : "";
35
- return new Text(
36
- `${theme.fg("toolTitle", theme.bold("supi_review_prepare "))}${theme.fg("accent", target)}${theme.fg("dim", suffix)}`,
37
- 0,
38
- 0,
39
- );
40
- }
41
-
42
- export function renderPrepareReviewResult(
43
- result: ToolResultLike,
44
- expanded: boolean,
45
- theme: ReviewTheme,
46
- ): Container | Text {
47
- const details = result.details as
48
- | PreparedAgentReviewDetails
49
- | AgentReviewProgressDetails
50
- | undefined;
51
- if (details?.kind === "review-progress") {
52
- return new Text(theme.fg("warning", "Synthesizing review brief…"), 0, 0);
53
- }
54
- if (details?.kind !== "review-prepared") return fallbackResult(result, theme);
55
-
56
- const container = new Container();
57
- container.addChild(
58
- new Text(
59
- `${theme.fg("success", "✓")} ${theme.fg("toolTitle", theme.bold("Review brief prepared"))}`,
60
- 0,
61
- 0,
62
- ),
63
- );
64
- container.addChild(new Text(theme.fg("dim", `Plan: ${details.planId}`), 0, 0));
65
- container.addChild(new Text(theme.fg("dim", `Snapshot: ${details.snapshot.title}`), 0, 0));
66
- container.addChild(
67
- new Text(theme.fg("muted", `Summary: ${details.generatedBrief.summary}`), 0, 0),
68
- );
69
- container.addChild(
70
- new Text(theme.fg("warning", "Main-agent critique required before run"), 0, 0),
71
- );
72
-
73
- if (expanded) {
74
- container.addChild(new Spacer(1));
75
- for (const line of formatBrief(details.generatedBrief)) {
76
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
77
- }
78
- }
79
- return container;
80
- }
81
-
82
- export function renderRunReviewCall(
83
- args: RunAgentReviewInput,
84
- expanded: boolean,
85
- theme: ReviewTheme,
86
- ): Container | Text {
87
- const verdictColor = args.critique.verdict === "revise" ? "warning" : "success";
88
- const header = `${theme.fg("toolTitle", theme.bold("supi_review_run "))}${theme.fg(verdictColor, args.critique.verdict)}${theme.fg("dim", ` · ${args.critique.findings.length} critique finding(s) · ${args.reviewers.length} reviewer(s)`)}`;
89
- if (!expanded) return new Text(header, 0, 0);
90
-
91
- const container = new Container();
92
- container.addChild(new Text(header, 0, 0));
93
- for (const line of formatCritique(args.critique)) {
94
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
95
- }
96
- if (args.revisedBrief) {
97
- container.addChild(new Spacer(1));
98
- container.addChild(new Text(theme.fg("accent", "Proposed revised brief"), 0, 0));
99
- for (const line of formatBrief(args.revisedBrief)) {
100
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
101
- }
102
- }
103
- container.addChild(new Spacer(1));
104
- for (const reviewer of args.reviewers) {
105
- container.addChild(new Text(theme.fg("muted", `${reviewer.id}: ${reviewer.focus}`), 0, 0));
106
- }
107
- return container;
108
- }
109
-
110
- export function renderRunReviewResult(
111
- result: ToolResultLike,
112
- expanded: boolean,
113
- theme: ReviewTheme,
114
- ): Container | Text {
115
- const details = result.details as
116
- | AgentReviewBatchDetails
117
- | AgentReviewProgressDetails
118
- | undefined;
119
- if (details?.kind === "review-progress") {
120
- return renderProgress(details, theme);
121
- }
122
- if (details?.kind !== "review-batch") return fallbackResult(result, theme);
123
-
124
- const container = new Container();
125
- const successCount = details.results.filter((entry) => entry.result.kind === "success").length;
126
- const verdictColor = details.evaluation.critique.verdict === "revise" ? "warning" : "success";
127
- container.addChild(
128
- new Text(
129
- `${theme.fg("success", "✓")} ${theme.fg("toolTitle", theme.bold("Review batch complete"))}${theme.fg("dim", ` · ${successCount}/${details.results.length} succeeded`)}`,
130
- 0,
131
- 0,
132
- ),
133
- );
134
- container.addChild(
135
- new Text(
136
- theme.fg(
137
- verdictColor,
138
- `Brief ${details.evaluation.critique.verdict}: ${details.evaluation.critique.summary}`,
139
- ),
140
- 0,
141
- 0,
142
- ),
143
- );
144
-
145
- for (const entry of details.results) {
146
- const status = summarizeResult(entry.result);
147
- container.addChild(
148
- new Text(
149
- `${theme.fg(status.color, status.icon)} ${entry.assignment.id}: ${status.text}`,
150
- 0,
151
- 0,
152
- ),
153
- );
154
- }
155
-
156
- if (expanded) {
157
- renderReviewerDiagnostics(container, details, theme);
158
- container.addChild(new Spacer(1));
159
- for (const line of formatCritique(details.evaluation.critique)) {
160
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
161
- }
162
- if (details.evaluation.critique.verdict === "revise") {
163
- container.addChild(new Spacer(1));
164
- container.addChild(new Text(theme.fg("accent", "Effective revised brief"), 0, 0));
165
- for (const line of formatBrief(details.evaluation.effectiveBrief)) {
166
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
167
- }
168
- }
169
- }
170
- return container;
171
- }
172
-
173
- function renderReviewerDiagnostics(
174
- container: Container,
175
- details: AgentReviewBatchDetails,
176
- theme: ReviewTheme,
177
- ): void {
178
- if (
179
- !details.results.some((entry) => entry.result.kind !== "success" && entry.result.diagnostics)
180
- ) {
181
- return;
182
- }
183
-
184
- container.addChild(new Spacer(1));
185
- container.addChild(new Text(theme.fg("accent", "Reviewer diagnostics"), 0, 0));
186
- for (const { assignment, result } of details.results) {
187
- if (result.kind === "success" || !result.diagnostics) continue;
188
- container.addChild(new Text(theme.fg("muted", `${assignment.id}:`), 0, 0));
189
- for (const line of formatChildFailureDiagnostics(result.diagnostics)) {
190
- container.addChild(new Text(theme.fg("dim", line), 0, 0));
191
- }
192
- }
193
- }
194
-
195
- function renderProgress(details: AgentReviewProgressDetails, theme: ReviewTheme): Text {
196
- if (details.phase === "prepare") {
197
- return new Text(theme.fg("warning", "Synthesizing review brief…"), 0, 0);
198
- }
199
- return new Text(
200
- theme.fg("warning", `Running reviewers… ${details.completed}/${details.total} completed`),
201
- 0,
202
- 0,
203
- );
204
- }
205
-
206
- function summarizeResult(result: AgentReviewBatchDetails["results"][number]["result"]): {
207
- icon: string;
208
- color: "success" | "warning" | "error";
209
- text: string;
210
- } {
211
- switch (result.kind) {
212
- case "success":
213
- return {
214
- icon: "✓",
215
- color: result.output.items.length > 0 ? "warning" : "success",
216
- text: `${result.output.items.length} item(s), ${result.output.overall_correctness}`,
217
- };
218
- case "failed":
219
- return {
220
- icon: "✗",
221
- color: "error",
222
- text: formatChildFailureCopy("reviewer", result.failureCode),
223
- };
224
- case "canceled":
225
- return { icon: "○", color: "warning", text: "canceled" };
226
- case "timeout":
227
- return { icon: "◷", color: "warning", text: "timed out" };
228
- }
229
- }
230
-
231
- function fallbackResult(result: ToolResultLike, theme: ReviewTheme): Text {
232
- const content = result.content.find((part) => part.type === "text")?.text ?? "No review output";
233
- return new Text(theme.fg("dim", content), 0, 0);
234
- }