pr-shepherd 0.10.3 → 0.12.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.
Files changed (37) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/README.md +51 -9
  3. package/bin/agent-runtime.mjs +7 -0
  4. package/bin/checks/triage.mjs +5 -46
  5. package/bin/cli/args.mjs +10 -2
  6. package/bin/cli/default-iterate.mjs +54 -0
  7. package/bin/cli/duration-flag.mjs +22 -0
  8. package/bin/cli/fix-formatter.mjs +25 -15
  9. package/bin/cli/formatters.mjs +26 -38
  10. package/bin/cli/handlers.mjs +26 -24
  11. package/bin/cli/iterate-formatter.mjs +14 -10
  12. package/bin/cli/iterate-instructions.mjs +75 -0
  13. package/bin/cli/iterate-lean.mjs +59 -6
  14. package/bin/cli/list-formatters.mjs +11 -0
  15. package/bin/cli-parser.iterate-fixtures.mjs +2 -0
  16. package/bin/cli-parser.mjs +15 -1
  17. package/bin/commands/check.mjs +6 -6
  18. package/bin/commands/commit-suggestion.mjs +34 -80
  19. package/bin/commands/iterate/classify.mjs +5 -4
  20. package/bin/commands/iterate/escalate.mjs +2 -1
  21. package/bin/commands/iterate/fix-code.mjs +16 -8
  22. package/bin/commands/iterate/helpers.mjs +34 -0
  23. package/bin/commands/iterate/index.mjs +2 -2
  24. package/bin/commands/iterate/render.mjs +25 -37
  25. package/bin/commands/iterate/stall.mjs +3 -1
  26. package/bin/commands/iterate.mjs +1 -1
  27. package/bin/commands/monitor.mjs +68 -17
  28. package/bin/commands/ready-delay.mjs +2 -1
  29. package/bin/commands/resolve-instructions.mjs +8 -4
  30. package/bin/commands/resolve.mjs +4 -4
  31. package/bin/config.json +1 -3
  32. package/bin/index.mjs +1 -0
  33. package/bin/reporters/agent.mjs +6 -2
  34. package/bin/reporters/check-instructions.mjs +11 -5
  35. package/bin/reporters/json.mjs +2 -2
  36. package/bin/reporters/text.mjs +24 -16
  37. package/package.json +3 -2
@@ -1,7 +1,7 @@
1
1
  import { buildCheckInstructions } from "./check-instructions.mjs";
2
- import { renderThreadBullet, renderCommentBullet, renderReviewBullet, renderFirstLookStatusTag, } from "../cli/list-formatters.mjs";
2
+ import { renderThreadBullet, renderCommentBullet, renderFirstLookStatusTag, renderReviewListSection, renderThreadResolutionStatusTag, } from "../cli/list-formatters.mjs";
3
3
  import { joinSections } from "../util/markdown.mjs";
