pr-shepherd 0.34.0 → 0.35.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 +3 -2
- package/.grok-plugin/marketplace.json +17 -0
- package/README.md +56 -39
- package/bin/api.d.mts +80 -0
- package/bin/api.mjs +236 -0
- package/bin/checks/classify.d.mts +41 -0
- package/bin/checks/startup-failures.d.mts +2 -0
- package/bin/checks/superseded.d.mts +21 -0
- package/bin/checks/triage.d.mts +4 -0
- package/bin/classify/apply.d.mts +18 -0
- package/bin/classify/apply.mjs +4 -0
- package/bin/classify/loader.d.mts +10 -0
- package/bin/classify/types.d.mts +35 -0
- package/bin/cli/args.d.mts +18 -0
- package/bin/cli/clean-formatter.d.mts +2 -0
- package/bin/cli/default-poll.d.mts +2 -0
- package/bin/cli/duration-flag.d.mts +2 -0
- package/bin/cli/duration.d.mts +13 -0
- package/bin/cli/fence.d.mts +1 -0
- package/bin/cli/fix-formatter-extra.d.mts +3 -0
- package/bin/cli/fix-formatter.d.mts +2 -0
- package/bin/cli/fix-formatter.mjs +6 -6
- package/bin/cli/formatters.d.mts +7 -0
- package/bin/cli/handlers.d.mts +4 -0
- package/bin/cli/handlers.mjs +11 -10
- package/bin/cli/help-command-pages.d.mts +231 -0
- package/bin/cli/help-command-pages.mjs +106 -1
- package/bin/cli/help-iterate-poll-pages.d.mts +4 -0
- package/bin/cli/help-iterate-poll-pages.mjs +4 -2
- package/bin/cli/help-log-file-page.d.mts +1 -0
- package/bin/cli/help-top-page.d.mts +1 -0
- package/bin/cli/help-top-page.mjs +14 -15
- package/bin/cli/help.d.mts +236 -0
- package/bin/cli/help.mjs +17 -0
- package/bin/cli/iterate-emitter.d.mts +8 -0
- package/bin/cli/iterate-flags.d.mts +11 -0
- package/bin/cli/iterate-formatter.d.mts +19 -0
- package/bin/cli/iterate-instructions.d.mts +6 -0
- package/bin/cli/iterate-lean.d.mts +12 -0
- package/bin/cli/journal-formatter.d.mts +2 -0
- package/bin/cli/journal-formatter.mjs +15 -0
- package/bin/cli/journal-handler.d.mts +1 -0
- package/bin/cli/journal-handler.mjs +7 -20
- package/bin/cli/list-formatters.d.mts +76 -0
- package/bin/cli/list-formatters.mjs +9 -9
- package/bin/cli/mark-files-as-viewed-flags.d.mts +11 -0
- package/bin/cli/mark-files-as-viewed-formatter.d.mts +2 -0
- package/bin/cli/mutate-formatter.d.mts +2 -0
- package/bin/cli/poll-handler.d.mts +1 -0
- package/bin/cli/poll-handler.mjs +2 -2
- package/bin/cli/resolve-validators.d.mts +3 -0
- package/bin/cli/resolve-validators.mjs +3 -3
- package/bin/cli/runner.d.mts +7 -0
- package/bin/cli/suggestion-renderer.d.mts +3 -0
- package/bin/cli/validate-default-args.d.mts +6 -0
- package/bin/cli-parser.d.mts +2 -0
- package/bin/cli-parser.mjs +72 -16
- package/bin/commands/check-annotations.d.mts +5 -0
- package/bin/commands/check-status.d.mts +3 -0
- package/bin/commands/check-terminal-report.d.mts +5 -0
- package/bin/commands/check.d.mts +6 -0
- package/bin/commands/check.mjs +2 -1
- package/bin/commands/clean.d.mts +21 -0
- package/bin/commands/commit-suggestion-instruction.d.mts +8 -0
- package/bin/commands/commit-suggestion-instruction.mjs +3 -3
- package/bin/commands/commit-suggestion.d.mts +8 -0
- package/bin/commands/commit-suggestion.mjs +11 -10
- package/bin/commands/iterate/check-instructions.d.mts +16 -0
- package/bin/commands/iterate/check-instructions.mjs +3 -3
- package/bin/commands/iterate/classify.d.mts +18 -0
- package/bin/commands/iterate/classify.mjs +4 -4
- package/bin/commands/iterate/escalate.d.mts +31 -0
- package/bin/commands/iterate/escalate.mjs +7 -4
- package/bin/commands/iterate/fix-code.d.mts +25 -0
- package/bin/commands/iterate/helpers.d.mts +13 -0
- package/bin/commands/iterate/helpers.mjs +4 -1
- package/bin/commands/iterate/index.d.mts +2 -0
- package/bin/commands/iterate/index.mjs +5 -2
- package/bin/commands/iterate/render.d.mts +5 -0
- package/bin/commands/iterate/render.mjs +8 -6
- package/bin/commands/iterate/reruns.d.mts +20 -0
- package/bin/commands/iterate/stall.d.mts +6 -0
- package/bin/commands/journal/index.d.mts +14 -0
- package/bin/commands/journal/index.mjs +1 -0
- package/bin/commands/journal/transform.d.mts +22 -0
- package/bin/commands/log-file.d.mts +5 -0
- package/bin/commands/mark-files-as-viewed.d.mts +26 -0
- package/bin/commands/mark-files-as-viewed.mjs +1 -0
- package/bin/commands/poll.d.mts +10 -0
- package/bin/commands/poll.mjs +1 -0
- package/bin/commands/ready-delay.d.mts +29 -0
- package/bin/commands/ready-mergeability.d.mts +15 -0
- package/bin/commands/resolve-mutate.d.mts +4 -0
- package/bin/commands/resolve-mutate.mjs +1 -0
- package/bin/commands/resolve.d.mts +4 -0
- package/bin/commands/shepherd-journal.d.mts +7 -0
- package/bin/commands/shepherd-journal.mjs +2 -2
- package/bin/comments/authors.d.mts +14 -0
- package/bin/comments/marker.d.mts +2 -0
- package/bin/comments/minimize-policy.d.mts +4 -0
- package/bin/comments/pending-ops.d.mts +15 -0
- package/bin/comments/rate-limit.d.mts +18 -0
- package/bin/comments/resolve.d.mts +34 -0
- package/bin/comments/resolve.mjs +1 -0
- package/bin/comments/review-thread-markers.d.mts +8 -0
- package/bin/comments/review-visibility.d.mts +28 -0
- package/bin/comments/sha-poll.d.mts +2 -0
- package/bin/comments/thread-visibility.d.mts +11 -0
- package/bin/comments/visible-comments.d.mts +11 -0
- package/bin/config/load.d.mts +60 -0
- package/bin/config/load.mjs +72 -1
- package/bin/config.json +0 -2
- package/bin/execution-context.d.mts +9 -0
- package/bin/execution-context.mjs +19 -0
- package/bin/exit-codes.d.mts +51 -0
- package/bin/github/activity.d.mts +3 -0
- package/bin/github/activity.mjs +7 -0
- package/bin/github/batch-parser-helpers.d.mts +22 -0
- package/bin/github/batch-parsers.d.mts +3 -0
- package/bin/github/batch-parsers.mjs +6 -0
- package/bin/github/batch-raw-types.d.mts +207 -0
- package/bin/github/batch-response.d.mts +4 -0
- package/bin/github/batch.d.mts +22 -0
- package/bin/github/branch-protection.d.mts +3 -0
- package/bin/github/check-annotations.d.mts +2 -0
- package/bin/github/client.d.mts +46 -0
- package/bin/github/client.mjs +7 -2
- package/bin/github/errors.d.mts +25 -0
- package/bin/github/gql/batch-pr.gql +5 -0
- package/bin/github/gql/review-thread-comments.gql +1 -0
- package/bin/github/graphql-http.d.mts +19 -0
- package/bin/github/graphql-response.d.mts +7 -0
- package/bin/github/http-auth.d.mts +4 -0
- package/bin/github/http-request.d.mts +7 -0
- package/bin/github/http-utils.d.mts +11 -0
- package/bin/github/http.d.mts +5 -0
- package/bin/github/pagination.d.mts +45 -0
- package/bin/github/queries.d.mts +24 -0
- package/bin/github/rest-http.d.mts +2 -0
- package/bin/github/thread-comments.d.mts +2 -0
- package/bin/index.d.mts +10 -0
- package/bin/index.mjs +1 -1
- package/bin/log/log-file.d.mts +28 -0
- package/bin/log/session.d.mts +31 -0
- package/bin/log/setup.d.mts +6 -0
- package/bin/mcp/index.d.mts +5 -0
- package/bin/mcp/index.mjs +8 -0
- package/bin/mcp/server.d.mts +8 -0
- package/bin/mcp/server.mjs +157 -0
- package/bin/mcp-stdio.d.mts +2 -0
- package/bin/mcp-stdio.mjs +7 -0
- package/bin/merge-status/derive.d.mts +19 -0
- package/bin/reporters/agent.d.mts +23 -0
- package/bin/reporters/agent.mjs +3 -0
- package/bin/state/base.d.mts +1 -0
- package/bin/state/bot-cr-seen.d.mts +51 -0
- package/bin/state/bot-cr-seen.mjs +1 -1
- package/bin/state/fix-attempts.d.mts +27 -0
- package/bin/state/iterate-stall.d.mts +27 -0
- package/bin/state/seen-comments.d.mts +62 -0
- package/bin/suggestions/extract.d.mts +8 -0
- package/bin/suggestions/parse.d.mts +48 -0
- package/bin/suggestions/patch.d.mts +14 -0
- package/bin/threads/transcript.d.mts +14 -0
- package/bin/threads/transcript.mjs +4 -0
- package/bin/types/activity.d.mts +30 -0
- package/bin/types/agent-thread.d.mts +9 -0
- package/bin/types/check-annotations.d.mts +14 -0
- package/bin/types/check-classification.d.mts +19 -0
- package/bin/types/github.d.mts +139 -0
- package/bin/types/iterate.d.mts +157 -0
- package/bin/types/protected-run.d.mts +6 -0
- package/bin/types/report.d.mts +176 -0
- package/bin/types/review-thread.d.mts +12 -0
- package/bin/types.d.mts +9 -0
- package/bin/util/markdown.d.mts +1 -0
- package/bin/util/path-segment.d.mts +2 -0
- package/bin/util/sleep.d.mts +1 -0
- package/bin/util/worktree.d.mts +9 -0
- package/bin/util/worktree.mjs +4 -1
- package/package.json +51 -37
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +3 -2
- package/plugins/pr-shepherd/.codex.mcp.json +8 -0
- package/plugins/pr-shepherd/.mcp.json +6 -0
- package/plugins/pr-shepherd/skills/mark-files-as-viewed/SKILL.md +5 -19
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -15
- package/src/classify/types.mts +12 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { AuthorType, ReviewThread, PrComment, Review, MergeStatusResult, CheckConclusion, SuggestionBlock } from "./github.mts";
|
|
2
|
+
import type { ClassifiedCheck, TriagedCheck } from "./check-classification.mts";
|
|
3
|
+
import type { AgentThreadComment } from "./agent-thread.mts";
|
|
4
|
+
import type { CheckAnnotation } from "./check-annotations.mts";
|
|
5
|
+
import type { PrActivitySummary } from "./activity.mts";
|
|
6
|
+
export interface FirstLookThread extends ReviewThread {
|
|
7
|
+
firstLookStatus: "outdated" | "resolved" | "minimized";
|
|
8
|
+
autoResolved?: boolean;
|
|
9
|
+
edited?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface FirstLookComment extends PrComment {
|
|
12
|
+
firstLookStatus: "minimized";
|
|
13
|
+
edited?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type ActionableComment = PrComment & {
|
|
16
|
+
edited?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type ShepherdStatus = "MERGED" | "CLOSED" | "READY" | "FAILING" | "PENDING" | "IN_PROGRESS" | "UNRESOLVED_COMMENTS" | "UNKNOWN";
|
|
19
|
+
export interface ShepherdReport {
|
|
20
|
+
pr: number;
|
|
21
|
+
/** GitHub node ID of the PR — used for mutations (e.g. markPullRequestReadyForReview). */
|
|
22
|
+
nodeId: string;
|
|
23
|
+
repo: string;
|
|
24
|
+
status: ShepherdStatus;
|
|
25
|
+
/** PR base branch from the GraphQL batch. */
|
|
26
|
+
baseBranch: string;
|
|
27
|
+
mergeStatus: MergeStatusResult;
|
|
28
|
+
checks: {
|
|
29
|
+
passing: ClassifiedCheck[];
|
|
30
|
+
failing: TriagedCheck[];
|
|
31
|
+
inProgress: ClassifiedCheck[];
|
|
32
|
+
skipped: ClassifiedCheck[];
|
|
33
|
+
/** Checks filtered out because they were triggered by a non-PR event (push, schedule, etc.). */
|
|
34
|
+
filtered: ClassifiedCheck[];
|
|
35
|
+
filteredNames: string[];
|
|
36
|
+
blockedByFilteredCheck: boolean;
|
|
37
|
+
ignoredNames?: string[];
|
|
38
|
+
supersededNames?: string[];
|
|
39
|
+
};
|
|
40
|
+
threads: {
|
|
41
|
+
actionable: ReviewThread[];
|
|
42
|
+
/** Unresolved threads that need a GitHub resolve mutation but do not require code edits. */
|
|
43
|
+
resolutionOnly: ReviewThread[];
|
|
44
|
+
autoResolved: ReviewThread[];
|
|
45
|
+
autoResolveErrors: string[];
|
|
46
|
+
/** First-look items — outdated/resolved/minimized threads not yet seen by the agent. */
|
|
47
|
+
firstLook: FirstLookThread[];
|
|
48
|
+
/** Thread IDs matched by user classification rules with autoResolve:true — routed to resolveThreadIds. */
|
|
49
|
+
ruleAutoResolveIds?: string[];
|
|
50
|
+
};
|
|
51
|
+
comments: {
|
|
52
|
+
actionable: ActionableComment[];
|
|
53
|
+
/** Visible PR comments that should be passed to `--minimize-comment-ids`. */
|
|
54
|
+
minimizeIds?: string[];
|
|
55
|
+
/** First-look items — minimized comments not yet seen by the agent. */
|
|
56
|
+
firstLook: FirstLookComment[];
|
|
57
|
+
};
|
|
58
|
+
changesRequestedReviews: Review[];
|
|
59
|
+
/** COMMENTED reviews already seen — eligible for `--minimize-comment-ids` without re-rendering. */
|
|
60
|
+
reviewSummaries: Review[];
|
|
61
|
+
/** COMMENTED reviews not yet seen — body must be surfaced before minimizing. */
|
|
62
|
+
firstLookSummaries: Review[];
|
|
63
|
+
/** COMMENTED reviews whose body changed since last seen — surface updated body, but do NOT re-add to `--minimize-comment-ids`. */
|
|
64
|
+
editedSummaries: Review[];
|
|
65
|
+
/** APPROVED reviews not yet minimized — opt-in minimize target. */
|
|
66
|
+
approvedReviews: Review[];
|
|
67
|
+
/** COMMENTED review summary IDs matched by user rules with autoResolve:true — minimized without surfacing to agent. */
|
|
68
|
+
ruleAutoResolveReviewSummaryIds?: string[];
|
|
69
|
+
/** Branch protection rule for the PR's base branch. Null when no rule exists or the base ref is unavailable. */
|
|
70
|
+
branchProtection: import("./github.mts").BranchProtection | null;
|
|
71
|
+
activity?: PrActivitySummary;
|
|
72
|
+
}
|
|
73
|
+
export interface ResolveOptions {
|
|
74
|
+
resolveThreadIds?: string[];
|
|
75
|
+
replyThreadIds?: string[];
|
|
76
|
+
minimizeCommentIds?: string[];
|
|
77
|
+
dismissReviewIds?: string[];
|
|
78
|
+
dismissMessage?: string;
|
|
79
|
+
/** When set, shepherd verifies GitHub has received this commit before resolving. */
|
|
80
|
+
requireSha?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface AgentThread {
|
|
83
|
+
id: string;
|
|
84
|
+
reviewId?: string;
|
|
85
|
+
path: string | null;
|
|
86
|
+
line: number | null;
|
|
87
|
+
startLine?: number;
|
|
88
|
+
author: string;
|
|
89
|
+
authorType?: AuthorType;
|
|
90
|
+
authorAssociation?: import("./github.mts").CommentAuthorAssociation;
|
|
91
|
+
body: string;
|
|
92
|
+
url: string;
|
|
93
|
+
comments?: AgentThreadComment[];
|
|
94
|
+
suggestion?: SuggestionBlock;
|
|
95
|
+
edited?: boolean;
|
|
96
|
+
}
|
|
97
|
+
/** Comment shape emitted to the iterate agent — stripped of always-false flags. */
|
|
98
|
+
export interface AgentComment {
|
|
99
|
+
id: string;
|
|
100
|
+
author: string;
|
|
101
|
+
authorType?: AuthorType;
|
|
102
|
+
authorAssociation?: import("./github.mts").CommentAuthorAssociation;
|
|
103
|
+
body: string;
|
|
104
|
+
url: string;
|
|
105
|
+
edited?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** Check shape emitted to the iterate agent under `fix_code`. Cancelled checks
|
|
108
|
+
* should be handled from `name`/`runId`/`detailsUrl`/`conclusion`; optional
|
|
109
|
+
* workflow/job/step metadata may still be present when available. */
|
|
110
|
+
export interface AgentCheck {
|
|
111
|
+
name: string;
|
|
112
|
+
runId: string | null;
|
|
113
|
+
/** Fallback for checks where runId is null (e.g. external status checks). */
|
|
114
|
+
detailsUrl: string | null;
|
|
115
|
+
/** Raw GitHub check conclusion; may be null for some completed checks from upstream data. */
|
|
116
|
+
conclusion: Exclude<CheckConclusion, "SKIPPED" | "NEUTRAL">;
|
|
117
|
+
/** Workflow display name (e.g. `"CI"`). Populated on a best-effort basis when available from the jobs API. */
|
|
118
|
+
workflowName?: string;
|
|
119
|
+
/** Name of the matched job (e.g. `"tests (ubuntu)"`). Distinct from check name for matrix builds. */
|
|
120
|
+
jobName?: string;
|
|
121
|
+
/** Name of the first failed step (e.g. `"Run tests"`, `"Set up job"`). */
|
|
122
|
+
failedStep?: string;
|
|
123
|
+
/** One-line status text shown in the GitHub UI (e.g. "67.68% of diff hit (target 85.00%)"). */
|
|
124
|
+
summary?: string;
|
|
125
|
+
logExcerpt?: string;
|
|
126
|
+
/** Marker-gated inline annotations from this failing check. */
|
|
127
|
+
annotations?: CheckAnnotation[];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A single CI check that is relevant to PR readiness — triggered by a PR event
|
|
131
|
+
* (or by a StatusContext with null event), completed, and not skipped/neutral.
|
|
132
|
+
*
|
|
133
|
+
* Included in every iterate result so the agent always sees the full CI picture
|
|
134
|
+
* regardless of which action fired.
|
|
135
|
+
*/
|
|
136
|
+
export interface RelevantCheck {
|
|
137
|
+
name: string;
|
|
138
|
+
conclusion: Exclude<CheckConclusion, "SKIPPED" | "NEUTRAL" | null>;
|
|
139
|
+
runId: string | null;
|
|
140
|
+
detailsUrl: string | null;
|
|
141
|
+
/** Workflow display name (e.g. `"CI"`). Available for all checks with a runId. */
|
|
142
|
+
workflowName?: string;
|
|
143
|
+
/** Name of the matched job (e.g. `"tests (ubuntu)"`). Distinct from check name for matrix builds. */
|
|
144
|
+
jobName?: string;
|
|
145
|
+
/** Name of the first failed step in the matched job. */
|
|
146
|
+
failedStep?: string;
|
|
147
|
+
/** One-line status text shown in the GitHub UI (e.g. "67.68% of diff hit (target 85.00%)"). */
|
|
148
|
+
summary?: string;
|
|
149
|
+
logExcerpt?: string;
|
|
150
|
+
/** Marker-gated inline annotations from this check. */
|
|
151
|
+
annotations?: CheckAnnotation[];
|
|
152
|
+
}
|
|
153
|
+
export interface CommitSuggestionResult {
|
|
154
|
+
pr: number;
|
|
155
|
+
repo: string;
|
|
156
|
+
threadId: string;
|
|
157
|
+
path: string;
|
|
158
|
+
startLine: number;
|
|
159
|
+
endLine: number;
|
|
160
|
+
author: string;
|
|
161
|
+
/** The unified diff generated for this suggestion. */
|
|
162
|
+
patch: string;
|
|
163
|
+
/** The commit subject line (user-supplied --message). */
|
|
164
|
+
commitMessage: string;
|
|
165
|
+
/** The commit body (optional description + Co-authored-by trailer). */
|
|
166
|
+
commitBody: string;
|
|
167
|
+
/** Files the agent should stage before committing. */
|
|
168
|
+
filesToStage: string[];
|
|
169
|
+
/** Numbered steps the agent must execute to apply, commit, resolve, and push. */
|
|
170
|
+
postActionInstructions: string[];
|
|
171
|
+
}
|
|
172
|
+
export interface GlobalOptions {
|
|
173
|
+
prNumber?: number;
|
|
174
|
+
format: "text" | "json";
|
|
175
|
+
verbose?: boolean;
|
|
176
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AuthorType, CommentAuthorAssociation } from "./github.mts";
|
|
2
|
+
export interface ReviewThreadComment {
|
|
3
|
+
id: string;
|
|
4
|
+
isMinimized: boolean;
|
|
5
|
+
reviewId?: string;
|
|
6
|
+
author: string;
|
|
7
|
+
authorType: AuthorType;
|
|
8
|
+
authorAssociation?: CommentAuthorAssociation;
|
|
9
|
+
body: string;
|
|
10
|
+
url: string;
|
|
11
|
+
createdAtUnix: number;
|
|
12
|
+
}
|
package/bin/types.d.mts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Shared type definitions for the shepherd CLI. */
|
|
2
|
+
export * from "./types/github.mts";
|
|
3
|
+
export * from "./types/check-classification.mts";
|
|
4
|
+
export * from "./types/activity.mts";
|
|
5
|
+
export * from "./types/review-thread.mts";
|
|
6
|
+
export * from "./types/agent-thread.mts";
|
|
7
|
+
export * from "./types/check-annotations.mts";
|
|
8
|
+
export * from "./types/report.mts";
|
|
9
|
+
export * from "./types/iterate.mts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function joinSections(sections: (string | null | undefined)[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Returns the absolute path to the current git worktree root. Throws outside a git repo. */
|
|
2
|
+
export declare function getWorktreeRoot(): Promise<string>;
|
|
3
|
+
/**
|
|
4
|
+
* Returns a filesystem-safe key for the current worktree, unique across
|
|
5
|
+
* worktrees of the same repo. Format: `<basename>-<sha8>` where sha8 is
|
|
6
|
+
* the first 8 hex chars of sha256(toplevel). Falls back to sha8-only if
|
|
7
|
+
* the basename contains characters outside SAFE_SEGMENT.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getWorktreeKey(): Promise<string>;
|
package/bin/util/worktree.mjs
CHANGED
|
@@ -3,10 +3,13 @@ import { promisify } from "node:util";
|
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { basename } from "node:path";
|
|
5
5
|
import { SAFE_SEGMENT } from "./path-segment.mjs";
|
|
6
|
+
import { getExecutionCwd } from "../execution-context.mjs";
|
|
6
7
|
const execFile = promisify(execFileCb);
|
|
7
8
|
/** Returns the absolute path to the current git worktree root. Throws outside a git repo. */
|
|
8
9
|
export async function getWorktreeRoot() {
|
|
9
|
-
const { stdout } = await execFile("git", ["rev-parse", "--show-toplevel"]
|
|
10
|
+
const { stdout } = await execFile("git", ["rev-parse", "--show-toplevel"], {
|
|
11
|
+
cwd: getExecutionCwd(),
|
|
12
|
+
});
|
|
10
13
|
return stdout.trim();
|
|
11
14
|
}
|
|
12
15
|
/**
|
package/package.json
CHANGED
|
@@ -1,48 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-shepherd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Autonomous PR CI monitor and review-comment resolver for agentic coding tools",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"automation",
|
|
7
|
+
"ci",
|
|
8
|
+
"claude",
|
|
9
|
+
"claude-code",
|
|
10
|
+
"code-review",
|
|
11
|
+
"codex",
|
|
12
|
+
"github",
|
|
13
|
+
"pull-request"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/jonathanong/pr-shepherd",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/jonathanong/pr-shepherd/issues"
|
|
18
|
+
},
|
|
5
19
|
"license": "MIT",
|
|
6
20
|
"author": "Jonathan Ong",
|
|
7
|
-
"
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/jonathanong/pr-shepherd.git"
|
|
24
|
+
},
|
|
8
25
|
"bin": {
|
|
9
|
-
"pr-shepherd": "bin/index.mjs"
|
|
26
|
+
"pr-shepherd": "bin/index.mjs",
|
|
27
|
+
"pr-shepherd-mcp": "bin/mcp-stdio.mjs"
|
|
10
28
|
},
|
|
11
29
|
"files": [
|
|
12
30
|
"bin/**",
|
|
31
|
+
"plugins/**/.mcp.json",
|
|
32
|
+
"plugins/**/.codex.mcp.json",
|
|
13
33
|
"src/classify/types.mts",
|
|
14
34
|
"plugins/**",
|
|
15
35
|
"plugins/**/.codex-plugin/**",
|
|
16
36
|
".claude-plugin/**",
|
|
37
|
+
".grok-plugin/**",
|
|
17
38
|
".agents/plugins/marketplace.json",
|
|
18
39
|
"marketplace.json",
|
|
19
40
|
"README.md",
|
|
20
41
|
"LICENSE"
|
|
21
42
|
],
|
|
22
|
-
"
|
|
23
|
-
"node": ">=22.18.0"
|
|
24
|
-
},
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"picomatch": "^4.0.4",
|
|
27
|
-
"yaml": "^2.7.0"
|
|
28
|
-
},
|
|
43
|
+
"type": "module",
|
|
29
44
|
"exports": {
|
|
45
|
+
".": {
|
|
46
|
+
"types": "./bin/api.d.mts",
|
|
47
|
+
"default": "./bin/api.mjs"
|
|
48
|
+
},
|
|
49
|
+
"./mcp": {
|
|
50
|
+
"types": "./bin/mcp/index.d.mts",
|
|
51
|
+
"default": "./bin/mcp/index.mjs"
|
|
52
|
+
},
|
|
30
53
|
"./classify": {
|
|
31
54
|
"types": "./src/classify/types.mts",
|
|
32
55
|
"default": "./bin/classify/types.mjs"
|
|
33
56
|
}
|
|
34
57
|
},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"@types/node": "^26.0.0",
|
|
37
|
-
"@types/picomatch": "^4.0.3",
|
|
38
|
-
"@vitest/coverage-v8": "^4.1.4",
|
|
39
|
-
"husky": "^9.1.7",
|
|
40
|
-
"knip": "^6.14.1",
|
|
41
|
-
"oxfmt": "^0.60.0",
|
|
42
|
-
"oxlint": "^1.60.0",
|
|
43
|
-
"typescript": "^7.0.2",
|
|
44
|
-
"vitest": "^4.1.4"
|
|
45
|
-
},
|
|
46
58
|
"scripts": {
|
|
47
59
|
"build": "node scripts/build.mjs",
|
|
48
60
|
"prepare": "node scripts/install-husky.mjs && npm run build",
|
|
@@ -58,22 +70,24 @@
|
|
|
58
70
|
"test:coverage": "vitest run --coverage && node scripts/strip-lcov-branches.mjs",
|
|
59
71
|
"test:watch": "vitest"
|
|
60
72
|
},
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"automation",
|
|
67
|
-
"codex",
|
|
68
|
-
"claude",
|
|
69
|
-
"claude-code"
|
|
70
|
-
],
|
|
71
|
-
"repository": {
|
|
72
|
-
"type": "git",
|
|
73
|
-
"url": "git+https://github.com/jonathanong/pr-shepherd.git"
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
75
|
+
"picomatch": "^4.0.4",
|
|
76
|
+
"yaml": "^2.7.0",
|
|
77
|
+
"zod": "^4.4.3"
|
|
74
78
|
},
|
|
75
|
-
"
|
|
76
|
-
"
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@types/node": "^26.0.0",
|
|
81
|
+
"@types/picomatch": "^4.0.3",
|
|
82
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
83
|
+
"husky": "^9.1.7",
|
|
84
|
+
"knip": "^6.14.1",
|
|
85
|
+
"oxfmt": "^0.62.0",
|
|
86
|
+
"oxlint": "^1.60.0",
|
|
87
|
+
"typescript": "^7.0.2",
|
|
88
|
+
"vitest": "^4.1.4"
|
|
77
89
|
},
|
|
78
|
-
"
|
|
90
|
+
"engines": {
|
|
91
|
+
"node": ">=22.18.0"
|
|
92
|
+
}
|
|
79
93
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-shepherd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Autonomous PR CI monitor and review-comment resolver for Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jonathan Ong",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"repository": "https://github.com/jonathanong/pr-shepherd",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"keywords": ["github", "pull-request", "ci", "code-review", "automation", "codex"],
|
|
14
|
-
"skills": "
|
|
14
|
+
"skills": "./skills/",
|
|
15
|
+
"mcpServers": "./.codex.mcp.json",
|
|
15
16
|
"interface": {
|
|
16
17
|
"displayName": "pr-shepherd",
|
|
17
18
|
"shortDescription": "Monitor PR CI and review comments from Codex",
|
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mark-files-as-viewed
|
|
3
|
-
description:
|
|
3
|
+
description: "Mark changed pull-request files as viewed with pr-shepherd (MCP or CLI)."
|
|
4
4
|
user-invocable: true
|
|
5
5
|
argument-hint: "[PR number or URL] [files|tests|--tests|--match REGEX]"
|
|
6
|
-
allowed-tools: ["Bash", "Read", "Grep", "Glob"]
|
|
6
|
+
allowed-tools: ["MCP", "Bash", "Read", "Grep", "Glob"]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# mark-files-as-viewed
|
|
10
10
|
|
|
11
|
-
Thin dispatcher for marking
|
|
11
|
+
Thin dispatcher for marking PR files viewed. Use the MCP server when it is available; otherwise use the CLI.
|
|
12
12
|
|
|
13
13
|
## Arguments: $ARGUMENTS
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. Parse an optional PR number or GitHub PR URL. Treat standalone `tests` as `--tests`; preserve explicit paths and `--match <regex>` selectors.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- If `$ARGUMENTS` contains a PR number, use it.
|
|
19
|
-
- If `$ARGUMENTS` contains a GitHub PR URL, extract the number.
|
|
20
|
-
- Otherwise, infer: `gh pr view --json number --jq .number`
|
|
21
|
-
- Treat a standalone `tests` argument as `--tests`.
|
|
22
|
-
- Preserve explicit file paths, `--tests`, and `--match <regex>` arguments.
|
|
23
|
-
- If no PR found, report an error and stop.
|
|
24
|
-
|
|
25
|
-
2. **Run `pr-shepherd`:**
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
pr-shepherd mark-files-as-viewed <N> <selectors>
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Print the full output.
|
|
17
|
+
2. If the `apply` MCP tool is available, call it with one `mark_files_viewed` operation, then print the full result. Otherwise run `pr-shepherd apply files` with the parsed PR and selectors and print the full result.
|
|
@@ -1,28 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pr-shepherd
|
|
3
|
-
description: 'Iterate a GitHub pull request
|
|
3
|
+
description: 'Iterate a GitHub pull request with pr-shepherd (MCP or CLI). Use for requests like "use pr-shepherd", "iterate PR #123", or "run pr-shepherd until this PR is ready".'
|
|
4
4
|
user-invocable: true
|
|
5
5
|
argument-hint: "[PR number or URL]"
|
|
6
|
-
allowed-tools: ["
|
|
6
|
+
allowed-tools: ["MCP", "Bash", "Read", "Grep", "Glob", "Edit", "Write"]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# pr-shepherd
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Thin dispatcher for iterating a PR. Poll with the CLI; use MCP `iterate` only when the CLI is unavailable.
|
|
12
12
|
|
|
13
13
|
## Arguments: $ARGUMENTS
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. Parse an optional PR number or GitHub PR URL from `$ARGUMENTS`; otherwise let pr-shepherd infer the current branch PR.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
2. Run the poll command `pr-shepherd` with the optional PR argument and print its full result. Do not run `pr-shepherd iterate`. If the CLI is unavailable and the `iterate` MCP tool is available, call `iterate` and print its full result.
|
|
18
18
|
|
|
19
|
-
|
|
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. `[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
|
-
|
|
23
|
-
4. **Exit codes:** an exit code of `64` or higher means the `pr-shepherd` command itself failed (bad flag, GitHub auth/permission error, transient failure, etc.) — surface the error and stop instead of looping. Any other exit code (`0` or `10`–`19`) means the command ran and the output above is real PR state — proceed to step 5.
|
|
24
|
-
|
|
25
|
-
5. **Terminal states (stop):**
|
|
26
|
-
- `[CANCEL]` — ready-delay completed, or PR merged/closed.
|
|
27
|
-
- `[ESCALATE]` — needs human direction (includes `stall-timeout` for repeated unchanged CI failures or CI that never starts).
|
|
28
|
-
- **Do NOT merge the pull request** unless the human has explicitly requested or allowed it.
|
|
19
|
+
3. Follow the returned instructions exactly. If this tick used MCP `iterate`, use MCP `apply` and `build_suggestion_patch` for the returned review mutations and suggestion patches — do not run a `pr-shepherd apply` shell command. If this tick used the CLI poll, run the printed apply command. After completing an action, run `pr-shepherd` again (or call `iterate` if only MCP is available) until a terminal action or the human directs you to stop.
|
package/src/classify/types.mts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/** Raw relationship between a comment author and the repository, as reported by GitHub. */
|
|
2
|
+
export type CommentAuthorAssociation =
|
|
3
|
+
| "COLLABORATOR"
|
|
4
|
+
| "CONTRIBUTOR"
|
|
5
|
+
| "FIRST_TIMER"
|
|
6
|
+
| "FIRST_TIME_CONTRIBUTOR"
|
|
7
|
+
| "MANNEQUIN"
|
|
8
|
+
| "MEMBER"
|
|
9
|
+
| "NONE"
|
|
10
|
+
| "OWNER";
|
|
11
|
+
|
|
1
12
|
export type ClassifyItemKind =
|
|
2
13
|
| "review-thread"
|
|
3
14
|
| "pr-comment"
|
|
@@ -9,6 +20,7 @@ export interface ClassifyItemBase {
|
|
|
9
20
|
readonly id: string;
|
|
10
21
|
readonly author: string;
|
|
11
22
|
readonly authorType: "User" | "Bot" | "Unknown";
|
|
23
|
+
readonly authorAssociation?: CommentAuthorAssociation;
|
|
12
24
|
readonly body: string;
|
|
13
25
|
readonly url?: string;
|
|
14
26
|
}
|