pr-shepherd 0.31.1 → 0.32.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -0
- package/bin/cli/args.mjs +1 -0
- package/bin/cli/default-poll.mjs +1 -0
- package/bin/cli/help-command-pages.mjs +5 -18
- package/bin/cli/help-log-file-page.mjs +17 -0
- package/bin/cli/help-top-page.mjs +1 -0
- package/bin/cli/poll-handler.mjs +1 -0
- package/bin/commands/poll.mjs +25 -19
- package/package.json +2 -2
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -90,6 +90,7 @@ Direct CLI:
|
|
|
90
90
|
pr-shepherd 42 # poll until non-WAIT or timeout
|
|
91
91
|
pr-shepherd 42 --interval 60s --timeout 270s
|
|
92
92
|
pr-shepherd 42 --quiet-status # print only changed WAIT status snapshots
|
|
93
|
+
pr-shepherd 42 --until-terminal # continue through WAIT/MARK_READY until work or terminal state
|
|
93
94
|
pr-shepherd 42 --ready-delay 15m
|
|
94
95
|
pr-shepherd iterate 42 # single tick
|
|
95
96
|
pr-shepherd poll 42 # explicit poll command
|
package/bin/cli/args.mjs
CHANGED
package/bin/cli/default-poll.mjs
CHANGED
|
@@ -13,6 +13,7 @@ const DEFAULT_POLL_BOOLEAN_FLAGS = new Set([
|
|
|
13
13
|
"--no-auto-mark-ready",
|
|
14
14
|
"--no-auto-cancel-actionable",
|
|
15
15
|
"--quiet-status",
|
|
16
|
+
"--until-terminal",
|
|
16
17
|
]);
|
|
17
18
|
export function isDefaultPollInvocation(subcommand) {
|
|
18
19
|
if (subcommand === "--help" || subcommand === "-h")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LOG_FILE_USAGE } from "./help-log-file-page.mjs";
|
|
1
2
|
export const COMMAND_USAGE = {
|
|
2
3
|
resolve: `pr-shepherd resolve
|
|
3
4
|
|
|
@@ -103,7 +104,7 @@ Exit codes:
|
|
|
103
104
|
|
|
104
105
|
Run iterate repeatedly while the action is WAIT. Print only the final tick to stdout.
|
|
105
106
|
Poll exits as soon as iterate returns MARK_READY, FIX_CODE, CANCEL, or ESCALATE, or when timeout
|
|
106
|
-
returns the last WAIT result.
|
|
107
|
+
returns the last WAIT result. With --until-terminal, poll also continues through MARK_READY.
|
|
107
108
|
|
|
108
109
|
Usage:
|
|
109
110
|
pr-shepherd poll [PR] [poll-flags] [iterate-flags]
|
|
@@ -112,6 +113,7 @@ Poll flags:
|
|
|
112
113
|
--interval <duration> Sleep between WAIT ticks. Default: 60s.
|
|
113
114
|
--timeout <duration> Maximum wall-clock wait. Default: 4.5m.
|
|
114
115
|
--quiet-status During WAIT polling, print only changed status snapshots.
|
|
116
|
+
--until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.
|
|
115
117
|
|
|
116
118
|
Forwarded iterate flags:
|
|
117
119
|
--ready-delay <duration> Settle window before a clean PR cancels. Example: 15m.
|
|
@@ -124,6 +126,7 @@ Forwarded iterate flags:
|
|
|
124
126
|
|
|
125
127
|
Durations accept seconds, minutes, or hours: 30s, 4.5m, 1h, or bare seconds.
|
|
126
128
|
Each WAIT tick writes a single dot to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.
|
|
129
|
+
With --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, CANCEL, or ESCALATE.
|
|
127
130
|
|
|
128
131
|
Exit codes:
|
|
129
132
|
0 WAIT timeout or MARK_READY
|
|
@@ -173,21 +176,5 @@ Flags:
|
|
|
173
176
|
--help, -h Print this help and exit before any GitHub I/O.
|
|
174
177
|
|
|
175
178
|
Exit code: 0 on success (including no-change no-op); 1 on validation, lookup, or mutation failure.`,
|
|
176
|
-
"log-file":
|
|
177
|
-
|
|
178
|
-
Print the per-worktree append-only debug log path for the current repository.
|
|
179
|
-
The log is created by the first non-help pr-shepherd command that initializes logging.
|
|
180
|
-
|
|
181
|
-
Usage:
|
|
182
|
-
pr-shepherd log-file [--format text|json]
|
|
183
|
-
|
|
184
|
-
Flags:
|
|
185
|
-
--format text|json Print a raw path or {"path": "..."} JSON. Default: text.
|
|
186
|
-
--help, -h Print this help and exit before logging setup.
|
|
187
|
-
|
|
188
|
-
Environment:
|
|
189
|
-
PR_SHEPHERD_LOG_DISABLED=1 disables logging.
|
|
190
|
-
PR_SHEPHERD_STATE_DIR overrides the base state directory.
|
|
191
|
-
|
|
192
|
-
Exit code: 0 on success; 1 if repository identity cannot be resolved.`,
|
|
179
|
+
"log-file": LOG_FILE_USAGE,
|
|
193
180
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const LOG_FILE_USAGE = `pr-shepherd log-file
|
|
2
|
+
|
|
3
|
+
Print the per-worktree append-only debug log path for the current repository.
|
|
4
|
+
The log is created by the first non-help pr-shepherd command that initializes logging.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
pr-shepherd log-file [--format text|json]
|
|
8
|
+
|
|
9
|
+
Flags:
|
|
10
|
+
--format text|json Print a raw path or {"path": "..."} JSON. Default: text.
|
|
11
|
+
--help, -h Print this help and exit before logging setup.
|
|
12
|
+
|
|
13
|
+
Environment:
|
|
14
|
+
PR_SHEPHERD_LOG_DISABLED=1 disables logging.
|
|
15
|
+
PR_SHEPHERD_STATE_DIR overrides the base state directory.
|
|
16
|
+
|
|
17
|
+
Exit code: 0 on success; 1 if repository identity cannot be resolved.`;
|
|
@@ -45,6 +45,7 @@ Poll flags:
|
|
|
45
45
|
--interval <duration> Delay between WAIT ticks. Default: 60s.
|
|
46
46
|
--timeout <duration> Poll wall-clock cap. Default: 4.5m.
|
|
47
47
|
--quiet-status During WAIT polling, print only changed status snapshots.
|
|
48
|
+
--until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.
|
|
48
49
|
|
|
49
50
|
Clean variants:
|
|
50
51
|
pr [number] Remove state for one PR. Defaults to current branch PR.
|
package/bin/cli/poll-handler.mjs
CHANGED
package/bin/commands/poll.mjs
CHANGED
|
@@ -55,39 +55,45 @@ function writeWaitProgress(opts) {
|
|
|
55
55
|
return signature;
|
|
56
56
|
}
|
|
57
57
|
export async function runPoll(opts) {
|
|
58
|
-
const { intervalSeconds, timeoutSeconds, ...iterateOpts } = opts;
|
|
58
|
+
const { intervalSeconds, timeoutSeconds, quietStatus: quietStatusOpt, untilTerminal: untilTerminalOpt, ...iterateOpts } = opts;
|
|
59
59
|
const intervalMs = Math.min(intervalSeconds * 1000, MAX_TIMER_MS);
|
|
60
60
|
const timeoutMs = Math.min(timeoutSeconds * 1000, MAX_TIMER_MS);
|
|
61
61
|
const start = Date.now();
|
|
62
62
|
let tick = 0;
|
|
63
63
|
let lastResult;
|
|
64
64
|
const verbose = opts.verbose === true;
|
|
65
|
-
const quietStatus =
|
|
65
|
+
const quietStatus = quietStatusOpt === true;
|
|
66
|
+
const untilTerminal = untilTerminalOpt === true;
|
|
66
67
|
let dotsPrinted = false;
|
|
67
68
|
let lastWaitSignature = null;
|
|
68
69
|
while (true) {
|
|
69
70
|
tick += 1;
|
|
70
71
|
lastResult = await runIterate(iterateOpts);
|
|
71
|
-
if (lastResult.action !== "wait")
|
|
72
|
+
if (lastResult.action !== "wait" && !(untilTerminal && lastResult.action === "mark_ready")) {
|
|
72
73
|
break;
|
|
74
|
+
}
|
|
73
75
|
const elapsedMs = Date.now() - start;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
if (!untilTerminal) {
|
|
77
|
+
const remainingMs = timeoutMs - elapsedMs;
|
|
78
|
+
if (remainingMs <= 0)
|
|
79
|
+
break;
|
|
80
|
+
if (remainingMs + TIMER_DRIFT_TOLERANCE_MS < intervalMs)
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
79
83
|
const nextSleepMs = intervalMs;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
if (lastResult.action === "wait") {
|
|
85
|
+
lastWaitSignature = writeWaitProgress({
|
|
86
|
+
tick,
|
|
87
|
+
elapsedMs,
|
|
88
|
+
sleepMs: nextSleepMs,
|
|
89
|
+
result: lastResult,
|
|
90
|
+
quietStatus,
|
|
91
|
+
verbose,
|
|
92
|
+
lastWaitSignature,
|
|
93
|
+
});
|
|
94
|
+
if (!quietStatus && !verbose)
|
|
95
|
+
dotsPrinted = true;
|
|
96
|
+
}
|
|
91
97
|
await sleep(nextSleepMs);
|
|
92
98
|
}
|
|
93
99
|
if (dotsPrinted)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-shepherd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Jonathan Ong",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@vitest/coverage-v8": "^4.1.4",
|
|
39
39
|
"husky": "^9.1.7",
|
|
40
40
|
"knip": "^6.14.1",
|
|
41
|
-
"oxfmt": "^0.
|
|
41
|
+
"oxfmt": "^0.54.0",
|
|
42
42
|
"oxlint": "^1.60.0",
|
|
43
43
|
"typescript": "^6.0.3",
|
|
44
44
|
"vitest": "^4.1.4"
|
|
@@ -16,9 +16,9 @@ Poll dispatcher for iterating a PR to completion.
|
|
|
16
16
|
|
|
17
17
|
1. **Resolve the PR number** (`$N`): use the number or URL in `$ARGUMENTS`; otherwise infer it with `gh pr view --json number --jq .number`. If none is found, report an error and stop.
|
|
18
18
|
|
|
19
|
-
2. **Define the poll command once:** `pr-shepherd $N --interval 60s --
|
|
19
|
+
2. **Define the poll command once:** `pr-shepherd $N --interval 60s --until-terminal --quiet-status`. Do not forward `$ARGUMENTS` as extra flags. Run `pr-shepherd --help` to inspect supported options.
|
|
20
20
|
|
|
21
|
-
3. **Loop:** Run the poll, print its full output, and follow its `## Instructions` section exactly. Then run the poll again. Repeat until the CLI emits `[CANCEL]` or `[ESCALATE]`, unless the human directs you to stop.
|
|
21
|
+
3. **Loop:** Run the poll, print its full output, and follow its `## Instructions` section exactly. Then run the poll again. Repeat until the CLI emits `[CANCEL]` or `[ESCALATE]`, unless the human directs you to stop. `[FIX_CODE]` is non-terminal: do its instructions, then poll again. The poll already waits between ticks via `--interval`; do not add manual `sleep`s between ticks.
|
|
22
22
|
|
|
23
23
|
4. **Nonzero exit codes:** Treat a nonzero poll exit as PR state only when the output contains a matching `# PR #$N [ACTION]` heading. Exit `1` can also mean a command or validation failure; if there is no `[ACTION]` heading, surface the error and stop instead of looping.
|
|
24
24
|
|