@warpmetrics/review 0.1.6 → 0.1.8
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/package.json +1 -1
- package/src/review.js +34 -12
package/package.json
CHANGED
package/src/review.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'fs';
|
|
2
2
|
import { minimatch } from 'minimatch';
|
|
3
|
-
import { run, group, call, outcome, flush } from '@warpmetrics/warp';
|
|
3
|
+
import { run, group, call, outcome, act, flush } from '@warpmetrics/warp';
|
|
4
4
|
import { createClient } from './llm.js';
|
|
5
5
|
import { findRun } from './warpmetrics.js';
|
|
6
6
|
import {
|
|
@@ -59,11 +59,13 @@ async function llmWithRetry(anthropic, params, maxRetries = 3) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function buildSummary(commentsPosted, filesReviewed, runId, wmAvailable, { totalFiltered = 0, truncatedCount = 0 } = {}) {
|
|
62
|
+
function buildSummary(commentsPosted, filesReviewed, runId, wmAvailable, { totalFiltered = 0, truncatedCount = 0, actId } = {}) {
|
|
63
63
|
const analyticsLink = wmAvailable && runId
|
|
64
64
|
? `\n\n[View review analytics \u2192](https://app.warpmetrics.com/runs/${runId})`
|
|
65
65
|
: '';
|
|
66
66
|
|
|
67
|
+
const actTag = actId ? `\n\n<!-- wm:act:${actId} -->` : '';
|
|
68
|
+
|
|
67
69
|
const notes = [];
|
|
68
70
|
if (totalFiltered > filesReviewed) {
|
|
69
71
|
notes.push(`Reviewed ${filesReviewed}/${totalFiltered} files. Increase \`maxFilesPerReview\` in \`.warp-review/config.json\` to review more.`);
|
|
@@ -76,10 +78,10 @@ function buildSummary(commentsPosted, filesReviewed, runId, wmAvailable, { total
|
|
|
76
78
|
if (commentsPosted.length > 0) {
|
|
77
79
|
const fileCount = new Set(commentsPosted.map(c => c.file)).size;
|
|
78
80
|
const firstComment = commentsPosted[0].body.slice(0, 100);
|
|
79
|
-
return `**warp-review** found ${commentsPosted.length} issue(s) in ${fileCount} file(s).${notesText}\n\nMost critical: ${firstComment}${analyticsLink}\n\n<sub>Powered by [WarpMetrics](https://warpmetrics.com) \u00b7 Edit \`.warp-review/skills.md\` to customize</sub>`;
|
|
81
|
+
return `**warp-review** found ${commentsPosted.length} issue(s) in ${fileCount} file(s).${notesText}\n\nMost critical: ${firstComment}${analyticsLink}${actTag}\n\n<sub>Powered by [WarpMetrics](https://warpmetrics.com) \u00b7 Edit \`.warp-review/skills.md\` to customize</sub>`;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
return `**warp-review** reviewed ${filesReviewed} file(s) \u2014 no issues found.${notesText}${analyticsLink}\n\n<sub>Powered by [WarpMetrics](https://warpmetrics.com)</sub>`;
|
|
84
|
+
return `**warp-review** reviewed ${filesReviewed} file(s) \u2014 no issues found.${notesText}${analyticsLink}${actTag}\n\n<sub>Powered by [WarpMetrics](https://warpmetrics.com)</sub>`;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
export async function review(ctx) {
|
|
@@ -130,12 +132,18 @@ export async function review(ctx) {
|
|
|
130
132
|
}
|
|
131
133
|
runRef = runDetail.id;
|
|
132
134
|
} else {
|
|
133
|
-
// Create new run
|
|
135
|
+
// Create new run (link as follow-up if warp-coder act ID found in PR body)
|
|
134
136
|
if (wmAvailable) {
|
|
135
|
-
|
|
137
|
+
const actMatch = body.match(/<!-- wm:act:(wm_act_\w+) -->/);
|
|
138
|
+
const runOpts = {
|
|
136
139
|
name: `${fullRepo}#${pr}`, repo: fullRepo, pr, pr_url: htmlUrl,
|
|
137
140
|
pr_author: prAuthor, additions, deletions, changed_files: changedFiles, base_branch: baseBranch,
|
|
138
|
-
}
|
|
141
|
+
};
|
|
142
|
+
if (actMatch) {
|
|
143
|
+
runRef = run(actMatch[1], 'warp-review', runOpts);
|
|
144
|
+
} else {
|
|
145
|
+
runRef = run('warp-review', runOpts);
|
|
146
|
+
}
|
|
139
147
|
}
|
|
140
148
|
}
|
|
141
149
|
|
|
@@ -249,16 +257,30 @@ export async function review(ctx) {
|
|
|
249
257
|
|
|
250
258
|
// Derive runId for summary link
|
|
251
259
|
const runId = typeof runRef === 'string' ? runRef : runRef?.id;
|
|
260
|
+
const hasIssues = validComments.length > 0;
|
|
261
|
+
|
|
262
|
+
// 13. Log comment groups + outcome + act to WM (before posting review, so we know the act ID)
|
|
263
|
+
let reviewActId = null;
|
|
264
|
+
let commentIds = [];
|
|
252
265
|
|
|
253
|
-
|
|
266
|
+
if (round) {
|
|
267
|
+
// Outcome + act on the round (for the chain)
|
|
268
|
+
const outcomeName = hasIssues ? 'Changes Requested' : 'Approved';
|
|
269
|
+
const oc = outcome(round, outcomeName, { comments: validComments.length });
|
|
270
|
+
if (oc) {
|
|
271
|
+
const actRef = act(oc, hasIssues ? 'revise' : 'merge', { pr, repo: fullRepo });
|
|
272
|
+
if (actRef) reviewActId = actRef.id;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 14. Post review (with act ID embedded for warp-coder)
|
|
254
277
|
const summaryBody = buildSummary(validComments, filesToReview.length, runId, wmAvailable, {
|
|
255
|
-
totalFiltered: filtered.length, truncatedCount,
|
|
278
|
+
totalFiltered: filtered.length, truncatedCount, actId: reviewActId,
|
|
256
279
|
});
|
|
257
280
|
const reviewResult = await postReview(owner, repo, pr, headSha, summaryBody, validComments);
|
|
258
281
|
const reviewId = reviewResult.id;
|
|
259
282
|
|
|
260
|
-
//
|
|
261
|
-
let commentIds = [];
|
|
283
|
+
// 15. Get comment IDs (matched by array index order)
|
|
262
284
|
if (validComments.length > 0) {
|
|
263
285
|
try {
|
|
264
286
|
commentIds = await getReviewCommentIds(owner, repo, pr, reviewId);
|
|
@@ -267,7 +289,7 @@ export async function review(ctx) {
|
|
|
267
289
|
}
|
|
268
290
|
}
|
|
269
291
|
|
|
270
|
-
//
|
|
292
|
+
// 16. Log comment groups + summary to WM
|
|
271
293
|
if (round) {
|
|
272
294
|
for (let i = 0; i < validComments.length; i++) {
|
|
273
295
|
const c = validComments[i];
|