4
- export function formatText(report) {
4
+ export function formatText(report, opts) {
5
5
  const header = [
6
6
  `# PR #${report.pr} [CHECK] — ${report.repo}`,
7
7
  `Status: ${report.status}`,
@@ -60,8 +60,11 @@ export function formatText(report) {
60
60
  ciSubsections.push(lines.join("\n"));
61
61
  }
62
62
  const ciSection = `## CI Checks\n\n${ciSubsections.join("\n\n")}`;
63
- const { actionable: actionableThreads, autoResolved, autoResolveErrors, firstLook: firstLookThreads, } = report.threads;
64
- const hasThreadSection = autoResolved.length > 0 || autoResolveErrors.length > 0 || actionableThreads.length > 0;
63
+ const { actionable: actionableThreads, resolutionOnly: resolutionOnlyThreads, autoResolved, autoResolveErrors, firstLook: firstLookThreads, } = report.threads;
64
+ const hasThreadSection = autoResolved.length > 0 ||
65
+ autoResolveErrors.length > 0 ||
66
+ actionableThreads.length > 0 ||
67
+ resolutionOnlyThreads.length > 0;
65
68
  let threadsSection = null;
66
69
  if (hasThreadSection) {
67
70
  const subparts = [];
@@ -86,6 +89,13 @@ export function formatText(report) {
86
89
  }
87
90
  subparts.push(lines.join("\n"));
88
91
  }
92
+ if (resolutionOnlyThreads.length > 0) {
93
+ const lines = [`### Needs resolution only (${resolutionOnlyThreads.length})`, ""];
94
+ for (const t of resolutionOnlyThreads) {
95
+ lines.push(renderThreadBullet(t, { statusTag: renderThreadResolutionStatusTag(t) }));
96
+ }
97
+ subparts.push(lines.join("\n"));
98
+ }
89
99
  threadsSection = `## Review Threads\n\n${subparts.join("\n\n")}`;
90
100
  }
91
101
  const { actionable: actionableComments, firstLook: firstLookComments } = report.comments;
@@ -97,15 +107,15 @@ export function formatText(report) {
97
107
  }
98
108
  commentsSection = `## PR Comments\n\n${lines.join("\n")}`;
99
109
  }
100
- const changesRequestedSection = reviewListSection("CHANGES_REQUESTED Reviews", report.changesRequestedReviews);
110
+ const changesRequestedSection = renderReviewListSection("CHANGES_REQUESTED Reviews", report.changesRequestedReviews);
101
111
  const allSummaries = [...report.firstLookSummaries, ...report.reviewSummaries];
102
- const reviewSummariesSection = reviewListSection("Review Summaries", allSummaries);
103
- const approvedReviewsSection = reviewListSection("Approved Reviews", report.approvedReviews);
112
+ const reviewSummariesSection = renderReviewListSection("Review Summaries", allSummaries);
113
+ const approvedReviewsSection = renderReviewListSection("Approved Reviews", report.approvedReviews);
104
114
  const firstLookTotal = firstLookThreads.length + firstLookComments.length;
105
115
  let firstLookSection = null;
106
116
  if (firstLookTotal > 0) {
107
117
  const lines = [
108
- `## First-look items (${firstLookTotal}) — already closed on GitHub; acknowledge only`,
118
+ `## First-look items (${firstLookTotal}) — acknowledge status before acting`,
109
119
  "",
110
120
  ];
111
121
  for (const t of firstLookThreads) {
@@ -117,15 +127,18 @@ export function formatText(report) {
117
127
  }
118
128
  firstLookSection = lines.join("\n");
119
129
  }
120
- const totalActionable = actionableThreads.length + actionableComments.length + report.changesRequestedReviews.length;
130
+ const totalActionable = actionableThreads.length +
131
+ resolutionOnlyThreads.length +
132
+ actionableComments.length +
133
+ report.changesRequestedReviews.length;
121
134
  const counts = [];
122
135
  if (totalActionable > 0)
123
136
  counts.push(`${totalActionable} actionable`);
124
137
  if (firstLookTotal > 0)
125
138
  counts.push(`${firstLookTotal} first-look`);
126
- const summaryLine = counts.join(", ") || "0 actionable — all threads resolved/minimized";
139
+ const summaryLine = counts.join(", ") || "0 actionable — no unresolved review items";
127
140
  const summarySection = `## Summary\n\n${summaryLine}`;
128
- const instructions = buildCheckInstructions(report);
141
+ const instructions = buildCheckInstructions(report, opts);
129
142
  const instructionsSection = `## Instructions\n\n${instructions.map((step, i) => `${i + 1}. ${step}`).join("\n")}`;
130
143
  return joinSections([
131
144
  header,
@@ -141,8 +154,3 @@ export function formatText(report) {
141
154
  instructionsSection,
142
155
  ]);
143
156
  }
144
- function reviewListSection(heading, items) {
145
- if (items.length === 0)
146
- return null;
147
- return `## ${heading}\n\n${items.map((r) => renderReviewBullet(r, { includeBody: true })).join("\n")}`;
148
- }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
- "version": "0.10.3",
4
- "description": "Autonomous PR CI monitor and review-comment resolver for Claude Code",
3
+ "version": "0.12.0",
4
+ "description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Ong",
7
7
  "type": "module",
@@ -49,6 +49,7 @@
49
49
  "ci",
50
50
  "code-review",
51
51
  "automation",
52
+ "codex",
52
53
  "claude",
53
54
  "claude-code"
54
55
  ],