pr-shepherd 1.1.1 → 1.1.2

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,7 +1,7 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
3
  "description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
4
- "version": "1.1.1",
4
+ "version": "1.1.2",
5
5
  "author": {
6
6
  "name": "Jonathan Ong",
7
7
  "email": "jonathanrichardong@gmail.com"
@@ -14,14 +14,12 @@ export declare function hasCheckDrivenActionableWork(checks: {
14
14
  passing: ClassifiedCheck[];
15
15
  skipped: ClassifiedCheck[];
16
16
  filtered: ClassifiedCheck[];
17
- ignored?: TriagedCheck[];
18
17
  }, mergeStatusValue: string): boolean;
19
18
  export declare function attachAndMergeCheckAnnotations(buckets: {
20
19
  passing: ClassifiedCheck[];
21
20
  failing: TriagedCheck[];
22
21
  skipped: ClassifiedCheck[];
23
22
  filtered: ClassifiedCheck[];
24
- ignored: ClassifiedCheck[];
25
23
  }, seenMap: Map<string, {
26
24
  seenAt: number;
27
25
  }>, prNumber: number, cacheOpts?: AnnotationCacheOptions): Promise<{
@@ -29,6 +27,5 @@ export declare function attachAndMergeCheckAnnotations(buckets: {
29
27
  failing: TriagedCheck[];
30
28
  skipped: ClassifiedCheck[];
31
29
  filtered: ClassifiedCheck[];
32
- ignored: ClassifiedCheck[];
33
30
  }>;
34
31
  export declare function annotationMarkerBody(a: CheckAnnotation): string;
@@ -12,7 +12,6 @@ export function checksWithActionableAnnotations(report) {
12
12
  ...report.checks.passing,
13
13
  ...report.checks.skipped,
14
14
  ...report.checks.filtered,
15
- ...(report.checks.ignored ?? []),
16
15
  ].filter(hasActionableAnnotation);
17
16
  }
18
17
  /**
@@ -25,13 +24,7 @@ export function checksWithActionableAnnotations(report) {
25
24
  */
26
25
  export function hasCheckDrivenActionableWork(checks, mergeStatusValue) {
27
26
  return (checks.failing.length > 0 ||
28
- [
29
- ...checks.failing,
30
- ...checks.passing,
31
- ...checks.skipped,
32
- ...checks.filtered,
33
- ...(checks.ignored ?? []),
34
- ].some(hasActionableAnnotation) ||
27
+ [...checks.failing, ...checks.passing, ...checks.skipped, ...checks.filtered].some(hasActionableAnnotation) ||
35
28
  mergeStatusValue === "CONFLICTS");
36
29
  }
37
30
  export async function attachAndMergeCheckAnnotations(buckets, seenMap, prNumber, cacheOpts) {
@@ -40,7 +33,6 @@ export async function attachAndMergeCheckAnnotations(buckets, seenMap, prNumber,
40
33
  ...buckets.passing,
41
34
  ...buckets.skipped,
42
35
  ...buckets.filtered,
43
- ...buckets.ignored,
44
36
  ].filter(shouldFetchCheckAnnotations);
45
37
  const expectedCounts = new Map(candidates.flatMap((c) => c.id != null && c.annotationCount ? [[c.id, c.annotationCount]] : []));
46
38
  const annotated = await attachUnseenCheckAnnotations(candidates, seenMap, prNumber, cacheOpts && { ...cacheOpts, expectedCounts });
@@ -57,7 +49,6 @@ export async function attachAndMergeCheckAnnotations(buckets, seenMap, prNumber,
57
49
  failing: apply(buckets.failing),
58
50
  skipped: apply(buckets.skipped),
59
51
  filtered: apply(buckets.filtered),
60
- ignored: apply(buckets.ignored),
61
52
  };
62
53
  }
63
54
  async function attachUnseenCheckAnnotations(checks, seenMap, prNumber, cacheOpts) {
@@ -110,7 +110,7 @@ function reportChecks(report) {
110
110
  ...report.checks.inProgress,
111
111
  ...report.checks.skipped,
112
112
  ...report.checks.filtered,
113
- ...(report.checks.ignored ?? []),
113
+ ...(report.checks.ignoredNames ?? []).map((name) => ({ name })),
114
114
  ...(report.checks.supersededNames ?? []).map((name) => ({ name })),
115
115
  ];
116
116
  }
@@ -186,7 +186,6 @@ async function runScopedCheck(opts, context, repo, prNumber, stateKey) {
186
186
  const inProgress = classifiedChecks.filter((c) => c.category === "in_progress");
187
187
  const skipped = classifiedChecks.filter((c) => c.category === "skipped");
188
188
  const filtered = classifiedChecks.filter((c) => c.category === "filtered");
189
- const ignored = classifiedChecks.filter((c) => c.category === "ignored");
190
189
  const triagedBase = failing.length > 0 && !opts.skipTriage
191
190
  ? await triageFailingChecks(failing, repo, stateKey, triageBudget, classifiedChecks.filter((c) => c.category !== "failing"))
192
191
  : failing;
@@ -199,8 +198,7 @@ async function runScopedCheck(opts, context, repo, prNumber, stateKey) {
199
198
  const ruleSet = await loadClassifyRules(getEffectiveCwd(), config.standardRules);
200
199
  const classifyIndex = buildClassifyIndex(ruleSet, batchData);
201
200
  const partition = partitionBatch(classifyIndex, batchData);
202
- const merged = await attachAndMergeCheckAnnotations({ passing, failing: triagedBase, skipped, filtered, ignored }, seenMap, prNumber, { stateKey, headSha: batchData.headRefOid });
203
- const ignoredAnnotated = merged.ignored.filter((c) => (c.annotations?.length ?? 0) > 0);
201
+ const merged = await attachAndMergeCheckAnnotations({ passing, failing: triagedBase, skipped, filtered }, seenMap, prNumber, { stateKey, headSha: batchData.headRefOid });
204
202
  const minimizedCommentCandidates = batchData.comments.filter((c) => c.isMinimized && !partition.suppressedCommentIds.has(c.id));
205
203
  const deniedRuleAutoResolveCommentIds = new Set(partition.ruleAutoResolveCommentIds.filter((id) => !canGenerateItemMutation(id, batchData.comments.find((comment) => comment.id === id)?.body ?? "", batchData.comments.find((comment) => comment.id === id)?.viewerCanMinimize, "minimize")));
206
204
  const visibleCommentClassification = classifyVisibleComments(batchData.comments.filter((c) => !partition.suppressedCommentIds.has(c.id) || deniedRuleAutoResolveCommentIds.has(c.id)), seenMap, config.iterate["minimize-comments"], botUsernames, new Set(batchData.comments
@@ -301,7 +299,6 @@ async function runScopedCheck(opts, context, repo, prNumber, stateKey) {
301
299
  passing: merged.passing,
302
300
  skipped: merged.skipped,
303
301
  filtered: merged.filtered,
304
- ignored: merged.ignored,
305
302
  }, mergeStatus.status);
306
303
  // A deferred tick shows no review items, so it is never capped; its seen markers stay unwritten.
307
304
  const { buckets: budgeted, rollup: reviewItems, heldThreadReviewIds, } = applyReviewOutputBudget({
@@ -314,12 +311,7 @@ async function runScopedCheck(opts, context, repo, prNumber, stateKey) {
314
311
  editedComments,
315
312
  }, deferWhileQueued ? 0 : (opts.reviewOutputMaxChars ?? 0));
316
313
  if (opts.persistSeen !== false) {
317
- const successfulAnnotations = [
318
- ...merged.passing,
319
- ...merged.skipped,
320
- ...merged.filtered,
321
- ...merged.ignored,
322
- ]
314
+ const successfulAnnotations = [...merged.passing, ...merged.skipped, ...merged.filtered]
323
315
  .filter((check) => check.conclusion === "SUCCESS")
324
316
  .flatMap((check) => check.annotations ?? []);
325
317
  const deferredMarkSeen = deferWhileQueued
@@ -410,7 +402,6 @@ async function runScopedCheck(opts, context, repo, prNumber, stateKey) {
410
402
  inProgress: inProgress,
411
403
  skipped: merged.skipped,
412
404
  filtered: merged.filtered,
413
- ...(ignoredAnnotated.length > 0 && { ignored: ignoredAnnotated }),
414
405
  filteredNames: verdict.filteredNames,
415
406
  blockedByFilteredCheck,
416
407
  ...(verdict.ignoredNames.length > 0 && {
@@ -12,7 +12,7 @@ export declare function countReportedChecks(checks: {
12
12
  inProgress: readonly unknown[];
13
13
  skipped: readonly unknown[];
14
14
  filtered: readonly unknown[];
15
- ignored?: readonly unknown[];
15
+ ignoredNames?: readonly unknown[];
16
16
  }): number;
17
17
  /** Place the missing-CI note with the conflict step, ahead of later repair lines. */
18
18
  export declare function insertConflictingHeadCiNote(instructions: string[], note: string | undefined): void;
@@ -18,7 +18,7 @@ export function countReportedChecks(checks) {
18
18
  checks.inProgress.length +
19
19
  checks.skipped.length +
20
20
  checks.filtered.length +
21
- (checks.ignored?.length ?? 0));
21
+ (checks.ignoredNames?.length ?? 0));
22
22
  }
23
23
  /** Place the missing-CI note with the conflict step, ahead of later repair lines. */
24
24
  export function insertConflictingHeadCiNote(instructions, note) {
@@ -4,7 +4,7 @@ import type { RawSummaryPr } from "./poll-summary-raw.mts";
4
4
  type Routed = Pick<PollSummaryItem, "action" | "reasons">;
5
5
  /**
6
6
  * The one-PR check treats unseen annotations on any non-SUCCESS check (failing, skipped,
7
- * filtered, ignored or neutral) as actionable work. The compact summary only has annotation
7
+ * filtered or neutral) as actionable work; `checks.ignore` checks never gate, annotations included. The compact summary only has annotation
8
8
  * totals, and only for a row that otherwise claims readiness, so it loads them then and reads
9
9
  * the annotations of just the non-SUCCESS checks that have any. A row with unseen annotations,
10
10
  * or whose annotations cannot be read, goes to its one-PR `pollCommand` instead of
@@ -11,7 +11,7 @@ const READY_CLAIMS = new Set([
11
11
  ]);
12
12
  /**
13
13
  * The one-PR check treats unseen annotations on any non-SUCCESS check (failing, skipped,
14
- * filtered, ignored or neutral) as actionable work. The compact summary only has annotation
14
+ * filtered or neutral) as actionable work; `checks.ignore` checks never gate, annotations included. The compact summary only has annotation
15
15
  * totals, and only for a row that otherwise claims readiness, so it loads them then and reads
16
16
  * the annotations of just the non-SUCCESS checks that have any. A row with unseen annotations,
17
17
  * or whose annotations cannot be read, goes to its one-PR `pollCommand` instead of
@@ -44,7 +44,7 @@ function nonSuccessCheckTotals(raw, required, totalsKnown) {
44
44
  for (const check of classifiedSummaryChecks(raw, required)) {
45
45
  if (check.scope || check.id == null || !head.has(check.id))
46
46
  continue;
47
- if (check.category === "in_progress" || check.category === "superseded")
47
+ if (["in_progress", "superseded", "ignored"].includes(check.category))
48
48
  continue;
49
49
  if (check.status !== "COMPLETED" || check.conclusion === "SUCCESS")
50
50
  continue;
@@ -69,8 +69,6 @@ export interface ShepherdReport {
69
69
  skipped: ClassifiedCheck[];
70
70
  /** Checks filtered out because they were triggered by a non-PR event (push, schedule, etc.). */
71
71
  filtered: ClassifiedCheck[];
72
- /** Ignored checks with unseen annotations; omitted when empty. */
73
- ignored?: ClassifiedCheck[];
74
72
  filteredNames: string[];
75
73
  blockedByFilteredCheck: boolean;
76
74
  ignoredNames?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
5
5
  "keywords": [
6
6
  "automation",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
3
  "description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
4
- "version": "1.1.1",
4
+ "version": "1.1.2",
5
5
  "author": {
6
6
  "name": "Jonathan Ong",
7
7
  "email": "jonathanrichardong@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Autonomous PR CI monitor and review-comment resolver for Codex.",
5
5
  "author": {
6
6
  "name": "Jonathan Ong",
@@ -2,7 +2,7 @@
2
2
  "mcpServers": {
3
3
  "pr-shepherd": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "pr-shepherd@1.1.1", "pr-shepherd-mcp"]
5
+ "args": ["--yes", "--package", "pr-shepherd@1.1.2", "pr-shepherd-mcp"]
6
6
  }
7
7
  }
8
8
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "pr-shepherd": {
3
3
  "command": "npx",
4
- "args": ["--yes", "--package", "pr-shepherd@1.1.1", "pr-shepherd-mcp"]
4
+ "args": ["--yes", "--package", "pr-shepherd@1.1.2", "pr-shepherd-mcp"]
5
5
  }
6
6
  }