patchrelay 0.35.16 → 0.35.17

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.35.16",
4
- "commit": "1915fecc2b8c",
5
- "builtAt": "2026-04-08T09:31:00.146Z"
3
+ "version": "0.35.17",
4
+ "commit": "36da3600a7de",
5
+ "builtAt": "2026-04-08T09:35:21.098Z"
6
6
  }
@@ -7,6 +7,20 @@ import { execCommand } from "./utils.js";
7
7
  function isFailingCheckStatus(status) {
8
8
  return status === "failed" || status === "failure";
9
9
  }
10
+ function isReviewDecisionApproved(value) {
11
+ return value?.trim().toUpperCase() === "APPROVED";
12
+ }
13
+ function isReviewDecisionChangesRequested(value) {
14
+ return value?.trim().toUpperCase() === "CHANGES_REQUESTED";
15
+ }
16
+ function isReviewDecisionReviewRequired(value) {
17
+ return value?.trim().toUpperCase() === "REVIEW_REQUIRED";
18
+ }
19
+ function hasCompletedReviewQuillVerdict(entries) {
20
+ return (entries ?? []).some((entry) => entry.__typename === "CheckRun"
21
+ && entry.name === "review-quill/verdict"
22
+ && entry.status === "COMPLETED");
23
+ }
10
24
  function getGateCheckNames(project) {
11
25
  const configured = project?.gateChecks?.map((entry) => entry.trim()).filter(Boolean) ?? [];
12
26
  return configured.length > 0 ? configured : ["verify"];
@@ -370,11 +384,13 @@ export class IdleIssueReconciler {
370
384
  linearIssueId: issue.linearIssueId,
371
385
  ...(pr.headRefOid ? { prHeadSha: pr.headRefOid } : {}),
372
386
  ...(pr.state === "OPEN" ? { prState: "open" } : {}),
373
- ...(pr.reviewDecision === "APPROVED"
387
+ ...(isReviewDecisionApproved(pr.reviewDecision)
374
388
  ? { prReviewState: "approved" }
375
- : pr.reviewDecision === "CHANGES_REQUESTED"
389
+ : isReviewDecisionChangesRequested(pr.reviewDecision)
376
390
  ? { prReviewState: "changes_requested" }
377
- : {}),
391
+ : isReviewDecisionReviewRequired(pr.reviewDecision)
392
+ ? { prReviewState: "commented" }
393
+ : {}),
378
394
  ...(gateCheckStatus ? { prCheckStatus: gateCheckStatus } : {}),
379
395
  ...(pr.headRefOid && gateCheckStatus
380
396
  ? {
@@ -399,6 +415,22 @@ export class IdleIssueReconciler {
399
415
  });
400
416
  return;
401
417
  }
418
+ if (isReviewDecisionReviewRequired(pr.reviewDecision)
419
+ && gateCheckStatus === "success"
420
+ && hasCompletedReviewQuillVerdict(pr.statusCheckRollup)) {
421
+ this.logger.warn({ issueKey: issue.issueKey, prNumber: issue.prNumber, reviewDecision: pr.reviewDecision }, "Reconciliation: review-quill completed without a decisive GitHub review; escalating for operator input");
422
+ this.advanceIdleIssue(issue, "awaiting_input");
423
+ this.feed?.publish({
424
+ level: "warn",
425
+ kind: "github",
426
+ issueKey: issue.issueKey,
427
+ projectId: issue.projectId,
428
+ stage: "awaiting_input",
429
+ status: "non_decisive_review",
430
+ summary: `PR #${issue.prNumber} needs operator input: review-quill finished but GitHub still requires review`,
431
+ });
432
+ return;
433
+ }
402
434
  const downstreamOwned = issue.factoryState === "awaiting_queue" || issue.prReviewState === "approved" || pr.reviewDecision === "APPROVED";
403
435
  const mergeConflictDetected = pr.mergeable === "CONFLICTING" || pr.mergeStateStatus === "DIRTY";
404
436
  const refreshedIssue = this.db.getIssue(issue.projectId, issue.linearIssueId) ?? issue;
@@ -432,7 +464,7 @@ export class IdleIssueReconciler {
432
464
  });
433
465
  return;
434
466
  }
435
- if (pr.reviewDecision === "APPROVED") {
467
+ if (isReviewDecisionApproved(pr.reviewDecision)) {
436
468
  this.db.upsertIssue({
437
469
  projectId: issue.projectId,
438
470
  linearIssueId: issue.linearIssueId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.35.16",
3
+ "version": "0.35.17",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {