@h-rig/pr-review-plugin 0.0.6-alpha.157 → 0.0.6-alpha.158
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/src/index.js +28 -3
- package/dist/src/plugin.js +84 -7
- package/dist/src/pr-review-gate.d.ts +3 -2
- package/dist/src/pr-review-gate.js +28 -3
- package/package.json +3 -5
package/dist/src/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// packages/pr-review-plugin/src/pr-review-gate.ts
|
|
3
3
|
import { mkdirSync, writeFileSync } from "fs";
|
|
4
4
|
import { resolve } from "path";
|
|
5
|
-
import { safePathSegment } from "@rig/
|
|
6
|
-
import { resolveRuntimeSecrets } from "@rig/
|
|
5
|
+
import { safePathSegment } from "@rig/core/safe-identifiers";
|
|
6
|
+
import { resolveRuntimeSecrets } from "@rig/core/baked-secrets";
|
|
7
7
|
function parseJsonObject(value) {
|
|
8
8
|
if (!value?.trim())
|
|
9
9
|
return { value: {}, error: "empty JSON output" };
|
|
@@ -1385,7 +1385,7 @@ function persistPrReviewCycleArtifacts(input) {
|
|
|
1385
1385
|
async function runStrictPrMergeGate(input) {
|
|
1386
1386
|
const evidence = await collectPrReviewEvidence(input);
|
|
1387
1387
|
const base = evaluateStrictPrMergeGate(evidence, input.requireGreptile !== false);
|
|
1388
|
-
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base
|
|
1388
|
+
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base });
|
|
1389
1389
|
const artifacts = persistPrReviewCycleArtifacts({
|
|
1390
1390
|
projectRoot: input.projectRoot,
|
|
1391
1391
|
taskId: input.taskId,
|
|
@@ -1399,8 +1399,33 @@ async function runStrictPrMergeGate(input) {
|
|
|
1399
1399
|
writeFileSync(artifacts.steeringPromptPath, steeringPrompt, "utf8");
|
|
1400
1400
|
return { ...base, artifacts, steeringPrompt };
|
|
1401
1401
|
}
|
|
1402
|
+
function strictMergeHeadShaFromGate(result, prUrl, requireGreptile = false) {
|
|
1403
|
+
if (!result.approved) {
|
|
1404
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate is not approved.`);
|
|
1405
|
+
}
|
|
1406
|
+
if (result.evidence.prUrl !== prUrl) {
|
|
1407
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate evidence belongs to ${result.evidence.prUrl}.`);
|
|
1408
|
+
}
|
|
1409
|
+
const headSha = result.evidence.headSha?.trim();
|
|
1410
|
+
if (!headSha) {
|
|
1411
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate did not provide a current head SHA.`);
|
|
1412
|
+
}
|
|
1413
|
+
if (!/^[0-9a-f]{40}$/i.test(headSha)) {
|
|
1414
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate head is not a raw 40-character commit SHA.`);
|
|
1415
|
+
}
|
|
1416
|
+
if (requireGreptile) {
|
|
1417
|
+
if (!result.evidence.greptile.fresh || result.evidence.greptile.currentHeadSha !== headSha) {
|
|
1418
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate approval is not tied to head ${headSha}.`);
|
|
1419
|
+
}
|
|
1420
|
+
if (result.evidence.greptile.mapping !== "score-5-of-5" && result.evidence.greptile.mapping !== "explicit-approved") {
|
|
1421
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate mapping is ${result.evidence.greptile.mapping}.`);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return headSha;
|
|
1425
|
+
}
|
|
1402
1426
|
export {
|
|
1403
1427
|
stripHtml,
|
|
1428
|
+
strictMergeHeadShaFromGate,
|
|
1404
1429
|
runStrictPrMergeGate,
|
|
1405
1430
|
persistPrReviewCycleArtifacts,
|
|
1406
1431
|
parseGreptileScore,
|
package/dist/src/plugin.js
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
4
17
|
|
|
5
18
|
// packages/pr-review-plugin/src/pr-review-gate.ts
|
|
19
|
+
var exports_pr_review_gate = {};
|
|
20
|
+
__export(exports_pr_review_gate, {
|
|
21
|
+
stripHtml: () => stripHtml,
|
|
22
|
+
strictMergeHeadShaFromGate: () => strictMergeHeadShaFromGate,
|
|
23
|
+
runStrictPrMergeGate: () => runStrictPrMergeGate,
|
|
24
|
+
persistPrReviewCycleArtifacts: () => persistPrReviewCycleArtifacts,
|
|
25
|
+
parseGreptileScore: () => parseGreptileScore,
|
|
26
|
+
parseGithubPrUrl: () => parseGithubPrUrl,
|
|
27
|
+
isGreptileGithubLogin: () => isGreptileGithubLogin,
|
|
28
|
+
evaluateStrictPrMergeGate: () => evaluateStrictPrMergeGate,
|
|
29
|
+
deriveGreptileEvidence: () => deriveGreptileEvidence,
|
|
30
|
+
collectPrReviewEvidence: () => collectPrReviewEvidence,
|
|
31
|
+
buildStrictPrGateSteeringPrompt: () => buildStrictPrGateSteeringPrompt
|
|
32
|
+
});
|
|
6
33
|
import { mkdirSync, writeFileSync } from "fs";
|
|
7
34
|
import { resolve } from "path";
|
|
8
|
-
import { safePathSegment } from "@rig/
|
|
9
|
-
import { resolveRuntimeSecrets } from "@rig/
|
|
35
|
+
import { safePathSegment } from "@rig/core/safe-identifiers";
|
|
36
|
+
import { resolveRuntimeSecrets } from "@rig/core/baked-secrets";
|
|
10
37
|
function parseJsonObject(value) {
|
|
11
38
|
if (!value?.trim())
|
|
12
39
|
return { value: {}, error: "empty JSON output" };
|
|
@@ -1388,7 +1415,7 @@ function persistPrReviewCycleArtifacts(input) {
|
|
|
1388
1415
|
async function runStrictPrMergeGate(input) {
|
|
1389
1416
|
const evidence = await collectPrReviewEvidence(input);
|
|
1390
1417
|
const base = evaluateStrictPrMergeGate(evidence, input.requireGreptile !== false);
|
|
1391
|
-
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base
|
|
1418
|
+
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base });
|
|
1392
1419
|
const artifacts = persistPrReviewCycleArtifacts({
|
|
1393
1420
|
projectRoot: input.projectRoot,
|
|
1394
1421
|
taskId: input.taskId,
|
|
@@ -1402,9 +1429,52 @@ async function runStrictPrMergeGate(input) {
|
|
|
1402
1429
|
writeFileSync(artifacts.steeringPromptPath, steeringPrompt, "utf8");
|
|
1403
1430
|
return { ...base, artifacts, steeringPrompt };
|
|
1404
1431
|
}
|
|
1432
|
+
function strictMergeHeadShaFromGate(result, prUrl, requireGreptile = false) {
|
|
1433
|
+
if (!result.approved) {
|
|
1434
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate is not approved.`);
|
|
1435
|
+
}
|
|
1436
|
+
if (result.evidence.prUrl !== prUrl) {
|
|
1437
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate evidence belongs to ${result.evidence.prUrl}.`);
|
|
1438
|
+
}
|
|
1439
|
+
const headSha = result.evidence.headSha?.trim();
|
|
1440
|
+
if (!headSha) {
|
|
1441
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate did not provide a current head SHA.`);
|
|
1442
|
+
}
|
|
1443
|
+
if (!/^[0-9a-f]{40}$/i.test(headSha)) {
|
|
1444
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate head is not a raw 40-character commit SHA.`);
|
|
1445
|
+
}
|
|
1446
|
+
if (requireGreptile) {
|
|
1447
|
+
if (!result.evidence.greptile.fresh || result.evidence.greptile.currentHeadSha !== headSha) {
|
|
1448
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate approval is not tied to head ${headSha}.`);
|
|
1449
|
+
}
|
|
1450
|
+
if (result.evidence.greptile.mapping !== "score-5-of-5" && result.evidence.greptile.mapping !== "explicit-approved") {
|
|
1451
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate mapping is ${result.evidence.greptile.mapping}.`);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
return headSha;
|
|
1455
|
+
}
|
|
1456
|
+
var init_pr_review_gate = () => {};
|
|
1405
1457
|
|
|
1406
1458
|
// packages/pr-review-plugin/src/plugin.ts
|
|
1459
|
+
init_pr_review_gate();
|
|
1460
|
+
import { definePlugin } from "@rig/core/config";
|
|
1461
|
+
import { defineCapability } from "@rig/core/capability";
|
|
1462
|
+
import { PR_MERGE_GATE } from "@rig/contracts";
|
|
1407
1463
|
var PR_REVIEW_PLUGIN_ID = "@rig/pr-review-plugin";
|
|
1464
|
+
var PrMergeGateCap = defineCapability(PR_MERGE_GATE);
|
|
1465
|
+
function createPrMergeGateService() {
|
|
1466
|
+
return async () => {
|
|
1467
|
+
const gate = await Promise.resolve().then(() => (init_pr_review_gate(), exports_pr_review_gate));
|
|
1468
|
+
return {
|
|
1469
|
+
resolveHeadSha: ({ result, prUrl, requireGreptile }) => gate.strictMergeHeadShaFromGate(result, prUrl, requireGreptile),
|
|
1470
|
+
runGate: (input) => gate.runStrictPrMergeGate(input),
|
|
1471
|
+
collectEvidence: (input) => gate.collectPrReviewEvidence(input),
|
|
1472
|
+
evaluateGate: (evidence, requireGreptile) => gate.evaluateStrictPrMergeGate(evidence, requireGreptile),
|
|
1473
|
+
parseGreptileScore: (input) => gate.parseGreptileScore(input),
|
|
1474
|
+
stripHtml: (input) => gate.stripHtml(input)
|
|
1475
|
+
};
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1408
1478
|
function createPrReviewPlugin() {
|
|
1409
1479
|
return definePlugin({
|
|
1410
1480
|
name: PR_REVIEW_PLUGIN_ID,
|
|
@@ -1412,8 +1482,14 @@ function createPrReviewPlugin() {
|
|
|
1412
1482
|
provides: [],
|
|
1413
1483
|
contributes: {
|
|
1414
1484
|
capabilities: [
|
|
1415
|
-
{ id: "pr-review.strict-merge-gate", title: "Strict PR review / merge gate" }
|
|
1416
|
-
|
|
1485
|
+
{ id: "pr-review.strict-merge-gate", title: "Strict PR review / merge gate" },
|
|
1486
|
+
PrMergeGateCap.provide(createPrMergeGateService(), { title: "PR merge-gate service" })
|
|
1487
|
+
],
|
|
1488
|
+
config: {
|
|
1489
|
+
defaults: () => ({
|
|
1490
|
+
pr: { mode: "auto", watchChecks: true, autoFixChecks: true, autoFixReview: true }
|
|
1491
|
+
})
|
|
1492
|
+
}
|
|
1417
1493
|
}
|
|
1418
1494
|
});
|
|
1419
1495
|
}
|
|
@@ -1421,6 +1497,7 @@ var prReviewPlugin = createPrReviewPlugin();
|
|
|
1421
1497
|
var plugin_default = prReviewPlugin;
|
|
1422
1498
|
export {
|
|
1423
1499
|
stripHtml,
|
|
1500
|
+
strictMergeHeadShaFromGate,
|
|
1424
1501
|
runStrictPrMergeGate,
|
|
1425
1502
|
prReviewPlugin,
|
|
1426
1503
|
persistPrReviewCycleArtifacts,
|
|
@@ -31,9 +31,10 @@ export declare function persistPrReviewCycleArtifacts(input: {
|
|
|
31
31
|
readonly projectRoot: string;
|
|
32
32
|
readonly taskId: string;
|
|
33
33
|
readonly cycle: number;
|
|
34
|
-
readonly artifactRoot?: string | null;
|
|
34
|
+
readonly artifactRoot?: string | null | undefined;
|
|
35
35
|
readonly result: Omit<StrictPrMergeGateResult, "artifacts" | "steeringPrompt">;
|
|
36
36
|
readonly steeringPrompt: string;
|
|
37
|
-
readonly final?: boolean;
|
|
37
|
+
readonly final?: boolean | undefined;
|
|
38
38
|
}): PrReviewCycleArtifacts;
|
|
39
39
|
export declare function runStrictPrMergeGate(input: StrictPrMergeGateInput): Promise<StrictPrMergeGateResult>;
|
|
40
|
+
export declare function strictMergeHeadShaFromGate(result: StrictPrMergeGateResult, prUrl: string, requireGreptile?: boolean): string;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// packages/pr-review-plugin/src/pr-review-gate.ts
|
|
3
3
|
import { mkdirSync, writeFileSync } from "fs";
|
|
4
4
|
import { resolve } from "path";
|
|
5
|
-
import { safePathSegment } from "@rig/
|
|
6
|
-
import { resolveRuntimeSecrets } from "@rig/
|
|
5
|
+
import { safePathSegment } from "@rig/core/safe-identifiers";
|
|
6
|
+
import { resolveRuntimeSecrets } from "@rig/core/baked-secrets";
|
|
7
7
|
function parseJsonObject(value) {
|
|
8
8
|
if (!value?.trim())
|
|
9
9
|
return { value: {}, error: "empty JSON output" };
|
|
@@ -1385,7 +1385,7 @@ function persistPrReviewCycleArtifacts(input) {
|
|
|
1385
1385
|
async function runStrictPrMergeGate(input) {
|
|
1386
1386
|
const evidence = await collectPrReviewEvidence(input);
|
|
1387
1387
|
const base = evaluateStrictPrMergeGate(evidence, input.requireGreptile !== false);
|
|
1388
|
-
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base
|
|
1388
|
+
const preliminaryPrompt = buildStrictPrGateSteeringPrompt({ ...base });
|
|
1389
1389
|
const artifacts = persistPrReviewCycleArtifacts({
|
|
1390
1390
|
projectRoot: input.projectRoot,
|
|
1391
1391
|
taskId: input.taskId,
|
|
@@ -1399,8 +1399,33 @@ async function runStrictPrMergeGate(input) {
|
|
|
1399
1399
|
writeFileSync(artifacts.steeringPromptPath, steeringPrompt, "utf8");
|
|
1400
1400
|
return { ...base, artifacts, steeringPrompt };
|
|
1401
1401
|
}
|
|
1402
|
+
function strictMergeHeadShaFromGate(result, prUrl, requireGreptile = false) {
|
|
1403
|
+
if (!result.approved) {
|
|
1404
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate is not approved.`);
|
|
1405
|
+
}
|
|
1406
|
+
if (result.evidence.prUrl !== prUrl) {
|
|
1407
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate evidence belongs to ${result.evidence.prUrl}.`);
|
|
1408
|
+
}
|
|
1409
|
+
const headSha = result.evidence.headSha?.trim();
|
|
1410
|
+
if (!headSha) {
|
|
1411
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate did not provide a current head SHA.`);
|
|
1412
|
+
}
|
|
1413
|
+
if (!/^[0-9a-f]{40}$/i.test(headSha)) {
|
|
1414
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate head is not a raw 40-character commit SHA.`);
|
|
1415
|
+
}
|
|
1416
|
+
if (requireGreptile) {
|
|
1417
|
+
if (!result.evidence.greptile.fresh || result.evidence.greptile.currentHeadSha !== headSha) {
|
|
1418
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate approval is not tied to head ${headSha}.`);
|
|
1419
|
+
}
|
|
1420
|
+
if (result.evidence.greptile.mapping !== "score-5-of-5" && result.evidence.greptile.mapping !== "explicit-approved") {
|
|
1421
|
+
throw new Error(`Refusing to merge ${prUrl}: strict merge gate mapping is ${result.evidence.greptile.mapping}.`);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return headSha;
|
|
1425
|
+
}
|
|
1402
1426
|
export {
|
|
1403
1427
|
stripHtml,
|
|
1428
|
+
strictMergeHeadShaFromGate,
|
|
1404
1429
|
runStrictPrMergeGate,
|
|
1405
1430
|
persistPrReviewCycleArtifacts,
|
|
1406
1431
|
parseGreptileScore,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/pr-review-plugin",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.158",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Swappable strict PR review / merge-gate policy capability plugin for Rig.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
"module": "./dist/src/index.js",
|
|
26
26
|
"types": "./dist/src/index.d.ts",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.
|
|
29
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
30
|
-
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.157",
|
|
31
|
-
"@rig/shared": "npm:@h-rig/shared@0.0.6-alpha.157"
|
|
28
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.158",
|
|
29
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.158"
|
|
32
30
|
}
|
|
33
31
|
}
|