pr-shepherd 0.41.0 → 0.43.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 +14 -9
- package/bin/api.d.mts +12 -1
- package/bin/api.mjs +34 -1
- package/bin/checks/classify.d.mts +3 -1
- package/bin/checks/classify.mjs +5 -2
- package/bin/cli/args.mjs +1 -0
- package/bin/cli/default-poll.mjs +1 -0
- package/bin/cli/fix-formatter.mjs +12 -2
- package/bin/cli/formatters.d.mts +2 -1
- package/bin/cli/formatters.mjs +33 -0
- package/bin/cli/handlers.d.mts +1 -0
- package/bin/cli/handlers.mjs +21 -1
- package/bin/cli/help-command-pages.d.mts +22 -6
- package/bin/cli/help-command-pages.mjs +20 -4
- package/bin/cli/help-iterate-poll-pages.d.mts +2 -2
- package/bin/cli/help-iterate-poll-pages.mjs +7 -2
- package/bin/cli/help-top-page.d.mts +1 -1
- package/bin/cli/help-top-page.mjs +3 -3
- package/bin/cli/help.d.mts +23 -7
- package/bin/cli/iterate-flags.d.mts +1 -0
- package/bin/cli/iterate-flags.mjs +2 -0
- package/bin/cli/iterate-formatter.mjs +4 -1
- package/bin/cli/iterate-instructions.mjs +15 -0
- package/bin/cli/iterate-lean.d.mts +1 -2
- package/bin/cli/iterate-lean.mjs +12 -17
- package/bin/cli/iterate-merge-formatter.d.mts +3 -0
- package/bin/cli/iterate-merge-formatter.mjs +52 -0
- package/bin/cli/iterate-verbose.d.mts +6 -0
- package/bin/cli/iterate-verbose.mjs +14 -0
- package/bin/cli/poll-handler.mjs +1 -0
- package/bin/cli/runner.mjs +4 -3
- package/bin/cli/suggestion-patch-flags.d.mts +11 -0
- package/bin/cli/suggestion-patch-flags.mjs +83 -0
- package/bin/cli-parser.mjs +6 -2
- package/bin/commands/check-terminal-report.mjs +1 -0
- package/bin/commands/check.mjs +42 -1
- package/bin/commands/commit-suggestion-instruction.d.mts +1 -1
- package/bin/commands/commit-suggestion-instruction.mjs +3 -3
- package/bin/commands/commit-suggestion.d.mts +1 -1
- package/bin/commands/commit-suggestion.mjs +19 -138
- package/bin/commands/iterate/base.d.mts +5 -0
- package/bin/commands/iterate/base.mjs +25 -0
- package/bin/commands/iterate/escalate.d.mts +3 -1
- package/bin/commands/iterate/escalate.mjs +18 -2
- package/bin/commands/iterate/fix-code.mjs +16 -0
- package/bin/commands/iterate/helpers.mjs +6 -2
- package/bin/commands/iterate/index.mjs +29 -35
- package/bin/commands/iterate/merge-state.d.mts +15 -0
- package/bin/commands/iterate/merge-state.mjs +53 -0
- package/bin/commands/iterate/merge.d.mts +13 -0
- package/bin/commands/iterate/merge.mjs +46 -0
- package/bin/commands/poll.mjs +3 -1
- package/bin/commands/suggestion-patch-git.d.mts +6 -0
- package/bin/commands/suggestion-patch-git.mjs +54 -0
- package/bin/commands/suggestion-patch-item.d.mts +15 -0
- package/bin/commands/suggestion-patch-item.mjs +106 -0
- package/bin/commands/suggestion-patches.d.mts +6 -0
- package/bin/commands/suggestion-patches.mjs +108 -0
- package/bin/config/load.d.mts +4 -0
- package/bin/config/load.mjs +34 -0
- package/bin/config/merge-command-args.d.mts +2 -0
- package/bin/config/merge-command-args.mjs +44 -0
- package/bin/config.json +3 -0
- package/bin/exit-codes.d.mts +2 -0
- package/bin/exit-codes.mjs +4 -0
- package/bin/github/batch-parse-checks.d.mts +3 -0
- package/bin/github/batch-parse-checks.mjs +29 -0
- package/bin/github/batch-parsers-rules.d.mts +3 -1
- package/bin/github/batch-parsers-rules.mjs +33 -0
- package/bin/github/batch-parsers.mjs +23 -26
- package/bin/github/batch-raw-rules.d.mts +48 -0
- package/bin/github/batch-raw-types.mjs +0 -1
- package/bin/github/batch.mjs +2 -0
- package/bin/github/gql/batch-pr.gql +92 -0
- package/bin/github/gql/commit-check-contexts.gql +58 -0
- package/bin/github/gql/{commit-suggestion-thread.gql → suggestion-threads.gql} +2 -2
- package/bin/github/merge-queue-checks.d.mts +4 -0
- package/bin/github/merge-queue-checks.mjs +48 -0
- package/bin/github/queries.d.mts +3 -1
- package/bin/github/queries.mjs +3 -1
- package/bin/github/suggestion-thread.d.mts +3 -3
- package/bin/github/suggestion-thread.mjs +8 -5
- package/bin/mcp/server.d.mts +1 -1
- package/bin/mcp/server.mjs +24 -3
- package/bin/reporters/agent.mjs +6 -3
- package/bin/types/activity.d.mts +2 -0
- package/bin/types/escalate.d.mts +30 -0
- package/bin/types/escalate.mjs +1 -0
- package/bin/types/github.d.mts +8 -0
- package/bin/types/github.mjs +0 -3
- package/bin/types/iterate.d.mts +14 -31
- package/bin/types/merge-action.d.mts +12 -0
- package/bin/types/merge-action.mjs +1 -0
- package/bin/types/merge-queue.d.mts +13 -0
- package/bin/types/merge-queue.mjs +1 -0
- package/bin/types/merge-requirements.d.mts +17 -0
- package/bin/types/report.d.mts +8 -19
- package/bin/types/suggestion-patch.d.mts +30 -0
- package/bin/types/suggestion-patch.mjs +1 -0
- package/bin/types.d.mts +4 -0
- package/bin/types.mjs +4 -0
- package/bin/util/markdown.d.mts +2 -0
- package/bin/util/markdown.mjs +7 -0
- package/package.json +1 -1
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
- package/plugins/pr-shepherd/.codex.mcp.json +1 -1
- package/plugins/pr-shepherd/.mcp.json +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +11 -10
package/README.md
CHANGED
|
@@ -9,14 +9,14 @@ An agent finishing a PR should think about code, not reconstruct GitHub state or
|
|
|
9
9
|
## What it does
|
|
10
10
|
|
|
11
11
|
1. **Gather all context for a PR** in one invocation: review threads, comments, replies, summaries, CI, mergeability, merge requirements, first-look / outdated / edited items, and author provenance.
|
|
12
|
-
2. **Provide deterministic actions for the agent**: exactly one of `WAIT`, `MARK_READY`, `FIX_CODE`, `CANCEL`, or `ESCALATE`, plus numbered `## Instructions` and explicit
|
|
12
|
+
2. **Provide deterministic actions for the agent**: exactly one of `WAIT`, `MARK_READY`, `FIX_CODE`, `MERGE`, `CANCEL`, or `ESCALATE`, plus numbered `## Instructions` and explicit commands. The agent still decides whether a comment or CI failure needs a code change. Shepherd does not classify signal vs noise and does not mutate git.
|
|
13
13
|
|
|
14
14
|
Highlights:
|
|
15
15
|
|
|
16
16
|
- Batched GraphQL reads and writes (plus REST where GraphQL cannot) so one poll replaces a tool-call fan-out. MCP `iterate` is one tick and the client owns recurrence; `--debounce` is a poll-dispatcher settle window, not an MCP tool.
|
|
17
17
|
- CI summaries include failed checks, and the failed job/step plus a log excerpt when triage can fetch them. Job and log details are omitted for `STARTUP_FAILURE` and `CANCELLED`; agents may still inspect logs.
|
|
18
18
|
- Handles GitHub comment types (comments, threads, replies) and their states, including first-look, outdated, resolved, minimized, and edited.
|
|
19
|
-
- `apply` batches resolve / reply / minimize / dismiss. `
|
|
19
|
+
- `apply` batches resolve / reply / minimize / dismiss. `build_suggestion_patches` validates and returns ordered diffs without mutating git.
|
|
20
20
|
- `BEHIND` is mergeability information, not a rebase or a guarantee that the next push is at the default-branch tip. The agent can update the branch before pushing.
|
|
21
21
|
|
|
22
22
|
Full reference: [docs/README.md](docs/README.md). Feature matrix: [docs/features.md](docs/features.md).
|
|
@@ -25,13 +25,14 @@ Full reference: [docs/README.md](docs/README.md). Feature matrix: [docs/features
|
|
|
25
25
|
|
|
26
26
|
`pr-shepherd` moves deterministic PR orchestration into a local MCP server, with a CLI for shells and CI. Both interfaces fetch the same GitHub state, emit raw-enough context, and return a numbered plan for the calling agent to follow.
|
|
27
27
|
|
|
28
|
-
The MCP server exposes
|
|
28
|
+
The MCP server exposes canonical `iterate`, `apply`, and `build_suggestion_patches` tools. `apply` accepts ordered review mutations, file-view mutations, and journal entries; the deprecated singular suggestion tool remains temporarily as an adapter. Direct MCP calls require a repository-qualified `pr`: a GitHub PR URL or `owner/repo#N`, matching the repository where the server started. The CLI and programmatic API also retain bare-number and current-branch PR discovery. The shipped skills are thin dispatchers for those tools.
|
|
29
29
|
|
|
30
30
|
Each tick returns exactly one action:
|
|
31
31
|
|
|
32
32
|
- `WAIT` — no immediate action; continue with the next poll.
|
|
33
33
|
- `MARK_READY` — the CLI converted an eligible draft PR to ready; continue polling.
|
|
34
34
|
- `FIX_CODE` — agent work is required; complete it, then continue polling.
|
|
35
|
+
- `MERGE` — run the emitted auto-merge or merge-queue command, then continue polling.
|
|
35
36
|
- `CANCEL` — stop polling because the PR merged, closed, or completed its ready-delay.
|
|
36
37
|
- `ESCALATE` — stop polling until a human provides direction.
|
|
37
38
|
|
|
@@ -76,7 +77,7 @@ Conversations Resolved: No [Not Required]
|
|
|
76
77
|
9. `[FIX_CODE]` is non-terminal. After completing these steps, iterate again with the same options to continue.
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
See [docs/actions.md](docs/actions.md) for the complete output contract. Iterate/poll PR outcomes use exit codes `0` and `10`–`
|
|
80
|
+
See [docs/actions.md](docs/actions.md) for the complete output contract. Iterate/poll PR outcomes use exit codes `0` and `10`–`15`; command and GitHub failures use `sysexits.h` codes — [docs/exit-codes.md](docs/exit-codes.md).
|
|
80
81
|
|
|
81
82
|
## Workflow Assumptions
|
|
82
83
|
|
|
@@ -88,7 +89,7 @@ This system is opinionated and works best with PRs that use required status chec
|
|
|
88
89
|
- Every review thread/comment/review summary is surfaced at least once, even if already outdated, resolved, or minimized; edited items re-surface through seen markers.
|
|
89
90
|
- Draft PRs can be marked ready automatically when clean; disable with `actions.autoMarkReady: false` or `--no-auto-mark-ready`.
|
|
90
91
|
- The CLI never performs git mutations. It emits instructions; the caller commits, rebases, pushes, and handles repository hooks.
|
|
91
|
-
- `
|
|
92
|
+
- `build_suggestion_patches` turns one or more ordered GitHub suggestion threads into checked patches and commit metadata, but never edits the working tree or git history. Local HEAD may be ahead when the live PR head is its ancestor.
|
|
92
93
|
|
|
93
94
|
## Usage
|
|
94
95
|
|
|
@@ -115,7 +116,7 @@ Grok:
|
|
|
115
116
|
/pr-shepherd 42
|
|
116
117
|
```
|
|
117
118
|
|
|
118
|
-
MCP clients call `iterate` once per tick, then use `apply` for review/file/journal mutations and `
|
|
119
|
+
MCP clients call `iterate` once per tick, then use `apply` for review/file/journal mutations and `build_suggestion_patches` for anchored suggestions. Every direct MCP call supplies the same repository-qualified PR reference. `iterate` returns the same structured action data as the CLI, including its review mutation arguments. The client owns recurrence, so this works consistently in Codex, Claude Code, Grok, and any other stdio MCP client.
|
|
119
120
|
|
|
120
121
|
The CLI remains useful for shell workflows. Its canonical polling form is:
|
|
121
122
|
|
|
@@ -126,12 +127,13 @@ pr-shepherd 42 --quiet-status # print only changed WAIT status snapshot
|
|
|
126
127
|
pr-shepherd 42 --until-terminal # continue through WAIT/MARK_READY until work or terminal state
|
|
127
128
|
pr-shepherd 42 --debounce 5m # wait 5m after first FIX_CODE, then return one batched tick
|
|
128
129
|
pr-shepherd 42 --ready-delay 15m
|
|
130
|
+
pr-shepherd 42 --merge # enable auto-merge or enter an enabled/required merge queue when ready
|
|
129
131
|
pr-shepherd iterate 42 # single tick
|
|
130
132
|
```
|
|
131
133
|
|
|
132
134
|
### Apply Review, File, And Journal Changes
|
|
133
135
|
|
|
134
|
-
Use `apply` with ordered operations to reply/resolve/minimize/dismiss review items, mark changed files viewed, or append an idempotent Shepherd Journal item. Use `
|
|
136
|
+
Use `apply` with ordered operations to reply/resolve/minimize/dismiss review items, mark changed files viewed, or append an idempotent Shepherd Journal item. Use `build_suggestion_patches` to turn ordered review suggestions into checked patches and commit metadata; it never changes the worktree or git history.
|
|
135
137
|
|
|
136
138
|
### Extract Shepherd Journal Entries
|
|
137
139
|
|
|
@@ -236,7 +238,10 @@ checks:
|
|
|
236
238
|
ciTriggerEvents:
|
|
237
239
|
- pull_request
|
|
238
240
|
- pull_request_target
|
|
239
|
-
|
|
241
|
+
merge:
|
|
242
|
+
commandArgs:
|
|
243
|
+
- --squash
|
|
244
|
+
- --delete-branch
|
|
240
245
|
actions:
|
|
241
246
|
autoMinimizeSuppressed: true
|
|
242
247
|
autoMarkReady: false
|
|
@@ -276,7 +281,7 @@ Ready-to-use examples for common patterns are in [`examples/classification/`](ex
|
|
|
276
281
|
|
|
277
282
|
## CLI aliases
|
|
278
283
|
|
|
279
|
-
`poll`, `resolve`, `commit-suggestion`, `mark-files-as-viewed`, `journal`, `clean`, and `log-file` are CLI aliases. Prefer default polling/`iterate` in a shell and the MCP `iterate`, `apply`, and `
|
|
284
|
+
`poll`, `resolve`, `build-suggestion-patch`, `commit-suggestion`, `mark-files-as-viewed`, `journal`, `clean`, and `log-file` are CLI aliases or deprecated adapters. Prefer default polling/`iterate` in a shell and the MCP `iterate`, `apply`, and `build_suggestion_patches` tools in an agent client.
|
|
280
285
|
|
|
281
286
|
## Requirements
|
|
282
287
|
|
package/bin/api.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type JournalResult } from "./commands/journal/index.mts";
|
|
2
2
|
import { type MarkFilesAsViewedResult } from "./commands/mark-files-as-viewed.mts";
|
|
3
3
|
import type { ResolveResult } from "./comments/resolve.mts";
|
|
4
|
-
import type { CommitSuggestionResult, IterateCommandOptions, IterateResult } from "./types.mts";
|
|
4
|
+
import type { BuildSuggestionPatchesResult, CommitSuggestionResult, IterateCommandOptions, IterateResult } from "./types.mts";
|
|
5
5
|
export interface CreatePrShepherdOptions {
|
|
6
6
|
/** Working directory used for git, config, and classification-rule lookups. */
|
|
7
7
|
cwd?: string;
|
|
@@ -58,9 +58,20 @@ export interface BuildSuggestionPatchInput {
|
|
|
58
58
|
message: string;
|
|
59
59
|
description?: string;
|
|
60
60
|
}
|
|
61
|
+
export interface SuggestionPatchInput {
|
|
62
|
+
threadId: string;
|
|
63
|
+
message: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface BuildSuggestionPatchesInput {
|
|
67
|
+
pr?: PrReference;
|
|
68
|
+
suggestions: SuggestionPatchInput[];
|
|
69
|
+
}
|
|
61
70
|
export interface PrShepherd {
|
|
62
71
|
iterate(input?: IterateInput): Promise<IterateResult>;
|
|
63
72
|
apply(input: ApplyInput): Promise<ApplyResult>;
|
|
73
|
+
buildSuggestionPatches(input: BuildSuggestionPatchesInput): Promise<BuildSuggestionPatchesResult>;
|
|
74
|
+
/** Compatibility adapter; prefer buildSuggestionPatches. */
|
|
64
75
|
buildSuggestionPatch(input: BuildSuggestionPatchInput): Promise<CommitSuggestionResult>;
|
|
65
76
|
}
|
|
66
77
|
/** Raised before any API mutation when an input cannot be validated. */
|
package/bin/api.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { runCommitSuggestion } from "./commands/commit-suggestion.mjs";
|
|
4
|
+
import { runSuggestionPatches } from "./commands/suggestion-patches.mjs";
|
|
4
5
|
import { runIterate } from "./commands/iterate/index.mjs";
|
|
5
6
|
import { runJournal } from "./commands/journal/index.mjs";
|
|
6
7
|
import { validateJournalItem } from "./commands/journal/transform.mjs";
|
|
@@ -101,6 +102,14 @@ export function createPrShepherd(options = {}) {
|
|
|
101
102
|
return runCommitSuggestion({ ...options, prNumber, format: "json" });
|
|
102
103
|
});
|
|
103
104
|
},
|
|
105
|
+
buildSuggestionPatches(input) {
|
|
106
|
+
validateSuggestionPatchesInput(input);
|
|
107
|
+
const { pr: _pr, ...options } = input;
|
|
108
|
+
return runWithExecutionCwd(cwd, async () => {
|
|
109
|
+
const prNumber = await resolvePrReference(input.pr);
|
|
110
|
+
return runSuggestionPatches({ ...options, prNumber, format: "json" });
|
|
111
|
+
});
|
|
112
|
+
},
|
|
104
113
|
});
|
|
105
114
|
}
|
|
106
115
|
function validateApplyInput(input) {
|
|
@@ -184,7 +193,7 @@ function validateMarkFilesViewed(operation) {
|
|
|
184
193
|
}
|
|
185
194
|
}
|
|
186
195
|
function validateSuggestionPatchInput(input) {
|
|
187
|
-
if (!input || typeof input.threadId !== "string" || input.threadId === "") {
|
|
196
|
+
if (!input || typeof input.threadId !== "string" || input.threadId.trim() === "") {
|
|
188
197
|
throw new PrShepherdValidationError("buildSuggestionPatch.threadId is required");
|
|
189
198
|
}
|
|
190
199
|
if (typeof input.message !== "string" || input.message.trim() === "") {
|
|
@@ -195,6 +204,30 @@ function validateSuggestionPatchInput(input) {
|
|
|
195
204
|
}
|
|
196
205
|
validatePrReference(input.pr);
|
|
197
206
|
}
|
|
207
|
+
function validateSuggestionPatchesInput(input) {
|
|
208
|
+
if (!input || !Array.isArray(input.suggestions) || input.suggestions.length === 0) {
|
|
209
|
+
throw new PrShepherdValidationError("buildSuggestionPatches.suggestions must be a non-empty array");
|
|
210
|
+
}
|
|
211
|
+
const seen = new Set();
|
|
212
|
+
for (const suggestion of input.suggestions) {
|
|
213
|
+
if (!suggestion ||
|
|
214
|
+
typeof suggestion.threadId !== "string" ||
|
|
215
|
+
suggestion.threadId.trim() === "") {
|
|
216
|
+
throw new PrShepherdValidationError("each suggestion.threadId is required");
|
|
217
|
+
}
|
|
218
|
+
if (typeof suggestion.message !== "string" || suggestion.message.trim() === "") {
|
|
219
|
+
throw new PrShepherdValidationError("each suggestion.message must be non-empty");
|
|
220
|
+
}
|
|
221
|
+
if (suggestion.description !== undefined && typeof suggestion.description !== "string") {
|
|
222
|
+
throw new PrShepherdValidationError("each suggestion.description must be a string");
|
|
223
|
+
}
|
|
224
|
+
if (seen.has(suggestion.threadId)) {
|
|
225
|
+
throw new PrShepherdValidationError(`duplicate suggestion thread ID: ${suggestion.threadId}`);
|
|
226
|
+
}
|
|
227
|
+
seen.add(suggestion.threadId);
|
|
228
|
+
}
|
|
229
|
+
validatePrReference(input.pr);
|
|
230
|
+
}
|
|
198
231
|
function validatePrReference(pr) {
|
|
199
232
|
const parsed = parsePrReference(pr);
|
|
200
233
|
if (parsed !== null)
|
|
@@ -20,7 +20,9 @@ import type { CheckRun, ClassifiedCheck } from "../types.mts";
|
|
|
20
20
|
* @param checks Raw check runs from the batch query.
|
|
21
21
|
* @returns Classified checks. "filtered" items were excluded from the tally.
|
|
22
22
|
*/
|
|
23
|
-
export declare function classifyChecks(checks: CheckRun[]
|
|
23
|
+
export declare function classifyChecks(checks: CheckRun[], opts?: {
|
|
24
|
+
additionalRelevantEvents?: string[];
|
|
25
|
+
}): ClassifiedCheck[];
|
|
24
26
|
export interface CiVerdict {
|
|
25
27
|
/** True when all relevant (non-filtered, non-skipped, non-ignored) checks passed. */
|
|
26
28
|
allPassed: boolean;
|
package/bin/checks/classify.mjs
CHANGED
|
@@ -22,9 +22,12 @@ import picomatch from "picomatch";
|
|
|
22
22
|
* @param checks Raw check runs from the batch query.
|
|
23
23
|
* @returns Classified checks. "filtered" items were excluded from the tally.
|
|
24
24
|
*/
|
|
25
|
-
export function classifyChecks(checks) {
|
|
25
|
+
export function classifyChecks(checks, opts = {}) {
|
|
26
26
|
const config = loadConfig();
|
|
27
|
-
const relevantEvents = new Set(
|
|
27
|
+
const relevantEvents = new Set([
|
|
28
|
+
...config.checks.ciTriggerEvents,
|
|
29
|
+
...(opts.additionalRelevantEvents ?? []),
|
|
30
|
+
]);
|
|
28
31
|
const isIgnored = buildMatcher(config.ignoreChecks ?? []);
|
|
29
32
|
const isProtected = buildMatcher(config.actions.neverCancelRuns ?? []);
|
|
30
33
|
const protectedRunIds = buildProtectedRunIds(checks, isProtected);
|
package/bin/cli/args.mjs
CHANGED
package/bin/cli/default-poll.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { renderResolveCommand } from "../commands/iterate/render.mjs";
|
|
2
|
-
import { joinSections } from "../util/markdown.mjs";
|
|
2
|
+
import { inlineCode, joinSections } from "../util/markdown.mjs";
|
|
3
3
|
import { renderSuggestionBlock, renderLineRange } from "./suggestion-renderer.mjs";
|
|
4
4
|
import { renderThreadBullet, renderReviewBullet, renderThreadResolutionStatusTag, renderAuthor, buildFirstLookBullets, renderThreadConversation, blockquote, } from "./list-formatters.mjs";
|
|
5
5
|
import { numberInstructions } from "./iterate-instructions.mjs";
|
|
6
6
|
import { renderCheckAnnotation, renderProtectedRun } from "./fix-formatter-extra.mjs";
|
|
7
7
|
import { isFailingAgentCheck } from "../checks/conclusions.mjs";
|
|
8
|
+
import { renderMergeCommand } from "../commands/iterate/merge.mjs";
|
|
8
9
|
export function formatFixCodeResult(header, result) {
|
|
9
10
|
const sections = [header];
|
|
10
11
|
if (result.fix.threads.length > 0) {
|
|
@@ -50,7 +51,10 @@ export function formatFixCodeResult(header, result) {
|
|
|
50
51
|
? `external \`${ch.detailsUrl}\``
|
|
51
52
|
: "(no runId)";
|
|
52
53
|
const conclusionTag = ch.conclusion !== null ? ` [conclusion: ${ch.conclusion}]` : "";
|
|
53
|
-
const
|
|
54
|
+
const scopeTag = ch.scope
|
|
55
|
+
? ` [scope: ${ch.scope}${ch.commitOid ? `, commit: ${ch.commitOid}` : ""}]`
|
|
56
|
+
: "";
|
|
57
|
+
const lines = [`- ${locator} — \`${workflowPrefix}${jobLabel}\`${conclusionTag}${scopeTag}`];
|
|
54
58
|
if (ch.conclusion !== "CANCELLED") {
|
|
55
59
|
if (ch.failedStep)
|
|
56
60
|
lines.push(` > ${ch.failedStep}`);
|
|
@@ -133,6 +137,12 @@ export function formatFixCodeResult(header, result) {
|
|
|
133
137
|
if (result.fix.resolveCommand.hasMutations) {
|
|
134
138
|
postFixLines.push(`- apply review: \`${renderResolveCommand(result.fix.resolveCommand)}\``);
|
|
135
139
|
}
|
|
140
|
+
if (result.fix.requeue) {
|
|
141
|
+
postFixLines.push(`- requeue: ${inlineCode(renderMergeCommand(result.fix.requeue.command))}`);
|
|
142
|
+
if (result.fix.requeue.queueApiFallbackCommand) {
|
|
143
|
+
postFixLines.push(`- requeue API fallback: ${inlineCode(renderMergeCommand(result.fix.requeue.queueApiFallbackCommand))}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
136
146
|
sections.push(postFixLines.join("\n"));
|
|
137
147
|
sections.push("## Instructions");
|
|
138
148
|
sections.push(numberInstructions(result.fix.instructions));
|
package/bin/cli/formatters.d.mts
CHANGED
|
@@ -3,5 +3,6 @@ export { projectIterateLean, projectIterateVerbose } from "./iterate-lean.mts";
|
|
|
3
3
|
export { formatCleanResult } from "./clean-formatter.mts";
|
|
4
4
|
export { formatMarkFilesAsViewedResult } from "./mark-files-as-viewed-formatter.mts";
|
|
5
5
|
export { formatMutateResult } from "./mutate-formatter.mts";
|
|
6
|
-
import type { CommitSuggestionResult } from "../types.mts";
|
|
6
|
+
import type { BuildSuggestionPatchesResult, CommitSuggestionResult } from "../types.mts";
|
|
7
|
+
export declare function formatSuggestionPatchesResult(result: BuildSuggestionPatchesResult): string;
|
|
7
8
|
export declare function formatCommitSuggestionResult(result: CommitSuggestionResult): string;
|
package/bin/cli/formatters.mjs
CHANGED
|
@@ -4,6 +4,14 @@ export { formatCleanResult } from "./clean-formatter.mjs";
|
|
|
4
4
|
export { formatMarkFilesAsViewedResult } from "./mark-files-as-viewed-formatter.mjs";
|
|
5
5
|
export { formatMutateResult } from "./mutate-formatter.mjs";
|
|
6
6
|
import { safeFence } from "./fence.mjs";
|
|
7
|
+
export function formatSuggestionPatchesResult(result) {
|
|
8
|
+
const lines = [`Suggestion patches for PR #${result.pr}:`, ` repo: ${result.repo}`];
|
|
9
|
+
result.patches.forEach((patch, index) => {
|
|
10
|
+
lines.push("", ...formatPatch(patch, `## Patch ${index + 1}`).split("\n"));
|
|
11
|
+
});
|
|
12
|
+
appendInstructions(lines, result.postActionInstructions);
|
|
13
|
+
return lines.join("\n");
|
|
14
|
+
}
|
|
7
15
|
export function formatCommitSuggestionResult(result) {
|
|
8
16
|
const lines = [];
|
|
9
17
|
const range = result.startLine === result.endLine
|
|
@@ -30,3 +38,28 @@ export function formatCommitSuggestionResult(result) {
|
|
|
30
38
|
}
|
|
31
39
|
return lines.join("\n");
|
|
32
40
|
}
|
|
41
|
+
function formatPatch(patch, heading) {
|
|
42
|
+
const range = patch.startLine === patch.endLine
|
|
43
|
+
? `line ${patch.startLine}`
|
|
44
|
+
: `lines ${patch.startLine}–${patch.endLine}`;
|
|
45
|
+
const lines = [
|
|
46
|
+
heading,
|
|
47
|
+
"",
|
|
48
|
+
`Suggestion from @${patch.author} — thread ${patch.threadId}:`,
|
|
49
|
+
` ${patch.path} (${range})`,
|
|
50
|
+
];
|
|
51
|
+
if (patch.patch) {
|
|
52
|
+
const fence = safeFence(patch.patch);
|
|
53
|
+
lines.push("", `${fence}diff`, patch.patch.trimEnd(), fence);
|
|
54
|
+
}
|
|
55
|
+
lines.push("", "### Suggested commit message", "", patch.commitMessage, "", patch.commitBody);
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
58
|
+
function appendInstructions(lines, instructions) {
|
|
59
|
+
if (instructions.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
lines.push("", "## Instructions", "");
|
|
62
|
+
instructions.forEach((instruction, index) => {
|
|
63
|
+
lines.push(`${index + 1}. ${instruction}`);
|
|
64
|
+
});
|
|
65
|
+
}
|
package/bin/cli/handlers.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function handleClean(args: string[], command?: "admin clean" | "clean"): Promise<void>;
|
|
2
2
|
export declare function handleCommitSuggestion(args: string[], command?: "build-suggestion-patch" | "commit-suggestion"): Promise<void>;
|
|
3
|
+
export declare function handleSuggestionPatches(args: string[]): Promise<void>;
|
|
3
4
|
export declare function handleIterate(args: string[]): Promise<void>;
|
|
4
5
|
export declare function handleMarkFilesAsViewed(args: string[], command?: "apply files" | "mark-files-as-viewed"): Promise<void>;
|
package/bin/cli/handlers.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runCommitSuggestion } from "../commands/commit-suggestion.mjs";
|
|
2
|
+
import { runSuggestionPatches } from "../commands/suggestion-patches.mjs";
|
|
2
3
|
import { runMarkFilesAsViewed } from "../commands/mark-files-as-viewed.mjs";
|
|
3
4
|
import { runIterate } from "../commands/iterate/index.mjs";
|
|
4
5
|
import { runClean } from "../commands/clean.mjs";
|
|
@@ -6,7 +7,8 @@ import { loadConfig } from "../config/load.mjs";
|
|
|
6
7
|
import { EXIT } from "../exit-codes.mjs";
|
|
7
8
|
import { parseCommonArgs, getFlag } from "./args.mjs";
|
|
8
9
|
import { USAGE } from "./help.mjs";
|
|
9
|
-
import { formatCommitSuggestionResult, formatCleanResult, formatMarkFilesAsViewedResult, } from "./formatters.mjs";
|
|
10
|
+
import { formatCommitSuggestionResult, formatSuggestionPatchesResult, formatCleanResult, formatMarkFilesAsViewedResult, } from "./formatters.mjs";
|
|
11
|
+
import { parseSuggestionPatchGroups } from "./suggestion-patch-flags.mjs";
|
|
10
12
|
import { parseIterateFlags } from "./iterate-flags.mjs";
|
|
11
13
|
import { emitIterateResult } from "./iterate-emitter.mjs";
|
|
12
14
|
import { parseMarkFilesAsViewedArgs } from "./mark-files-as-viewed-flags.mjs";
|
|
@@ -92,6 +94,23 @@ export async function handleCommitSuggestion(args, command = "build-suggestion-p
|
|
|
92
94
|
? `${JSON.stringify(result, null, 2)}\n`
|
|
93
95
|
: `${formatCommitSuggestionResult(result)}\n`);
|
|
94
96
|
}
|
|
97
|
+
export async function handleSuggestionPatches(args) {
|
|
98
|
+
const { prNumber, global: globalOpts, extra } = parseCommonArgs(args);
|
|
99
|
+
const parsed = parseSuggestionPatchGroups(extra);
|
|
100
|
+
if (!parsed.ok) {
|
|
101
|
+
process.stderr.write(`${parsed.error}\n${USAGE["build-suggestion-patches"]}\n`);
|
|
102
|
+
process.exitCode = EXIT.USAGE;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const result = await runSuggestionPatches({
|
|
106
|
+
...globalOpts,
|
|
107
|
+
prNumber,
|
|
108
|
+
suggestions: parsed.suggestions,
|
|
109
|
+
});
|
|
110
|
+
process.stdout.write(globalOpts.format === "json"
|
|
111
|
+
? `${JSON.stringify(result, null, 2)}\n`
|
|
112
|
+
: `${formatSuggestionPatchesResult(result)}\n`);
|
|
113
|
+
}
|
|
95
114
|
export async function handleIterate(args) {
|
|
96
115
|
const { prNumber, global: globalOpts, extra } = parseCommonArgs(args);
|
|
97
116
|
const cfg = loadConfig();
|
|
@@ -105,6 +124,7 @@ export async function handleIterate(args) {
|
|
|
105
124
|
stallTimeoutSeconds: flags.stallTimeoutSeconds,
|
|
106
125
|
noAutoMarkReady: flags.noAutoMarkReady,
|
|
107
126
|
noAutoCancelActionable: flags.noAutoCancelActionable,
|
|
127
|
+
merge: flags.merge,
|
|
108
128
|
});
|
|
109
129
|
emitIterateResult(result, {
|
|
110
130
|
format: globalOpts.format,
|
|
@@ -61,11 +61,27 @@ PR may be a number or GitHub pull request URL. An item must start with '- ' foll
|
|
|
61
61
|
Use --file to read an item from a file, or --file - to read it from stdin. Exactly one item source
|
|
62
62
|
is required. --dry-run previews the resulting body without writing it.
|
|
63
63
|
--help, -h Print this help and exit before GitHub I/O.`;
|
|
64
|
-
readonly "build-suggestion-
|
|
64
|
+
readonly "build-suggestion-patches": `pr-shepherd build-suggestion-patches
|
|
65
65
|
|
|
66
|
-
Build
|
|
66
|
+
Build an ordered list of patches and commit instructions from GitHub review suggestions.
|
|
67
67
|
The command does not edit files or mutate git history.
|
|
68
68
|
|
|
69
|
+
Usage:
|
|
70
|
+
pr-shepherd build-suggestion-patches [PR]
|
|
71
|
+
--thread-id ID --message MSG [--description DESC]
|
|
72
|
+
[--thread-id ID --message MSG [--description DESC] ...]
|
|
73
|
+
[--format text|json]
|
|
74
|
+
|
|
75
|
+
Each --thread-id starts a suggestion group. Its following --message and optional --description
|
|
76
|
+
belong to that suggestion. Groups are validated and returned in command-line order.
|
|
77
|
+
|
|
78
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head;
|
|
79
|
+
every generated patch is dry-run in order with git apply --check before output.
|
|
80
|
+
--help, -h Print this help and exit before GitHub, git, config, or log I/O.`;
|
|
81
|
+
readonly "build-suggestion-patch": `pr-shepherd build-suggestion-patch
|
|
82
|
+
|
|
83
|
+
Deprecated one-suggestion adapter. Use build-suggestion-patches.
|
|
84
|
+
|
|
69
85
|
Usage:
|
|
70
86
|
pr-shepherd build-suggestion-patch [PR] --thread-id ID --message MSG
|
|
71
87
|
[--description DESC] [--format text|json]
|
|
@@ -76,7 +92,7 @@ Flags:
|
|
|
76
92
|
--description <text> Optional longer commit body.
|
|
77
93
|
--format text|json Output format. Default: text.
|
|
78
94
|
|
|
79
|
-
The current branch must match the PR head ref
|
|
95
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head.
|
|
80
96
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.`;
|
|
81
97
|
readonly admin: `pr-shepherd admin
|
|
82
98
|
|
|
@@ -149,7 +165,7 @@ Flags:
|
|
|
149
165
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.
|
|
150
166
|
|
|
151
167
|
Preconditions:
|
|
152
|
-
The current branch must match the PR head ref
|
|
168
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head.
|
|
153
169
|
|
|
154
170
|
Exit codes:
|
|
155
171
|
0 suggestion patch and instructions produced
|
|
@@ -176,8 +192,8 @@ Flags:
|
|
|
176
192
|
|
|
177
193
|
PR may be a number or GitHub pull request URL. When omitted, the current branch PR is inferred.
|
|
178
194
|
Exit code: 0 on success; nonzero on failure (sysexits.h — see docs/exit-codes.md).`;
|
|
179
|
-
readonly iterate: "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling: merged/closed or ready-delay elapsed.\n ESCALATE Stop polling until a human provides direction.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
180
|
-
readonly poll: "pr-shepherd poll\n\nRun iterate repeatedly for WAIT ticks and during the FIX_CODE debounce window. Print only the\nfinal tick to stdout.\nPoll exits as soon as iterate returns MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR] [poll-flags] [iterate-flags]\n\nPoll flags:\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: 60s.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: 4.5m.\n --debounce <duration> Settle window after first FIX_CODE before returning. Bare number = seconds. Default: 60s. 0 disables.\n --quiet-status During WAIT polling, print only changed status snapshots.\n --until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes an explicit still-running line to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, CANCEL, or ESCALATE.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
195
|
+
readonly iterate: "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling: merged/closed or ready-delay elapsed.\n ESCALATE Stop polling until a human provides direction.\n MERGE Run the emitted merge/queue command, then continue monitoring.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
196
|
+
readonly poll: "pr-shepherd poll\n\nRun iterate repeatedly for WAIT ticks and during the FIX_CODE debounce window. Print only the\nfinal tick to stdout.\nPoll exits as soon as iterate returns MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal or --merge, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR] [poll-flags] [iterate-flags]\n\nPoll flags:\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: 60s.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: 4.5m.\n --debounce <duration> Settle window after first FIX_CODE before returning. Bare number = seconds. Default: 60s. 0 disables.\n --quiet-status During WAIT polling, print only changed status snapshots.\n --until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes an explicit still-running line to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, MERGE, CANCEL, or ESCALATE. With --merge, --timeout still bounds WAIT ticks; it only continues through MARK_READY while polling remains within that timeout.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
181
197
|
readonly clean: `pr-shepherd clean
|
|
182
198
|
|
|
183
199
|
Remove pr-shepherd state files from PR_SHEPHERD_STATE_DIR.
|
|
@@ -64,11 +64,27 @@ PR may be a number or GitHub pull request URL. An item must start with '- ' foll
|
|
|
64
64
|
Use --file to read an item from a file, or --file - to read it from stdin. Exactly one item source
|
|
65
65
|
is required. --dry-run previews the resulting body without writing it.
|
|
66
66
|
--help, -h Print this help and exit before GitHub I/O.`,
|
|
67
|
-
"build-suggestion-
|
|
67
|
+
"build-suggestion-patches": `pr-shepherd build-suggestion-patches
|
|
68
68
|
|
|
69
|
-
Build
|
|
69
|
+
Build an ordered list of patches and commit instructions from GitHub review suggestions.
|
|
70
70
|
The command does not edit files or mutate git history.
|
|
71
71
|
|
|
72
|
+
Usage:
|
|
73
|
+
pr-shepherd build-suggestion-patches [PR]
|
|
74
|
+
--thread-id ID --message MSG [--description DESC]
|
|
75
|
+
[--thread-id ID --message MSG [--description DESC] ...]
|
|
76
|
+
[--format text|json]
|
|
77
|
+
|
|
78
|
+
Each --thread-id starts a suggestion group. Its following --message and optional --description
|
|
79
|
+
belong to that suggestion. Groups are validated and returned in command-line order.
|
|
80
|
+
|
|
81
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head;
|
|
82
|
+
every generated patch is dry-run in order with git apply --check before output.
|
|
83
|
+
--help, -h Print this help and exit before GitHub, git, config, or log I/O.`,
|
|
84
|
+
"build-suggestion-patch": `pr-shepherd build-suggestion-patch
|
|
85
|
+
|
|
86
|
+
Deprecated one-suggestion adapter. Use build-suggestion-patches.
|
|
87
|
+
|
|
72
88
|
Usage:
|
|
73
89
|
pr-shepherd build-suggestion-patch [PR] --thread-id ID --message MSG
|
|
74
90
|
[--description DESC] [--format text|json]
|
|
@@ -79,7 +95,7 @@ Flags:
|
|
|
79
95
|
--description <text> Optional longer commit body.
|
|
80
96
|
--format text|json Output format. Default: text.
|
|
81
97
|
|
|
82
|
-
The current branch must match the PR head ref
|
|
98
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head.
|
|
83
99
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.`,
|
|
84
100
|
admin: `pr-shepherd admin
|
|
85
101
|
|
|
@@ -152,7 +168,7 @@ Flags:
|
|
|
152
168
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.
|
|
153
169
|
|
|
154
170
|
Preconditions:
|
|
155
|
-
The current branch must match the PR head ref
|
|
171
|
+
The current branch must match the PR head ref. Local HEAD may equal or descend from the PR head.
|
|
156
172
|
|
|
157
173
|
Exit codes:
|
|
158
174
|
0 suggestion patch and instructions produced
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const ITERATE_USAGE = "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling: merged/closed or ready-delay elapsed.\n ESCALATE Stop polling until a human provides direction.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
2
|
-
export declare const POLL_USAGE = "pr-shepherd poll\n\nRun iterate repeatedly for WAIT ticks and during the FIX_CODE debounce window. Print only the\nfinal tick to stdout.\nPoll exits as soon as iterate returns MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR] [poll-flags] [iterate-flags]\n\nPoll flags:\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: 60s.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: 4.5m.\n --debounce <duration> Settle window after first FIX_CODE before returning. Bare number = seconds. Default: 60s. 0 disables.\n --quiet-status During WAIT polling, print only changed status snapshots.\n --until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes an explicit still-running line to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, CANCEL, or ESCALATE.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
1
|
+
export declare const ITERATE_USAGE = "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling: merged/closed or ready-delay elapsed.\n ESCALATE Stop polling until a human provides direction.\n MERGE Run the emitted merge/queue command, then continue monitoring.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
2
|
+
export declare const POLL_USAGE = "pr-shepherd poll\n\nRun iterate repeatedly for WAIT ticks and during the FIX_CODE debounce window. Print only the\nfinal tick to stdout.\nPoll exits as soon as iterate returns MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal or --merge, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR] [poll-flags] [iterate-flags]\n\nPoll flags:\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: 60s.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: 4.5m.\n --debounce <duration> Settle window after first FIX_CODE before returning. Bare number = seconds. Default: 60s. 0 disables.\n --quiet-status During WAIT polling, print only changed status snapshots.\n --until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes an explicit still-running line to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, MERGE, CANCEL, or ESCALATE. With --merge, --timeout still bounds WAIT ticks; it only continues through MARK_READY while polling remains within that timeout.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
|
|
3
3
|
/** Public help page for the default PR polling invocation. */
|
|
4
4
|
export declare const DEFAULT_USAGE: string;
|
|
@@ -11,6 +11,7 @@ Iterate flags:
|
|
|
11
11
|
--stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.
|
|
12
12
|
--no-auto-mark-ready Do not convert draft PRs to ready for review.
|
|
13
13
|
--no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.
|
|
14
|
+
--merge Shepherd through readiness, then emit a merge or merge-queue command.
|
|
14
15
|
--format text|json Output Markdown text or JSON. Default: text.
|
|
15
16
|
--verbose Include verbose iterate fields.
|
|
16
17
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.
|
|
@@ -23,6 +24,7 @@ Actions:
|
|
|
23
24
|
FIX_CODE Agent action is required; follow the instructions, then continue polling.
|
|
24
25
|
CANCEL Stop polling: merged/closed or ready-delay elapsed.
|
|
25
26
|
ESCALATE Stop polling until a human provides direction.
|
|
27
|
+
MERGE Run the emitted merge/queue command, then continue monitoring.
|
|
26
28
|
|
|
27
29
|
Exit codes:
|
|
28
30
|
0 CANCEL (merged or ready-delay elapsed)
|
|
@@ -31,6 +33,7 @@ Exit codes:
|
|
|
31
33
|
12 FIX_CODE
|
|
32
34
|
13 ESCALATE
|
|
33
35
|
14 CANCEL (closed without merging)
|
|
36
|
+
15 MERGE
|
|
34
37
|
A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).`;
|
|
35
38
|
export const POLL_USAGE = `pr-shepherd poll
|
|
36
39
|
|
|
@@ -39,7 +42,7 @@ final tick to stdout.
|
|
|
39
42
|
Poll exits as soon as iterate returns MARK_READY, CANCEL, or ESCALATE, or when timeout
|
|
40
43
|
returns the last WAIT result. FIX_CODE starts a --debounce settle window (default 1m): poll keeps
|
|
41
44
|
iterating at --interval, then runs one more tick after the window and returns that result.
|
|
42
|
-
With --until-terminal, poll also continues through MARK_READY.
|
|
45
|
+
With --until-terminal or --merge, poll also continues through MARK_READY.
|
|
43
46
|
|
|
44
47
|
Usage:
|
|
45
48
|
pr-shepherd poll [PR] [poll-flags] [iterate-flags]
|
|
@@ -56,6 +59,7 @@ Forwarded iterate flags:
|
|
|
56
59
|
--stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.
|
|
57
60
|
--no-auto-mark-ready Do not convert draft PRs to ready for review.
|
|
58
61
|
--no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.
|
|
62
|
+
--merge Shepherd through readiness, then emit a merge or merge-queue command.
|
|
59
63
|
--format text|json Output Markdown text or JSON. Default: text.
|
|
60
64
|
--verbose Include verbose iterate fields and detailed per-tick lines.
|
|
61
65
|
--help, -h Print this help and exit before GitHub, git, config, or log I/O.
|
|
@@ -65,7 +69,7 @@ for --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout);
|
|
|
65
69
|
an explicit unit (4.5m).
|
|
66
70
|
Each WAIT tick writes an explicit still-running line to stderr by default; --quiet-status prints only changed WAIT snapshots, and --verbose emits detailed per-tick lines.
|
|
67
71
|
FIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.
|
|
68
|
-
With --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, CANCEL, or ESCALATE.
|
|
72
|
+
With --until-terminal, --timeout is ignored for WAIT ticks and polling continues until FIX_CODE, MERGE, CANCEL, or ESCALATE. With --merge, --timeout still bounds WAIT ticks; it only continues through MARK_READY while polling remains within that timeout.
|
|
69
73
|
|
|
70
74
|
Exit codes: same as iterate (the final tick's action/reason decides the code).
|
|
71
75
|
0 CANCEL (merged or ready-delay elapsed)
|
|
@@ -74,6 +78,7 @@ Exit codes: same as iterate (the final tick's action/reason decides the code).
|
|
|
74
78
|
12 FIX_CODE
|
|
75
79
|
13 ESCALATE
|
|
76
80
|
14 CANCEL (closed without merging)
|
|
81
|
+
15 MERGE
|
|
77
82
|
A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).`;
|
|
78
83
|
/** Public help page for the default PR polling invocation. */
|
|
79
84
|
export const DEFAULT_USAGE = POLL_USAGE.replace(/^pr-shepherd poll$/m, "pr-shepherd [PR]").replace(/^ {2}pr-shepherd poll \[PR\]/m, " pr-shepherd [PR]");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const TOP_USAGE = "pr-shepherd\n\nAutonomous PR CI monitor and review-comment resolver for agentic coding tools.\n\nUsage:\n pr-shepherd --version | -v\n pr-shepherd --help | -h\n pr-shepherd [PR] [poll-flags] [iterate-flags]\n pr-shepherd iterate [PR] [iterate-flags]\n pr-shepherd apply review [PR] [review-flags]\n pr-shepherd apply files [PR] [files...] [--tests] [--match REGEX]\n pr-shepherd apply journal [PR] <item> [--dry-run] [--format text|json]\n pr-shepherd build-suggestion-
|
|
1
|
+
export declare const TOP_USAGE = "pr-shepherd\n\nAutonomous PR CI monitor and review-comment resolver for agentic coding tools.\n\nUsage:\n pr-shepherd --version | -v\n pr-shepherd --help | -h\n pr-shepherd [PR] [poll-flags] [iterate-flags]\n pr-shepherd iterate [PR] [iterate-flags]\n pr-shepherd apply review [PR] [review-flags]\n pr-shepherd apply files [PR] [files...] [--tests] [--match REGEX]\n pr-shepherd apply journal [PR] <item> [--dry-run] [--format text|json]\n pr-shepherd build-suggestion-patches [PR] --thread-id ID --message MSG [groups...]\n pr-shepherd admin clean <pr|branch|current|repo|all> [value] [flags]\n pr-shepherd admin log-file [--format text|json]\n\nCommands:\n [PR] Poll until non-WAIT or timeout. This is the default command.\n iterate Run one iterate tick (single-tick alias).\n apply review Apply review-state mutations after fixes.\n apply files Mark changed files as viewed in GitHub.\n apply journal Append a list item to the Shepherd Journal details block of a PR body.\n build-suggestion-patches\n Convert ordered GitHub suggestion threads into patches and commit instructions.\n admin clean Remove pr-shepherd state files.\n admin log-file Print the per-worktree debug log path.\n\nPR argument:\n PR may be a number such as 42 or a GitHub pull request URL.\n When omitted, pr-shepherd infers the current branch's pull request.\n\nCommon flags:\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed poll-tick lines.\n --help, -h Print help and exit before any GitHub, git, config, or log I/O.\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Do not cancel in-progress runs before actionable fixes.\n\nPolling flags:\n --interval <duration> Delay between WAIT ticks. Bare number = seconds. Default: 60s.\n --timeout <duration> Poll wall-clock cap for WAIT ticks. Bare number = seconds. Default: 4.5m.\n --debounce <duration> Settle window after first FIX_CODE before returning. Bare number = seconds. Default: 60s. 0 disables.\n --quiet-status During WAIT polling, print only changed status snapshots.\n --until-terminal Continue through WAIT/MARK_READY until FIX_CODE/CANCEL/ESCALATE.\n\nClean variants:\n pr [number] Remove state for one PR. Defaults to current branch PR.\n branch [name] Remove state for a branch's PR. Defaults to current branch.\n current Alias for branch against the current branch.\n repo Remove all state for the current repository.\n all Remove all pr-shepherd state.\n\nExit codes: 0 done, 10-19 PR state, 64-78 shepherd failed (sysexits.h).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\nSee docs/exit-codes.md for the full sysexits.h error-code table.\n\nDuration examples: 30s, 4.5m, 1h. A bare number uses each flag's default unit (see above); decimals are allowed with an explicit unit (4.5m).\n\nRun 'pr-shepherd <command> --help' for command-specific details.";
|