@renaiss-shipflow/cli 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +19 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -0
- package/dist/client.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +3 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/git-identity.d.ts +3 -0
- package/dist/commands/git-identity.d.ts.map +1 -0
- package/dist/commands/git-identity.js +77 -0
- package/dist/commands/git-identity.js.map +1 -0
- package/dist/commands/issue.d.ts.map +1 -1
- package/dist/commands/issue.js +49 -6
- package/dist/commands/issue.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +16 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/pr.d.ts.map +1 -1
- package/dist/commands/pr.js +140 -2
- package/dist/commands/pr.js.map +1 -1
- package/dist/commands/stats.d.ts +7 -0
- package/dist/commands/stats.d.ts.map +1 -1
- package/dist/commands/stats.js +48 -1
- package/dist/commands/stats.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -0
- package/dist/config.js.map +1 -1
- package/dist/escalation-format.d.ts +35 -2
- package/dist/escalation-format.d.ts.map +1 -1
- package/dist/escalation-format.js +81 -4
- package/dist/escalation-format.js.map +1 -1
- package/dist/gh.d.ts +43 -1
- package/dist/gh.d.ts.map +1 -1
- package/dist/gh.js +93 -4
- package/dist/gh.js.map +1 -1
- package/dist/git-local.d.ts +4 -0
- package/dist/git-local.d.ts.map +1 -1
- package/dist/git-local.js +37 -0
- package/dist/git-local.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/packet.d.ts +70 -0
- package/dist/packet.d.ts.map +1 -0
- package/dist/packet.js +261 -0
- package/dist/packet.js.map +1 -0
- package/dist/review-contract.d.ts +59 -0
- package/dist/review-contract.d.ts.map +1 -0
- package/dist/review-contract.js +129 -0
- package/dist/review-contract.js.map +1 -0
- package/package.json +1 -1
package/dist/packet.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// Review-packet assembly (Superpowers-6 technique: pre-bake everything the
|
|
2
|
+
// loop's PR reviewer needs into ONE command output, instead of the reviewer
|
|
3
|
+
// spending tokens and wall time re-deriving it with a pile of gh calls).
|
|
4
|
+
//
|
|
5
|
+
// The packet deliberately leads with the SPEC/BRIEF section: a diff-only
|
|
6
|
+
// packet tempts a reviewer into confidently redefining "spec" as whatever the
|
|
7
|
+
// diff implies — the exact failure family Superpowers 6 measured (0/5 flagged
|
|
8
|
+
// a missing brief). When no linked issue exists, the packet says so loudly.
|
|
9
|
+
// Budgets mirror the server-side pr_review runner so both reviewers see
|
|
10
|
+
// comparably sized diffs.
|
|
11
|
+
export const PACKET_PER_FILE_CAP = 6000;
|
|
12
|
+
export const PACKET_TOTAL_CAP = 60000;
|
|
13
|
+
export const PACKET_BRIEF_CAP = 8000; // acceptance criteria sit at the BOTTOM of issue bodies — a tight cap silently drops the spec's checklist
|
|
14
|
+
// Noise paths excluded from the packet diff — lockfiles, generated output,
|
|
15
|
+
// vendored deps, binary-adjacent assets. Kept in sync (by convention) with the
|
|
16
|
+
// server's featuremap noise lists.
|
|
17
|
+
const NOISE_SUBSTRINGS = [
|
|
18
|
+
"node_modules/", "vendor/", "dist/", "build/", ".next/", "__generated__/",
|
|
19
|
+
"__snapshots__/", "coverage/", "storybook-static/", ".turbo/", "out/",
|
|
20
|
+
];
|
|
21
|
+
const NOISE_SUFFIXES = [
|
|
22
|
+
".lock", ".sum", "package-lock.json", "bun.lockb", ".min.js", ".min.css",
|
|
23
|
+
".map", ".snap", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg",
|
|
24
|
+
".woff", ".woff2", ".ttf", ".eot", ".pb.go", "_generated.go", ".gen.go",
|
|
25
|
+
];
|
|
26
|
+
export function isNoiseDiffPath(path) {
|
|
27
|
+
const p = path.toLowerCase();
|
|
28
|
+
return (NOISE_SUBSTRINGS.some((s) => p.includes(s)) ||
|
|
29
|
+
NOISE_SUFFIXES.some((s) => p.endsWith(s)));
|
|
30
|
+
}
|
|
31
|
+
/** Split a unified `gh pr diff` output into per-file sections. */
|
|
32
|
+
export function splitUnifiedDiff(diff) {
|
|
33
|
+
const sections = [];
|
|
34
|
+
const lines = diff.split("\n");
|
|
35
|
+
let current = null;
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
const m = /^diff --git a\/(.+) b\/(.+)$/.exec(line);
|
|
38
|
+
if (m) {
|
|
39
|
+
if (current)
|
|
40
|
+
sections.push(current);
|
|
41
|
+
current = { path: m[2], body: line };
|
|
42
|
+
}
|
|
43
|
+
else if (current) {
|
|
44
|
+
current.body += "\n" + line;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (current)
|
|
48
|
+
sections.push(current);
|
|
49
|
+
return sections;
|
|
50
|
+
}
|
|
51
|
+
/** Noise-filter and budget the diff (per-file + total caps). */
|
|
52
|
+
export function filterDiffForPacket(diff) {
|
|
53
|
+
const out = [];
|
|
54
|
+
let shown = 0;
|
|
55
|
+
let omittedNoise = 0;
|
|
56
|
+
let omittedBudget = 0;
|
|
57
|
+
let truncatedFiles = 0;
|
|
58
|
+
let total = 0;
|
|
59
|
+
for (const s of splitUnifiedDiff(diff)) {
|
|
60
|
+
if (isNoiseDiffPath(s.path)) {
|
|
61
|
+
omittedNoise++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (total >= PACKET_TOTAL_CAP) {
|
|
65
|
+
omittedBudget++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
let body = s.body;
|
|
69
|
+
if (body.length > PACKET_PER_FILE_CAP) {
|
|
70
|
+
body = body.slice(0, PACKET_PER_FILE_CAP) + "\n… (file diff truncated)";
|
|
71
|
+
truncatedFiles++;
|
|
72
|
+
}
|
|
73
|
+
out.push(body);
|
|
74
|
+
total += body.length;
|
|
75
|
+
shown++;
|
|
76
|
+
}
|
|
77
|
+
return { text: out.join("\n"), shown, omittedNoise, omittedBudget, truncatedFiles };
|
|
78
|
+
}
|
|
79
|
+
/** Lines from PR comments that carry test evidence / health captions. */
|
|
80
|
+
export function extractEvidenceLines(comments) {
|
|
81
|
+
const lines = [];
|
|
82
|
+
for (const c of comments) {
|
|
83
|
+
const body = c.body ?? "";
|
|
84
|
+
if (!body.includes("Test evidence") && !/health \d+/.test(body))
|
|
85
|
+
continue;
|
|
86
|
+
for (const line of body.split("\n")) {
|
|
87
|
+
if (line.includes("Test evidence") || /health \d+→\d+|health \d+ ?→/.test(line) || line.startsWith("Verified:") || line.trimStart().startsWith("- Verified")) {
|
|
88
|
+
lines.push(line.trim());
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return lines.slice(0, 12);
|
|
93
|
+
}
|
|
94
|
+
/** Names of the features whose path prefixes match any non-noise diff path,
|
|
95
|
+
* in feature-map order, deduped. */
|
|
96
|
+
export function touchedFeatures(diffPaths, features) {
|
|
97
|
+
const changed = diffPaths.filter((p) => !isNoiseDiffPath(p));
|
|
98
|
+
const out = [];
|
|
99
|
+
for (const f of features) {
|
|
100
|
+
const prefixes = (f.paths ?? []).map((p) => p.replace(/^\.\//, ""));
|
|
101
|
+
// Directory-boundary match: "src/app/admin" owns "src/app/admin/…" and the
|
|
102
|
+
// exact path itself, but never "src/app/admin-shop/…".
|
|
103
|
+
const owns = (prefix, path) => path === prefix || path.startsWith(prefix.endsWith("/") ? prefix : prefix + "/");
|
|
104
|
+
if (prefixes.some((prefix) => prefix && changed.some((path) => owns(prefix, path)))) {
|
|
105
|
+
out.push(f.name || f.key);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
/** The deterministic layer under the per-feature evidence rule: a PR that
|
|
111
|
+
* touches more than one feature needs at least one proof per feature. The
|
|
112
|
+
* semantic judgment (which proof covers which feature) stays with the
|
|
113
|
+
* reviewer; this only counts — conservatively, by comment. */
|
|
114
|
+
export function assessEvidenceCoverage(touched, comments) {
|
|
115
|
+
const evidenceItems = comments.filter((c) => {
|
|
116
|
+
const body = c.body ?? "";
|
|
117
|
+
// Anchored: a structured caption line ("- Verified: …") or the 🧪 bundle
|
|
118
|
+
// header at line start. A bare substring match would count prose like
|
|
119
|
+
// "not yet verified:" or quoted captions and silently suppress the warning.
|
|
120
|
+
return /^\s*🧪.*Test evidence/m.test(body) || /^\s*-?\s*\*{0,2}verified:/im.test(body);
|
|
121
|
+
}).length;
|
|
122
|
+
if (touched.length <= 1 || evidenceItems >= touched.length) {
|
|
123
|
+
return { evidenceItems, warning: null };
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
evidenceItems,
|
|
127
|
+
warning: `⚠️ ${touched.length} features touched, ${evidenceItems} evidence item(s) — ` +
|
|
128
|
+
`need ≥1 proof per feature on a multi-feature PR; treat each unproven feature ` +
|
|
129
|
+
`as an unresolved thread (request_changes) unless every touched feature maps ` +
|
|
130
|
+
`to a proof.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** The "### Deviations from brief" section of a PR body — where the worker
|
|
134
|
+
* logs off-brief pivots (field-guide pattern: deviations must be visible to
|
|
135
|
+
* review, not buried in commit messages). Empty string when absent. */
|
|
136
|
+
export function extractDeviations(prBody) {
|
|
137
|
+
const m = /^###\s*Deviations from brief\s*$/im.exec(prBody);
|
|
138
|
+
if (!m)
|
|
139
|
+
return "";
|
|
140
|
+
const rest = prBody.slice(m.index + m[0].length);
|
|
141
|
+
const end = rest.search(/^#{1,3}\s/m);
|
|
142
|
+
return (end >= 0 ? rest.slice(0, end) : rest).trim();
|
|
143
|
+
}
|
|
144
|
+
/** Render the full review packet as markdown. */
|
|
145
|
+
export function buildReviewPacket(input) {
|
|
146
|
+
const { pr, threads, diff, issue } = input;
|
|
147
|
+
const b = [];
|
|
148
|
+
b.push(`# Review packet — PR #${pr.number}: ${pr.title}`);
|
|
149
|
+
const meta = [];
|
|
150
|
+
if (pr.headRefName)
|
|
151
|
+
meta.push(`${pr.headRefName} → ${pr.baseRefName ?? "?"}`);
|
|
152
|
+
if (pr.isDraft)
|
|
153
|
+
meta.push("DRAFT");
|
|
154
|
+
if (pr.mergeable)
|
|
155
|
+
meta.push(`mergeable: ${pr.mergeable}`);
|
|
156
|
+
if (pr.labels?.length)
|
|
157
|
+
meta.push(`labels: ${pr.labels.map((l) => l.name).join(", ")}`);
|
|
158
|
+
b.push(meta.join(" · "));
|
|
159
|
+
// Spec first — the reviewer judges against THIS, not against the diff.
|
|
160
|
+
b.push("\n## Spec / acceptance brief");
|
|
161
|
+
if (issue) {
|
|
162
|
+
b.push(`Issue #${issue.number} (${issue.linkKind}): ${issue.title}`);
|
|
163
|
+
const body = (issue.body ?? "").trim();
|
|
164
|
+
b.push(body.length > PACKET_BRIEF_CAP ? body.slice(0, PACKET_BRIEF_CAP) + "\n… (brief truncated)" : body || "_(issue has no body)_");
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
b.push("⚠️ **No linked issue/brief found.** Do NOT infer the spec from the diff — " +
|
|
168
|
+
"reviewing against a self-derived spec is a known silent failure. Flag the missing brief in your verdict.");
|
|
169
|
+
}
|
|
170
|
+
const prBody = (pr.body ?? "").trim();
|
|
171
|
+
if (prBody) {
|
|
172
|
+
b.push("\n## PR description");
|
|
173
|
+
b.push(prBody.length > PACKET_BRIEF_CAP ? prBody.slice(0, PACKET_BRIEF_CAP) + "\n… (truncated)" : prBody);
|
|
174
|
+
}
|
|
175
|
+
const deviations = extractDeviations(pr.body ?? "");
|
|
176
|
+
if (deviations) {
|
|
177
|
+
b.push("\n## Deviations from brief");
|
|
178
|
+
b.push(deviations);
|
|
179
|
+
b.push("_Verify each deviation: conservative? justified? does the spec still hold?_");
|
|
180
|
+
}
|
|
181
|
+
b.push("\n## CI");
|
|
182
|
+
const checks = pr.statusCheckRollup ?? [];
|
|
183
|
+
if (checks.length === 0) {
|
|
184
|
+
b.push("no checks reported");
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
let pass = 0, fail = 0, pending = 0;
|
|
188
|
+
const failing = [];
|
|
189
|
+
for (const c of checks) {
|
|
190
|
+
const concl = (c.conclusion ?? c.state ?? "").toUpperCase();
|
|
191
|
+
if (concl === "SUCCESS" || concl === "NEUTRAL" || concl === "SKIPPED")
|
|
192
|
+
pass++;
|
|
193
|
+
else if (concl === "" || concl === "PENDING" || (c.status ?? "").toUpperCase() === "IN_PROGRESS")
|
|
194
|
+
pending++;
|
|
195
|
+
else {
|
|
196
|
+
fail++;
|
|
197
|
+
failing.push(c.name ?? "unnamed");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
b.push(`${pass} passing · ${fail} failing · ${pending} pending${failing.length ? ` — failing: ${failing.join(", ")}` : ""}`);
|
|
201
|
+
}
|
|
202
|
+
const unresolved = threads.filter((t) => !t.isResolved);
|
|
203
|
+
b.push(`\n## External review threads (unresolved: ${unresolved.length})`);
|
|
204
|
+
if (unresolved.length === 0) {
|
|
205
|
+
b.push("none");
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
for (const t of unresolved.slice(0, 20)) {
|
|
209
|
+
const anchor = t.path ? `${t.path}${t.line ? `:${t.line}` : ""}` : "(top-level)";
|
|
210
|
+
b.push(`- ${anchor} @${t.author || "unknown"} — ${t.body.replace(/\s+/g, " ").slice(0, 140)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const evidence = extractEvidenceLines(pr.comments ?? []);
|
|
214
|
+
b.push("\n## Evidence / health");
|
|
215
|
+
if (input.features?.length) {
|
|
216
|
+
const touched = touchedFeatures(splitUnifiedDiff(diff).map((s) => s.path), input.features);
|
|
217
|
+
if (touched.length) {
|
|
218
|
+
b.push(`Features touched (${touched.length}): ${touched.join(", ")}`);
|
|
219
|
+
const cov = assessEvidenceCoverage(touched, pr.comments ?? []);
|
|
220
|
+
if (cov.warning)
|
|
221
|
+
b.push(cov.warning);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
b.push(evidence.length ? evidence.join("\n") : "no evidence caption posted");
|
|
225
|
+
// Features (relevant slice) — kills the reviewer's mandatory full-map pull:
|
|
226
|
+
// touched features in detail, same-layer neighbors by name, full map only
|
|
227
|
+
// on demand (issue #83).
|
|
228
|
+
if (input.features?.length) {
|
|
229
|
+
const diffPaths = splitUnifiedDiff(diff).map((s) => s.path);
|
|
230
|
+
const touchedNames = new Set(touchedFeatures(diffPaths, input.features));
|
|
231
|
+
if (touchedNames.size) {
|
|
232
|
+
const touched = input.features.filter((f) => touchedNames.has(f.name || f.key)).slice(0, 12);
|
|
233
|
+
b.push("\n## Features (relevant slice)");
|
|
234
|
+
for (const f of touched) {
|
|
235
|
+
const layer = f.layer ? ` [${f.layer}]` : "";
|
|
236
|
+
const tp = f.testPriority ? ` · test_priority: ${f.testPriority}` : "";
|
|
237
|
+
const desc = f.description ? ` — ${f.description}` : "";
|
|
238
|
+
b.push(`- ${f.name || f.key}${layer}${tp}${desc}`);
|
|
239
|
+
}
|
|
240
|
+
const layers = new Set(touched.map((f) => f.layer).filter(Boolean));
|
|
241
|
+
const neighbors = input.features
|
|
242
|
+
.filter((f) => !touchedNames.has(f.name || f.key) && f.layer && layers.has(f.layer))
|
|
243
|
+
.map((f) => f.name || f.key)
|
|
244
|
+
.slice(0, 15);
|
|
245
|
+
if (neighbors.length)
|
|
246
|
+
b.push(`Same-layer neighbors: ${neighbors.join(", ")}`);
|
|
247
|
+
b.push("_This slice replaces the full map for most reviews — run `renaiss-shipflow features --json` only if you need beyond it._");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const filtered = filterDiffForPacket(diff);
|
|
251
|
+
b.push(`\n## Diff (${filtered.shown} file(s) shown` +
|
|
252
|
+
(filtered.omittedNoise ? `, ${filtered.omittedNoise} noise file(s) omitted` : "") +
|
|
253
|
+
(filtered.omittedBudget ? `, ${filtered.omittedBudget} over budget` : "") +
|
|
254
|
+
(filtered.truncatedFiles ? `, ${filtered.truncatedFiles} truncated` : "") +
|
|
255
|
+
")");
|
|
256
|
+
b.push("```diff");
|
|
257
|
+
b.push(filtered.text);
|
|
258
|
+
b.push("```");
|
|
259
|
+
return b.join("\n");
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packet.js","sourceRoot":"","sources":["../src/packet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Unified verdict vocabulary. The loop reviewer's `approve`/`request_changes`/
|
|
2
|
+
* `reject` plus the server's advisory `comment`. */
|
|
3
|
+
export type Verdict = "approve" | "comment" | "request_changes" | "reject";
|
|
4
|
+
/** Severity badge — byte-identical to the server's severityBadge(). */
|
|
5
|
+
export declare function severityBadge(severity: string): string;
|
|
6
|
+
/** CodeRabbit-style fix-size tag after the badge — mirrors the server. */
|
|
7
|
+
export declare function effortTag(effort?: string): string;
|
|
8
|
+
/** Verdict header, shared by the inline review body and any fallback comment. */
|
|
9
|
+
export declare function verdictHeader(verdict: Verdict): string;
|
|
10
|
+
export interface ReviewFinding {
|
|
11
|
+
path: string;
|
|
12
|
+
line: number;
|
|
13
|
+
severity: string;
|
|
14
|
+
issue: string;
|
|
15
|
+
why?: string;
|
|
16
|
+
fix?: string;
|
|
17
|
+
effort?: string;
|
|
18
|
+
suggestion?: string;
|
|
19
|
+
code?: string;
|
|
20
|
+
}
|
|
21
|
+
/** One finding's comment body — mirrors renderInlineFinding(): badge + effort +
|
|
22
|
+
* issue, why, fix, and a committable ```suggestion block when present. */
|
|
23
|
+
export declare function renderFindingBody(f: ReviewFinding): string;
|
|
24
|
+
/** Repo-relative path in one canonical shape: forward slashes, no leading
|
|
25
|
+
* "./". Applied to both diff keys and finding paths so `./src/x` / `src\\x`
|
|
26
|
+
* still anchor. NOT a filesystem realpath — diff paths aren't fs paths. */
|
|
27
|
+
export declare function normPath(p: string): string;
|
|
28
|
+
/** Map of path → set of new-file line numbers that GitHub will accept a
|
|
29
|
+
* RIGHT-side inline comment on (context + added lines). Mirrors the server's
|
|
30
|
+
* annotatePatch line numbering so a bad anchor can't 422 the whole review. */
|
|
31
|
+
export declare function diffAnchors(diff: string): Map<string, Set<number>>;
|
|
32
|
+
/** Partition findings into ones that anchor to a real diff line (postable
|
|
33
|
+
* inline) and ones that must fold into the summary body (bad line / file). */
|
|
34
|
+
export declare function splitAnchorable(findings: ReviewFinding[], anchors: Map<string, Set<number>>): {
|
|
35
|
+
inline: ReviewFinding[];
|
|
36
|
+
body: ReviewFinding[];
|
|
37
|
+
};
|
|
38
|
+
export interface ReviewComment {
|
|
39
|
+
path: string;
|
|
40
|
+
line: number;
|
|
41
|
+
side: "RIGHT";
|
|
42
|
+
body: string;
|
|
43
|
+
}
|
|
44
|
+
export interface ReviewPayload {
|
|
45
|
+
event: "COMMENT";
|
|
46
|
+
body: string;
|
|
47
|
+
comments: ReviewComment[];
|
|
48
|
+
}
|
|
49
|
+
/** Build the GitHub "create review" payload: a COMMENT-event review (ShipFlow
|
|
50
|
+
* reviews are advisory — approval authority stays with the label gate, so the
|
|
51
|
+
* event is never APPROVE/REQUEST_CHANGES; the verdict lives in the header),
|
|
52
|
+
* with on-diff findings as inline comments and the rest folded into the body. */
|
|
53
|
+
export declare function buildReviewPayload(opts: {
|
|
54
|
+
summary: string;
|
|
55
|
+
verdict: Verdict;
|
|
56
|
+
findings: ReviewFinding[];
|
|
57
|
+
anchors: Map<string, Set<number>>;
|
|
58
|
+
}): ReviewPayload;
|
|
59
|
+
//# sourceMappingURL=review-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-contract.d.ts","sourceRoot":"","sources":["../src/review-contract.ts"],"names":[],"mappings":"AAKA;qDACqD;AACrD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAE3E,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOtD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID;2EAC2E;AAC3E,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAS1D;AAED;;4EAE4E;AAC5E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1C;AAKD;;+EAE+E;AAC/E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAkBlE;AAED;+EAC+E;AAC/E,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAChC;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,IAAI,EAAE,aAAa,EAAE,CAAA;CAAE,CAQpD;AAED,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAAE;AAC3F,MAAM,WAAW,aAAa;IAAG,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;CAAE;AAE7F;;;kFAGkF;AAClF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACnC,GAAG,aAAa,CAqBhB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// Canonical review contract shared by the loop reviewer (this CLI) — the
|
|
2
|
+
// single source of truth for verdict vocabulary, severity badges, finding
|
|
3
|
+
// rendering, and diff anchoring, mirroring the server's runner_pr_review.go so
|
|
4
|
+
// the two reviewers post CONSISTENTLY (epic #96). Pure + testable; no I/O.
|
|
5
|
+
/** Severity badge — byte-identical to the server's severityBadge(). */
|
|
6
|
+
export function severityBadge(severity) {
|
|
7
|
+
switch (severity.trim().toLowerCase()) {
|
|
8
|
+
case "critical": return "🔴 **critical**";
|
|
9
|
+
case "high": return "🟠 **high**";
|
|
10
|
+
case "low": return "🔵 **low**";
|
|
11
|
+
default: return "🟡 **medium**";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** CodeRabbit-style fix-size tag after the badge — mirrors the server. */
|
|
15
|
+
export function effortTag(effort) {
|
|
16
|
+
switch ((effort ?? "").trim().toLowerCase()) {
|
|
17
|
+
case "quick": return " · ⚡ quick fix";
|
|
18
|
+
case "involved": return " · 🔨 involved";
|
|
19
|
+
default: return "";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Verdict header, shared by the inline review body and any fallback comment. */
|
|
23
|
+
export function verdictHeader(verdict) {
|
|
24
|
+
switch (verdict) {
|
|
25
|
+
case "approve": return "**✅ APPROVE — ShipFlow review**";
|
|
26
|
+
case "request_changes": return "**🔴 CHANGES REQUESTED — ShipFlow review**";
|
|
27
|
+
case "reject": return "**⛔ REJECT — ShipFlow review**";
|
|
28
|
+
default: return "**💬 ShipFlow review — comments**";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const REVIEW_MARKER = "<!-- shipflow:loop-review -->";
|
|
32
|
+
/** One finding's comment body — mirrors renderInlineFinding(): badge + effort +
|
|
33
|
+
* issue, why, fix, and a committable ```suggestion block when present. */
|
|
34
|
+
export function renderFindingBody(f) {
|
|
35
|
+
let b = `${severityBadge(f.severity)}${effortTag(f.effort)} ${f.issue}`;
|
|
36
|
+
if (f.why?.trim())
|
|
37
|
+
b += `\n\n${f.why.trim()}`;
|
|
38
|
+
if (f.fix?.trim())
|
|
39
|
+
b += `\n\n**Fix:** ${f.fix.trim()}`;
|
|
40
|
+
const sug = (f.suggestion ?? "").replace(/\n+$/, "");
|
|
41
|
+
const code = (f.code ?? "").replace(/\n+$/, "");
|
|
42
|
+
if (sug.trim())
|
|
43
|
+
b += `\n\`\`\`suggestion\n${sug}\n\`\`\``;
|
|
44
|
+
else if (code.trim())
|
|
45
|
+
b += `\n\`\`\`\n${code}\n\`\`\``;
|
|
46
|
+
return `${b}\n\n${REVIEW_MARKER}`;
|
|
47
|
+
}
|
|
48
|
+
/** Repo-relative path in one canonical shape: forward slashes, no leading
|
|
49
|
+
* "./". Applied to both diff keys and finding paths so `./src/x` / `src\\x`
|
|
50
|
+
* still anchor. NOT a filesystem realpath — diff paths aren't fs paths. */
|
|
51
|
+
export function normPath(p) {
|
|
52
|
+
return p.replace(/\\/g, "/").replace(/^\.\//, "").trim();
|
|
53
|
+
}
|
|
54
|
+
const HUNK_RE = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
|
|
55
|
+
const FILE_RE = /^\+\+\+ b\/(.+)$/;
|
|
56
|
+
/** Map of path → set of new-file line numbers that GitHub will accept a
|
|
57
|
+
* RIGHT-side inline comment on (context + added lines). Mirrors the server's
|
|
58
|
+
* annotatePatch line numbering so a bad anchor can't 422 the whole review. */
|
|
59
|
+
export function diffAnchors(diff) {
|
|
60
|
+
const out = new Map();
|
|
61
|
+
let path = "";
|
|
62
|
+
let ln = 0;
|
|
63
|
+
for (const raw of diff.split(/\r?\n/)) {
|
|
64
|
+
const fm = FILE_RE.exec(raw);
|
|
65
|
+
if (fm) {
|
|
66
|
+
path = normPath(fm[1]);
|
|
67
|
+
ln = 0;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const hm = HUNK_RE.exec(raw);
|
|
71
|
+
if (hm) {
|
|
72
|
+
ln = parseInt(hm[1], 10);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!path || ln === 0)
|
|
76
|
+
continue;
|
|
77
|
+
if (raw.startsWith("-"))
|
|
78
|
+
continue; // removed: no RIGHT-side line
|
|
79
|
+
if (raw.startsWith("+") || raw.startsWith(" ")) {
|
|
80
|
+
if (!out.has(path))
|
|
81
|
+
out.set(path, new Set());
|
|
82
|
+
out.get(path).add(ln);
|
|
83
|
+
ln++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
/** Partition findings into ones that anchor to a real diff line (postable
|
|
89
|
+
* inline) and ones that must fold into the summary body (bad line / file). */
|
|
90
|
+
export function splitAnchorable(findings, anchors) {
|
|
91
|
+
const inline = [];
|
|
92
|
+
const body = [];
|
|
93
|
+
for (const f of findings) {
|
|
94
|
+
if (f.line > 0 && anchors.get(normPath(f.path))?.has(f.line))
|
|
95
|
+
inline.push(f);
|
|
96
|
+
else
|
|
97
|
+
body.push(f);
|
|
98
|
+
}
|
|
99
|
+
return { inline, body };
|
|
100
|
+
}
|
|
101
|
+
/** Build the GitHub "create review" payload: a COMMENT-event review (ShipFlow
|
|
102
|
+
* reviews are advisory — approval authority stays with the label gate, so the
|
|
103
|
+
* event is never APPROVE/REQUEST_CHANGES; the verdict lives in the header),
|
|
104
|
+
* with on-diff findings as inline comments and the rest folded into the body. */
|
|
105
|
+
export function buildReviewPayload(opts) {
|
|
106
|
+
const { inline, body: unanchored } = splitAnchorable(opts.findings, opts.anchors);
|
|
107
|
+
const lines = [verdictHeader(opts.verdict)];
|
|
108
|
+
if (opts.summary.trim())
|
|
109
|
+
lines.push("", opts.summary.trim());
|
|
110
|
+
if (unanchored.length) {
|
|
111
|
+
lines.push("", "**Further findings (outside the annotated diff lines):**");
|
|
112
|
+
for (const f of unanchored) {
|
|
113
|
+
const anchor = f.line > 0 ? `${f.path}:${f.line}` : f.path;
|
|
114
|
+
const fbLines = renderFindingBody(f).split("\n\n" + REVIEW_MARKER)[0].split("\n");
|
|
115
|
+
lines.push(`- \`${anchor}\` — ${fbLines[0]}`);
|
|
116
|
+
// Indent why/fix/suggestion continuation two spaces so GitHub keeps them
|
|
117
|
+
// nested under the bullet instead of rendering as top-level paragraphs.
|
|
118
|
+
for (let i = 1; i < fbLines.length; i++)
|
|
119
|
+
lines.push(fbLines[i] ? ` ${fbLines[i]}` : "");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
lines.push("", REVIEW_MARKER);
|
|
123
|
+
return {
|
|
124
|
+
event: "COMMENT",
|
|
125
|
+
body: lines.join("\n"),
|
|
126
|
+
comments: inline.map((f) => ({ path: f.path, line: f.line, side: "RIGHT", body: renderFindingBody(f) })),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=review-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-contract.js","sourceRoot":"","sources":["../src/review-contract.ts"],"names":[],"mappings":"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"}
|