pr-shepherd 0.10.1 → 0.10.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 Claude Code",
4
- "version": "0.10.1",
4
+ "version": "0.10.2",
5
5
  "author": {
6
6
  "name": "Jonathan Ong",
7
7
  "email": "jonathanrichardong@gmail.com"
package/README.md CHANGED
@@ -29,12 +29,12 @@ At a high level, to start the monitor, the skill/command invokes a CLI that retu
29
29
 
30
30
  # PR #123 [MONITOR]
31
31
 
32
- Loop tag: `# pr-shepherd-loop:pr=123`
33
- Loop args: `4m --max-turns 50 --expires 8h`
32
+ Loop tag: `#pr-shepherd-loop:pr=123:`
33
+ Loop args: `4m`
34
34
 
35
35
  ## Loop prompt
36
36
 
37
- # pr-shepherd-loop:pr=123
37
+ #pr-shepherd-loop:pr=123:
38
38
 
39
39
  **IMPORTANT — recurrence rules:** Do not call ScheduleWakeup or /loop. End the turn
40
40
  after completing the actions below. The cron job handles the next fire.
@@ -125,7 +125,9 @@ Some other workflow improvements:
125
125
 
126
126
  Recommendations:
127
127
 
128
- - Run `pr-shepherd` on all your PRs before you go to sleep so that you wake up to reviewable PRs. As it uses `/loop`, it will continue working when your rate limit window is reset. There is a default timeout of 8 hours and 50 loops before exiting automatically.
128
+ - Run `pr-shepherd` on all your PRs before you go to sleep so that you wake up to reviewable PRs. As it uses `/loop`, it will continue working when your rate limit window is reset. The loop cancels automatically when the PR is merged, closed, or after the ready-delay elapses.
129
+ - Instruct your agents to write comments in a single review (comment, changes requested, or approved). This allows the review's comments/threads to be minimized or resolved together, keeping your pull request history clean. If you write inline comments outside of a review, each comment would still show up in the pull request history and take up space.
130
+ - Avoid sticky comments as they will continue to be hidden. Instead, just make a new comment, especially on reviews. If you really want sticky comments, instruct your agent to unhide/unminimize them when updating them.
129
131
 
130
132
  ## Design Principles
131
133
 
@@ -6,16 +6,10 @@ export async function runMonitor(opts) {
6
6
  if (prNumber === null) {
7
7
  throw new Error("No open PR found for current branch. Pass a PR number explicitly.");
8
8
  }
9
- const { interval, maxTurns, expiresHours } = config.watch;
9
+ const { interval } = config.watch;
10
10
  if (typeof interval !== "string" || !/^\d+[smhd]$/.test(interval)) {
11
11
  throw new Error(`Invalid config: watch.interval must be a duration string like "4m" or "1h", got ${JSON.stringify(interval)}`);
12
12
  }
13
- if (!Number.isFinite(expiresHours) || expiresHours <= 0 || !Number.isInteger(expiresHours)) {
14
- throw new Error(`Invalid config: watch.expiresHours must be a positive integer, got ${JSON.stringify(expiresHours)}`);
15
- }
16
- if (!Number.isFinite(maxTurns) || maxTurns <= 0 || !Number.isInteger(maxTurns)) {
17
- throw new Error(`Invalid config: watch.maxTurns must be a positive integer, got ${JSON.stringify(maxTurns)}`);
18
- }
19
13
  // No space after `#` — `# text` is a CommonMark ATX heading; `#text` is not.
20
14
  // Trailing `:` prevents substring false positives: without it, the dedup grep
21
15
  // for pr=1 would match a cron prompt for pr=135. Both the CronList check in
@@ -23,7 +17,7 @@ export async function runMonitor(opts) {
23
17
  // block depend on this exact string — don't change the format.
24
18
  const loopTag = `#pr-shepherd-loop:pr=${prNumber}:`;
25
19
  const loopPrompt = buildLoopPrompt(prNumber, loopTag, opts.readyDelaySuffix);
26
- const loopArgs = `${interval} --max-turns ${maxTurns} --expires ${expiresHours}h`;
20
+ const loopArgs = interval;
27
21
  return { prNumber, loopTag, loopArgs, loopPrompt };
28
22
  }
29
23
  // ---------------------------------------------------------------------------
@@ -44,7 +38,7 @@ export function formatMonitorResult(result) {
44
38
  "## Instructions",
45
39
  "",
46
40
  `1. Run \`CronList\`. If any job's prompt contains \`${loopTag}\`, run the \`## Loop prompt\` body once inline (as if it were a cron tick) then stop — do not create a duplicate loop.`,
47
- `2. Otherwise, invoke the \`/loop\` skill via the Skill tool. Build the \`args\` parameter as: only the value inside the backticks on the \`Loop args\` line above (the interval/flags string — not the \`Loop args:\` label), then a blank line, then the full \`## Loop prompt\` body.`,
41
+ `2. Otherwise, invoke the \`/loop\` skill via the Skill tool. Build the \`args\` parameter as: only the value inside the backticks on the \`Loop args\` line above (the interval — not the \`Loop args:\` label), then a blank line, then the full \`## Loop prompt\` body.`,
48
42
  ].join("\n");
49
43
  }
50
44
  // ---------------------------------------------------------------------------
package/bin/config.json CHANGED
@@ -7,9 +7,7 @@
7
7
  },
8
8
  "watch": {
9
9
  "interval": "4m",
10
- "readyDelayMinutes": 10,
11
- "expiresHours": 8,
12
- "maxTurns": 50
10
+ "readyDelayMinutes": 10
13
11
  },
14
12
  "resolve": {
15
13
  "shaPoll": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pr-shepherd",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Autonomous PR CI monitor and review-comment resolver for Claude Code",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Ong",