pr-shepherd 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/.claude-plugin/plugin.json +3 -2
  2. package/.grok-plugin/marketplace.json +17 -0
  3. package/README.md +80 -43
  4. package/bin/api.d.mts +80 -0
  5. package/bin/api.mjs +236 -0
  6. package/bin/checks/classify.d.mts +41 -0
  7. package/bin/checks/startup-failures.d.mts +2 -0
  8. package/bin/checks/superseded.d.mts +21 -0
  9. package/bin/checks/triage.d.mts +4 -0
  10. package/bin/checks/triage.mjs +11 -3
  11. package/bin/classify/apply.d.mts +18 -0
  12. package/bin/classify/apply.mjs +4 -0
  13. package/bin/classify/loader.d.mts +10 -0
  14. package/bin/classify/types.d.mts +35 -0
  15. package/bin/cli/args.d.mts +18 -0
  16. package/bin/cli/args.mjs +1 -0
  17. package/bin/cli/clean-formatter.d.mts +2 -0
  18. package/bin/cli/default-poll.d.mts +2 -0
  19. package/bin/cli/default-poll.mjs +1 -0
  20. package/bin/cli/duration-flag.d.mts +2 -0
  21. package/bin/cli/duration.d.mts +13 -0
  22. package/bin/cli/fence.d.mts +1 -0
  23. package/bin/cli/fix-formatter-extra.d.mts +3 -0
  24. package/bin/cli/fix-formatter.d.mts +2 -0
  25. package/bin/cli/fix-formatter.mjs +6 -6
  26. package/bin/cli/formatters.d.mts +7 -0
  27. package/bin/cli/handlers.d.mts +4 -0
  28. package/bin/cli/handlers.mjs +11 -10
  29. package/bin/cli/help-command-pages.d.mts +231 -0
  30. package/bin/cli/help-command-pages.mjs +106 -1
  31. package/bin/cli/help-iterate-poll-pages.d.mts +4 -0
  32. package/bin/cli/help-iterate-poll-pages.mjs +14 -7
  33. package/bin/cli/help-log-file-page.d.mts +1 -0
  34. package/bin/cli/help-top-page.d.mts +1 -0
  35. package/bin/cli/help-top-page.mjs +16 -16
  36. package/bin/cli/help.d.mts +236 -0
  37. package/bin/cli/help.mjs +17 -0
  38. package/bin/cli/iterate-emitter.d.mts +8 -0
  39. package/bin/cli/iterate-flags.d.mts +11 -0
  40. package/bin/cli/iterate-formatter.d.mts +19 -0
  41. package/bin/cli/iterate-formatter.mjs +11 -2
  42. package/bin/cli/iterate-instructions.d.mts +6 -0
  43. package/bin/cli/iterate-lean.d.mts +12 -0
  44. package/bin/cli/iterate-lean.mjs +1 -0
  45. package/bin/cli/journal-formatter.d.mts +2 -0
  46. package/bin/cli/journal-formatter.mjs +15 -0
  47. package/bin/cli/journal-handler.d.mts +1 -0
  48. package/bin/cli/journal-handler.mjs +7 -20
  49. package/bin/cli/list-formatters.d.mts +76 -0
  50. package/bin/cli/list-formatters.mjs +9 -9
  51. package/bin/cli/mark-files-as-viewed-flags.d.mts +11 -0
  52. package/bin/cli/mark-files-as-viewed-formatter.d.mts +2 -0
  53. package/bin/cli/mutate-formatter.d.mts +2 -0
  54. package/bin/cli/poll-handler.d.mts +1 -0
  55. package/bin/cli/poll-handler.mjs +9 -2
  56. package/bin/cli/resolve-validators.d.mts +3 -0
  57. package/bin/cli/resolve-validators.mjs +3 -3
  58. package/bin/cli/runner.d.mts +7 -0
  59. package/bin/cli/suggestion-renderer.d.mts +3 -0
  60. package/bin/cli/validate-default-args.d.mts +6 -0
  61. package/bin/cli-parser.d.mts +2 -0
  62. package/bin/cli-parser.mjs +72 -16
  63. package/bin/commands/check-annotations.d.mts +5 -0
  64. package/bin/commands/check-status.d.mts +3 -0
  65. package/bin/commands/check-terminal-report.d.mts +5 -0
  66. package/bin/commands/check.d.mts +7 -0
  67. package/bin/commands/check.mjs +28 -23
  68. package/bin/commands/clean.d.mts +21 -0
  69. package/bin/commands/commit-suggestion-instruction.d.mts +8 -0
  70. package/bin/commands/commit-suggestion-instruction.mjs +3 -3
  71. package/bin/commands/commit-suggestion.d.mts +8 -0
  72. package/bin/commands/commit-suggestion.mjs +20 -13
  73. package/bin/commands/iterate/check-instructions.d.mts +16 -0
  74. package/bin/commands/iterate/check-instructions.mjs +3 -3
  75. package/bin/commands/iterate/classify.d.mts +18 -0
  76. package/bin/commands/iterate/classify.mjs +4 -4
  77. package/bin/commands/iterate/escalate.d.mts +31 -0
  78. package/bin/commands/iterate/escalate.mjs +7 -4
  79. package/bin/commands/iterate/fix-code.d.mts +25 -0
  80. package/bin/commands/iterate/fix-code.mjs +1 -1
  81. package/bin/commands/iterate/helpers.d.mts +14 -0
  82. package/bin/commands/iterate/helpers.mjs +19 -7
  83. package/bin/commands/iterate/index.d.mts +2 -0
  84. package/bin/commands/iterate/index.mjs +8 -12
  85. package/bin/commands/iterate/render.d.mts +5 -0
  86. package/bin/commands/iterate/render.mjs +8 -6
  87. package/bin/commands/iterate/reruns.d.mts +20 -0
  88. package/bin/commands/iterate/stall.d.mts +6 -0
  89. package/bin/commands/journal/index.d.mts +14 -0
  90. package/bin/commands/journal/index.mjs +1 -0
  91. package/bin/commands/journal/transform.d.mts +22 -0
  92. package/bin/commands/log-file.d.mts +5 -0
  93. package/bin/commands/mark-files-as-viewed.d.mts +26 -0
  94. package/bin/commands/mark-files-as-viewed.mjs +1 -0
  95. package/bin/commands/poll.d.mts +12 -0
  96. package/bin/commands/poll.mjs +52 -17
  97. package/bin/commands/ready-delay.d.mts +29 -0
  98. package/bin/commands/ready-delay.mjs +3 -13
  99. package/bin/commands/ready-mergeability.d.mts +15 -0
  100. package/bin/commands/resolve-mutate.d.mts +4 -0
  101. package/bin/commands/resolve-mutate.mjs +1 -0
  102. package/bin/commands/resolve.d.mts +4 -0
  103. package/bin/commands/shepherd-journal.d.mts +7 -0
  104. package/bin/commands/shepherd-journal.mjs +2 -2
  105. package/bin/comments/authors.d.mts +14 -0
  106. package/bin/comments/marker.d.mts +2 -0
  107. package/bin/comments/minimize-policy.d.mts +4 -0
  108. package/bin/comments/pending-ops.d.mts +15 -0
  109. package/bin/comments/rate-limit.d.mts +18 -0
  110. package/bin/comments/resolve.d.mts +34 -0
  111. package/bin/comments/resolve.mjs +1 -0
  112. package/bin/comments/review-thread-markers.d.mts +8 -0
  113. package/bin/comments/review-visibility.d.mts +28 -0
  114. package/bin/comments/sha-poll.d.mts +2 -0
  115. package/bin/comments/thread-visibility.d.mts +11 -0
  116. package/bin/comments/visible-comments.d.mts +11 -0
  117. package/bin/config/load.d.mts +60 -0
  118. package/bin/config/load.mjs +129 -16
  119. package/bin/config.json +0 -2
  120. package/bin/execution-context.d.mts +9 -0
  121. package/bin/execution-context.mjs +19 -0
  122. package/bin/exit-codes.d.mts +51 -0
  123. package/bin/github/activity.d.mts +3 -0
  124. package/bin/github/activity.mjs +7 -0
  125. package/bin/github/batch-page-helpers.d.mts +45 -0
  126. package/bin/github/batch-page-helpers.mjs +63 -0
  127. package/bin/github/batch-page.d.mts +14 -0
  128. package/bin/github/batch-page.mjs +62 -0
  129. package/bin/github/batch-parse-suites.d.mts +4 -0
  130. package/bin/github/batch-parse-suites.mjs +25 -0
  131. package/bin/github/batch-parser-helpers.d.mts +22 -0
  132. package/bin/github/batch-parsers-rules.d.mts +6 -0
  133. package/bin/github/batch-parsers-rules.mjs +122 -0
  134. package/bin/github/batch-parsers.d.mts +3 -0
  135. package/bin/github/batch-parsers.mjs +12 -0
  136. package/bin/github/batch-raw-rules.d.mts +59 -0
  137. package/bin/github/batch-raw-rules.mjs +1 -0
  138. package/bin/github/batch-raw-types.d.mts +216 -0
  139. package/bin/github/batch-response.d.mts +4 -0
  140. package/bin/github/batch.d.mts +24 -0
  141. package/bin/github/batch.mjs +14 -120
  142. package/bin/github/branch-protection.d.mts +3 -0
  143. package/bin/github/check-annotations.d.mts +2 -0
  144. package/bin/github/client.d.mts +46 -0
  145. package/bin/github/client.mjs +7 -2
  146. package/bin/github/errors.d.mts +25 -0
  147. package/bin/github/gql/batch-pr-page.gql +189 -0
  148. package/bin/github/gql/batch-pr.gql +79 -21
  149. package/bin/github/gql/commit-suggestion-thread.gql +40 -0
  150. package/bin/github/gql/review-thread-comments.gql +1 -0
  151. package/bin/github/graphql-http.d.mts +19 -0
  152. package/bin/github/graphql-response.d.mts +7 -0
  153. package/bin/github/http-auth.d.mts +4 -0
  154. package/bin/github/http-request.d.mts +7 -0
  155. package/bin/github/http-utils.d.mts +11 -0
  156. package/bin/github/http.d.mts +6 -0
  157. package/bin/github/http.mjs +2 -1
  158. package/bin/github/pagination.d.mts +46 -0
  159. package/bin/github/pagination.mjs +3 -2
  160. package/bin/github/queries.d.mts +28 -0
  161. package/bin/github/queries.mjs +4 -0
  162. package/bin/github/rest-http.d.mts +7 -0
  163. package/bin/github/rest-http.mjs +25 -86
  164. package/bin/github/rest-text.d.mts +1 -0
  165. package/bin/github/rest-text.mjs +88 -0
  166. package/bin/github/suggestion-thread.d.mts +9 -0
  167. package/bin/github/suggestion-thread.mjs +45 -0
  168. package/bin/github/thread-comments.d.mts +2 -0
  169. package/bin/github/thread-comments.mjs +12 -8
  170. package/bin/index.d.mts +10 -0
  171. package/bin/index.mjs +1 -1
  172. package/bin/log/log-file.d.mts +28 -0
  173. package/bin/log/session.d.mts +31 -0
  174. package/bin/log/setup.d.mts +6 -0
  175. package/bin/mcp/index.d.mts +5 -0
  176. package/bin/mcp/index.mjs +8 -0
  177. package/bin/mcp/server.d.mts +8 -0
  178. package/bin/mcp/server.mjs +157 -0
  179. package/bin/mcp-stdio.d.mts +2 -0
  180. package/bin/mcp-stdio.mjs +7 -0
  181. package/bin/merge-status/derive.d.mts +19 -0
  182. package/bin/merge-status/derive.mjs +2 -0
  183. package/bin/merge-status/requirements-format.d.mts +3 -0
  184. package/bin/merge-status/requirements-format.mjs +88 -0
  185. package/bin/merge-status/requirements.d.mts +2 -0
  186. package/bin/merge-status/requirements.mjs +51 -0
  187. package/bin/reporters/agent.d.mts +23 -0
  188. package/bin/reporters/agent.mjs +3 -0
  189. package/bin/state/base.d.mts +10 -0
  190. package/bin/state/base.mjs +23 -0
  191. package/bin/state/bot-cr-seen.d.mts +51 -0
  192. package/bin/state/bot-cr-seen.mjs +4 -14
  193. package/bin/state/fix-attempts.d.mts +27 -0
  194. package/bin/state/fix-attempts.mjs +3 -13
  195. package/bin/state/iterate-stall.d.mts +27 -0
  196. package/bin/state/iterate-stall.mjs +3 -13
  197. package/bin/state/seen-comments.d.mts +62 -0
  198. package/bin/state/seen-comments.mjs +6 -13
  199. package/bin/suggestions/extract.d.mts +8 -0
  200. package/bin/suggestions/parse.d.mts +48 -0
  201. package/bin/suggestions/patch.d.mts +14 -0
  202. package/bin/threads/transcript.d.mts +14 -0
  203. package/bin/threads/transcript.mjs +4 -0
  204. package/bin/types/activity.d.mts +30 -0
  205. package/bin/types/agent-thread.d.mts +9 -0
  206. package/bin/types/check-annotations.d.mts +14 -0
  207. package/bin/types/check-classification.d.mts +19 -0
  208. package/bin/types/github.d.mts +136 -0
  209. package/bin/types/iterate.d.mts +156 -0
  210. package/bin/types/merge-requirements.d.mts +82 -0
  211. package/bin/types/merge-requirements.mjs +2 -0
  212. package/bin/types/protected-run.d.mts +6 -0
  213. package/bin/types/report.d.mts +176 -0
  214. package/bin/types/review-thread.d.mts +12 -0
  215. package/bin/types.d.mts +10 -0
  216. package/bin/types.mjs +1 -0
  217. package/bin/util/markdown.d.mts +1 -0
  218. package/bin/util/path-segment.d.mts +4 -0
  219. package/bin/util/path-segment.mjs +2 -0
  220. package/bin/util/pool.d.mts +2 -0
  221. package/bin/util/pool.mjs +18 -0
  222. package/bin/util/sleep.d.mts +1 -0
  223. package/bin/util/worktree.d.mts +9 -0
  224. package/bin/util/worktree.mjs +4 -1
  225. package/package.json +51 -37
  226. package/plugins/pr-shepherd/.codex-plugin/plugin.json +3 -2
  227. package/plugins/pr-shepherd/.codex.mcp.json +8 -0
  228. package/plugins/pr-shepherd/.mcp.json +6 -0
  229. package/plugins/pr-shepherd/skills/mark-files-as-viewed/SKILL.md +5 -19
  230. package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -15
  231. package/src/classify/types.mts +12 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Build a git-apply-compatible unified diff for a single suggestion hunk.
3
+ *
4
+ * The diff uses `--- a/<path>` / `+++ b/<path>` headers so `git apply` and
5
+ * `git apply --check` accept it without a `diff --git` preamble.
6
+ */
7
+ export declare function buildUnifiedDiff({ path, originalContent, startLine, endLine, replacementLines, context, }: {
8
+ path: string;
9
+ originalContent: string;
10
+ startLine: number;
11
+ endLine: number;
12
+ replacementLines: readonly string[];
13
+ context?: number;
14
+ }): string;
@@ -0,0 +1,14 @@
1
+ import type { ReviewThread, ReviewThreadComment } from "../types.mts";
2
+ export declare function threadComments(thread: {
3
+ body: string;
4
+ author: string;
5
+ authorType?: ReviewThreadComment["authorType"];
6
+ authorAssociation?: ReviewThreadComment["authorAssociation"];
7
+ url?: string;
8
+ createdAtUnix?: number;
9
+ comments?: Array<Pick<ReviewThreadComment, "id" | "author" | "body" | "url"> & {
10
+ authorType?: ReviewThreadComment["authorType"];
11
+ authorAssociation?: ReviewThreadComment["authorAssociation"];
12
+ } & Partial<Pick<ReviewThreadComment, "isMinimized" | "createdAtUnix">>>;
13
+ }): ReviewThreadComment[];
14
+ export declare function threadTranscriptBody(thread: ReviewThread, appendedBodies?: string[]): string;
@@ -5,6 +5,7 @@ export function threadComments(thread) {
5
5
  isMinimized: c.isMinimized ?? false,
6
6
  author: c.author,
7
7
  authorType: c.authorType ?? "Unknown",
8
+ ...(c.authorAssociation !== undefined && { authorAssociation: c.authorAssociation }),
8
9
  body: c.body,
9
10
  url: c.url,
10
11
  createdAtUnix: c.createdAtUnix ?? 0,
@@ -16,6 +17,9 @@ export function threadComments(thread) {
16
17
  isMinimized: false,
17
18
  author: thread.author,
18
19
  authorType: thread.authorType ?? "Unknown",
20
+ ...(thread.authorAssociation !== undefined && {
21
+ authorAssociation: thread.authorAssociation,
22
+ }),
19
23
  body: thread.body,
20
24
  url: thread.url ?? "",
21
25
  createdAtUnix: thread.createdAtUnix ?? 0,
@@ -0,0 +1,30 @@
1
+ import type { AuthorType, CheckStatus, CommentAuthorAssociation } from "./github.mts";
2
+ type ReviewActivityKind = "pr-comment" | "review-thread-comment" | "review-summary" | "approved-review" | "changes-requested-review";
3
+ export interface ReviewActivityItem {
4
+ kind: ReviewActivityKind;
5
+ id: string;
6
+ author: string;
7
+ authorType: AuthorType;
8
+ authorAssociation?: CommentAuthorAssociation;
9
+ body: string;
10
+ url?: string;
11
+ createdAtUnix: number;
12
+ threadId?: string;
13
+ path?: string | null;
14
+ line?: number | null;
15
+ }
16
+ export interface PrActivitySummary {
17
+ commitCount: number;
18
+ reviewRoundCount: number;
19
+ latestCommitCommittedAtUnix: number | null;
20
+ reviewItemsSinceLatestCommit: ReviewActivityItem[];
21
+ }
22
+ export interface ActiveCheck {
23
+ name: string;
24
+ status: CheckStatus;
25
+ runId: string | null;
26
+ detailsUrl: string | null;
27
+ workflowName?: string;
28
+ summary?: string;
29
+ }
30
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { AuthorType, CommentAuthorAssociation } from "./github.mts";
2
+ export interface AgentThreadComment {
3
+ id: string;
4
+ author: string;
5
+ authorType?: AuthorType;
6
+ authorAssociation?: CommentAuthorAssociation;
7
+ body: string;
8
+ url: string;
9
+ }
@@ -0,0 +1,14 @@
1
+ export interface CheckAnnotation {
2
+ /** Stable marker id used by Shepherd; prefixed to avoid collisions with comment/review IDs. */
3
+ id: string;
4
+ path: string;
5
+ startLine: number | null;
6
+ endLine: number | null;
7
+ startColumn?: number | null;
8
+ endColumn?: number | null;
9
+ level: string;
10
+ title?: string;
11
+ message: string;
12
+ rawDetails?: string;
13
+ blobUrl?: string;
14
+ }
@@ -0,0 +1,19 @@
1
+ import type { CheckAnnotation } from "./check-annotations.mts";
2
+ import type { CheckRun } from "./github.mts";
3
+ type CheckCategory = "passed" | "failing" | "in_progress" | "skipped" | "filtered" | "ignored" | "superseded";
4
+ export interface ClassifiedCheck extends CheckRun {
5
+ category: CheckCategory;
6
+ }
7
+ export interface TriagedCheck extends ClassifiedCheck {
8
+ /** Workflow display name (e.g. `"CI"`). Populated when available from the jobs API; may be `undefined` on fetch failure or when no matching job is found. */
9
+ workflowName?: string;
10
+ /** Name of the matched job (e.g. `"tests (ubuntu)"`). Distinct from the check name for matrix builds. */
11
+ jobName?: string;
12
+ /** Name of the first failed step in the matched job (e.g. `"Run tests"`). */
13
+ failedStep?: string;
14
+ /** Bounded raw excerpt from the matched failed job log, when GitHub exposes one. */
15
+ logExcerpt?: string;
16
+ /** Inline annotations attached to this failing check run, surfaced once per PR. */
17
+ annotations?: CheckAnnotation[];
18
+ }
19
+ export {};
@@ -0,0 +1,136 @@
1
+ import type { ReviewThreadComment } from "./review-thread.mts";
2
+ import type { PrActivitySummary } from "./activity.mts";
3
+ import type { BatchPrMergeFields, MergeRequirements } from "./merge-requirements.mts";
4
+ export type CheckConclusion = "ACTION_REQUIRED" | "CANCELLED" | "FAILURE" | "NEUTRAL" | "SKIPPED" | "STALE" | "STARTUP_FAILURE" | "SUCCESS" | "TIMED_OUT" | null;
5
+ export type CheckStatus = "COMPLETED" | "IN_PROGRESS" | "PENDING" | "QUEUED" | "REQUESTED" | "WAITING";
6
+ export type MergeableState = "CONFLICTING" | "MERGEABLE" | "UNKNOWN";
7
+ export type MergeStateStatus = "BEHIND" | "BLOCKED" | "CLEAN" | "DIRTY" | "DRAFT" | "HAS_HOOKS" | "UNKNOWN" | "UNSTABLE";
8
+ export type ReviewDecision = "APPROVED" | "CHANGES_REQUESTED" | "REVIEW_REQUIRED" | null;
9
+ export type AuthorType = "User" | "Bot" | "Unknown";
10
+ /** Raw relationship between a comment author and the repository, as reported by GitHub. */
11
+ export type CommentAuthorAssociation = "COLLABORATOR" | "CONTRIBUTOR" | "FIRST_TIMER" | "FIRST_TIME_CONTRIBUTOR" | "MANNEQUIN" | "MEMBER" | "NONE" | "OWNER";
12
+ export interface CheckRun {
13
+ /** GitHub node ID for CheckRun contexts. Missing for StatusContext and synthetic checks. */
14
+ id?: string | null;
15
+ name: string;
16
+ status: CheckStatus;
17
+ conclusion: CheckConclusion;
18
+ source?: "check_run" | "status_context" | "startup_failure";
19
+ detailsUrl: string;
20
+ event: string | null;
21
+ runId: string | null;
22
+ createdAtUnix?: number;
23
+ startedAtUnix?: number;
24
+ completedAtUnix?: number;
25
+ updatedAtUnix?: number;
26
+ /** One-line status text shown in the GitHub UI (CheckRun.title or first line of summary; StatusContext.description). */
27
+ summary?: string;
28
+ /** Workflow display name for GitHub Actions check runs, when GraphQL exposes it. */
29
+ workflowName?: string;
30
+ workflowId?: string;
31
+ }
32
+ export interface ReviewThread {
33
+ id: string;
34
+ isResolved: boolean;
35
+ isOutdated: boolean;
36
+ isMinimized: boolean;
37
+ path: string | null;
38
+ line: number | null;
39
+ /** Start of the comment's line range. Null for single-line comments (use `line` for both). */
40
+ startLine: number | null;
41
+ /** PullRequestReview ID that created the top comment, when GitHub exposes it. */
42
+ reviewId?: string;
43
+ author: string;
44
+ authorType: AuthorType;
45
+ authorAssociation?: CommentAuthorAssociation;
46
+ body: string;
47
+ url: string;
48
+ createdAtUnix?: number;
49
+ comments?: ReviewThreadComment[];
50
+ /** True when Shepherd re-surfaced this thread because its body changed after first look. */
51
+ edited?: boolean;
52
+ }
53
+ /** Parsed GitHub ```suggestion block attached to a review thread. */
54
+ export interface SuggestionBlock {
55
+ /** 1-indexed inclusive start line. Equal to `endLine` for single-line suggestions. */
56
+ startLine: number;
57
+ /** 1-indexed inclusive end line. */
58
+ endLine: number;
59
+ /** Replacement lines verbatim. Empty array = delete; `[""]` = single blank line. Join with `"\n"` to display as a string. */
60
+ lines: readonly string[];
61
+ /** Reviewer login, surfaced so callers can co-credit them in commits. */
62
+ author: string;
63
+ }
64
+ export interface PrComment {
65
+ id: string;
66
+ isMinimized: boolean;
67
+ author: string;
68
+ authorType: AuthorType;
69
+ authorAssociation?: CommentAuthorAssociation;
70
+ body: string;
71
+ url: string;
72
+ createdAtUnix: number;
73
+ }
74
+ export interface Review {
75
+ id: string;
76
+ author: string;
77
+ authorType: AuthorType;
78
+ authorAssociation?: CommentAuthorAssociation;
79
+ body: string;
80
+ createdAtUnix?: number;
81
+ edited?: boolean;
82
+ /** True for bot CR re-surfaced after first look (body unchanged). Terse render. */
83
+ staleBotCr?: boolean;
84
+ /** Commit OID the review was made against, when available from GraphQL. */
85
+ commitOid?: string;
86
+ /** True when commitOid !== headRefOid AND all associated threads are resolved/outdated. Distinct from `staleBotCr` (time-based). Reviews with no threads are not marked stale. */
87
+ staleReview?: boolean;
88
+ }
89
+ export interface BranchProtection {
90
+ requiresApprovingReviews: boolean;
91
+ requiredApprovingReviewCount: number;
92
+ requiresConversationResolution: boolean;
93
+ requiresStatusChecks: boolean;
94
+ /** Required status check context names (e.g. "ci/build", "ci/test"). Empty when requiresStatusChecks is false, or when requiresStatusChecks is true but GitHub returns no explicit contexts. */
95
+ requiredStatusCheckContexts: string[];
96
+ }
97
+ export type ShepherdMergeStatus = "CLEAN" | "BEHIND" | "CONFLICTS" | "BLOCKED" | "UNSTABLE" | "DRAFT" | "UNKNOWN";
98
+ export interface MergeStatusResult {
99
+ status: ShepherdMergeStatus;
100
+ state: "OPEN" | "CLOSED" | "MERGED";
101
+ isDraft: boolean;
102
+ mergeable: MergeableState;
103
+ reviewDecision: ReviewDecision;
104
+ blockingBotReviewInProgress: boolean;
105
+ mergeStateStatus: MergeStateStatus;
106
+ mergeRequirements?: MergeRequirements;
107
+ }
108
+ export interface BatchPrData extends BatchPrMergeFields {
109
+ nodeId: string;
110
+ number: number;
111
+ state: "OPEN" | "CLOSED" | "MERGED";
112
+ isDraft: boolean;
113
+ mergeable: MergeableState;
114
+ mergeStateStatus: MergeStateStatus;
115
+ reviewDecision: ReviewDecision;
116
+ headRefOid: string;
117
+ headRefName: string;
118
+ /** `"owner/name"` of the head repository; null when the fork has been deleted. */
119
+ headRepoWithOwner: string | null;
120
+ baseRefName: string;
121
+ reviewRequests: Array<{
122
+ login: string;
123
+ }>;
124
+ latestReviews: Array<{
125
+ login: string;
126
+ state: string;
127
+ }>;
128
+ reviewThreads: ReviewThread[];
129
+ comments: PrComment[];
130
+ changesRequestedReviews: Review[];
131
+ reviewSummaries: Review[];
132
+ approvedReviews: Review[];
133
+ checks: CheckRun[];
134
+ branchProtection: BranchProtection | null;
135
+ activity?: PrActivitySummary;
136
+ }
@@ -0,0 +1,156 @@
1
+ import type { AgentThread, AgentComment, AgentCheck, GlobalOptions, RelevantCheck, ShepherdStatus, FirstLookThread, FirstLookComment } from "./report.mts";
2
+ import type { ActiveCheck, PrActivitySummary } from "./activity.mts";
3
+ import type { BranchProtection, CheckStatus, MergeStateStatus, Review, ReviewDecision, ReviewThread, ShepherdMergeStatus } from "./github.mts";
4
+ import type { MergeRequirements } from "./merge-requirements.mts";
5
+ import type { ProtectedRun } from "./protected-run.mts";
6
+ export type ShepherdAction = "wait" | "fix_code" | "mark_ready" | "cancel" | "escalate";
7
+ export type EscalateTrigger = "fix-thrash" | "base-branch-unknown" | "stall-timeout" | "thread-missing-location" | "bot-cr-not-dismissed";
8
+ export interface AgentStalledCheck {
9
+ name: string;
10
+ status: CheckStatus;
11
+ source: "check_run" | "status_context" | "startup_failure";
12
+ runId: string | null;
13
+ detailsUrl: string | null;
14
+ createdAtUnix?: number;
15
+ startedAtUnix?: number;
16
+ updatedAtUnix?: number;
17
+ ageSeconds: number;
18
+ summary?: string;
19
+ }
20
+ export interface EscalateDetails {
21
+ triggers: EscalateTrigger[];
22
+ unresolvedThreads: AgentThread[];
23
+ ambiguousComments: AgentComment[];
24
+ changesRequestedReviews: Review[];
25
+ /** Pending/unstarted CI checks that exceeded the stall timeout. */
26
+ stalledChecks?: AgentStalledCheck[];
27
+ /** Populated when fix-thrash triggered — threads that have been attempted too many times. */
28
+ thrashHistory?: Array<{
29
+ threadId: string;
30
+ attempts: number;
31
+ }>;
32
+ suggestion: string;
33
+ humanMessage: string;
34
+ }
35
+ export interface IterateResultSummary {
36
+ passing: number;
37
+ skipped: number;
38
+ filtered: number;
39
+ inProgress: number;
40
+ superseded: number;
41
+ }
42
+ export interface IterateResultBase {
43
+ pr: number;
44
+ repo: string;
45
+ status: ShepherdStatus;
46
+ state: "OPEN" | "CLOSED" | "MERGED" | "UNKNOWN";
47
+ mergeStateStatus: MergeStateStatus;
48
+ mergeStatus: ShepherdMergeStatus;
49
+ reviewDecision: ReviewDecision;
50
+ blockingBotReviewInProgress: boolean;
51
+ isDraft: boolean;
52
+ shouldCancel: boolean;
53
+ remainingSeconds: number;
54
+ summary: IterateResultSummary;
55
+ /** Validated base branch (e.g. "main") for this PR. */
56
+ baseBranch: string;
57
+ /** Null when no classic protection rule exists or the base ref is unavailable. */
58
+ branchProtection: BranchProtection | null;
59
+ mergeRequirements?: MergeRequirements;
60
+ /**
61
+ * PR-event checks that completed and are not skipped/neutral.
62
+ * Failing entries carry `workflowName`, `jobName`, `failedStep`, and `summary`.
63
+ */
64
+ checks: RelevantCheck[];
65
+ inProgressChecks?: ActiveCheck[];
66
+ ignoredNames?: string[];
67
+ supersededNames?: string[];
68
+ activity?: PrActivitySummary;
69
+ }
70
+ interface IterateResultWait extends IterateResultBase {
71
+ action: "wait";
72
+ log: string;
73
+ }
74
+ export type CancelReason = "merged" | "closed" | "ready-delay-elapsed";
75
+ interface IterateResultCancel extends IterateResultBase {
76
+ action: "cancel";
77
+ reason: CancelReason;
78
+ log: string;
79
+ }
80
+ export interface ResolveCommand {
81
+ /** Argv for spawn-style execution. May contain a `$DISMISS_MESSAGE` placeholder. `$HEAD_SHA` is never in `argv` — `renderResolveCommand` (from `commands/iterate/render.mts`) appends `--require-sha "$HEAD_SHA"` when rendering if `requiresHeadSha` is true. Use `renderResolveCommand` to render as a command string; don't naive-join. */
82
+ argv: string[];
83
+ /** When true, `renderResolveCommand` appends `--require-sha "$HEAD_SHA"` to the rendered command. */
84
+ requiresHeadSha: boolean;
85
+ /** Whether the model must substitute $DISMISS_MESSAGE with a specific description of the fix. */
86
+ requiresDismissMessage: boolean;
87
+ /** Thread IDs that should receive a reply instead of a resolve mutation. */
88
+ replyThreadIds?: string[];
89
+ /** Thread IDs that should be resolved on GitHub. Human-authored IDs must not appear here. */
90
+ resolveThreadIds?: string[];
91
+ /** Bot/non-human CHANGES_REQUESTED review IDs to dismiss. Human-authored IDs must not appear here. */
92
+ dismissReviewIds?: string[];
93
+ /** True when any mutation flag was appended (threads/comments/reviews). False for a bare runner-specific `pr-shepherd apply review <PR>` with nothing to do. Callers use this to gate emitting an apply instruction — coupling to argv length would break silently if the base argv ever grew a global flag. */
94
+ hasMutations: boolean;
95
+ }
96
+ /**
97
+ * Default fix_code variant: agent applies edits locally, commits, pushes,
98
+ * then runs the pre-built apply command. Emitted under `## Post-fix push`.
99
+ */
100
+ interface FixRebaseAndPush {
101
+ threads: AgentThread[];
102
+ /** Unresolved threads that should be resolved on GitHub without requiring code edits. */
103
+ resolutionOnlyThreads: ReviewThread[];
104
+ /** PR comment bodies surfaced to the agent for evaluation, including previously filtered bot/noise comments; do not treat `actionableComments.length` as a proxy for "must push code". */
105
+ actionableComments: AgentComment[];
106
+ /** Review IDs (COMMENTED summaries and, if opted in, APPROVED reviews) to minimize — no code change needed. */
107
+ reviewSummaryIds: string[];
108
+ /** COMMENTED review summaries surfaced to the agent for the first time this iteration — body shown inline. */
109
+ firstLookSummaries: Review[];
110
+ /** COMMENTED review summaries whose body changed since the agent first saw them. Body shown inline; IDs not in `reviewSummaryIds`. */
111
+ editedSummaries: Review[];
112
+ /** APPROVED-state reviews surfaced for visibility (when `iterate.minimizeApprovals` is false). */
113
+ surfacedApprovals: Review[];
114
+ checks: AgentCheck[];
115
+ changesRequestedReviews: Review[];
116
+ /** Pre-built apply command. Run after committing and pushing. */
117
+ resolveCommand: ResolveCommand;
118
+ /** When present, run this command first (no SHA substitution needed) to resolve bot threads and minimize comments, independent of any push. */
119
+ resolveOnlyCommand?: ResolveCommand;
120
+ /** Ordered steps for the model to follow. */
121
+ instructions: string[];
122
+ /** Run IDs of in-progress GitHub Actions checks. The agent should cancel these before pushing new commits; if it decides not to push (e.g. resolve-only), it may skip cancellation. Empty when all in-progress runs are external status checks or already cancelled. */
123
+ inProgressRunIds: string[];
124
+ /** Workflow runs deliberately excluded from cancellation by actions.neverCancelRuns. */
125
+ protectedRuns: ProtectedRun[];
126
+ /** First-look threads — previously hidden, surfaced for acknowledgment only. */
127
+ firstLookThreads: FirstLookThread[];
128
+ /** First-look comments — previously hidden, surfaced for acknowledgment only. */
129
+ firstLookComments: FirstLookComment[];
130
+ }
131
+ export interface IterateResultFixCode extends IterateResultBase {
132
+ action: "fix_code";
133
+ fix: FixRebaseAndPush;
134
+ cancelled: string[];
135
+ }
136
+ interface IterateResultMarkReady extends IterateResultBase {
137
+ action: "mark_ready";
138
+ markedReady: boolean;
139
+ log: string;
140
+ }
141
+ interface IterateResultEscalate extends IterateResultBase {
142
+ action: "escalate";
143
+ escalate: EscalateDetails;
144
+ }
145
+ export type IterateResult = IterateResultWait | IterateResultCancel | IterateResultFixCode | IterateResultMarkReady | IterateResultEscalate;
146
+ export interface IterateCommandOptions extends GlobalOptions {
147
+ readyDelaySeconds?: number;
148
+ noAutoMarkReady?: boolean;
149
+ noAutoCancelActionable?: boolean;
150
+ /** Override stall timeout seconds. Defaults to config.iterate.stallTimeoutMinutes * 60. */
151
+ stallTimeoutSeconds?: number;
152
+ /** Case-insensitive workflow/check glob patterns Shepherd must not cancel. */
153
+ neverCancelRuns?: string[];
154
+ persistSeen?: boolean;
155
+ }
156
+ export {};
@@ -0,0 +1,82 @@
1
+ /** Branch-rule and "why can't I merge" types shared by batch data and merge status. */
2
+ export interface BranchRules {
3
+ requiredApprovingReviewCount: number;
4
+ requiresConversationResolution: boolean;
5
+ requiresCodeOwnerReviews: boolean;
6
+ requiresLastPushApproval: boolean;
7
+ requiresCommitSignatures: boolean;
8
+ requiresLinearHistory: boolean;
9
+ requiresStrictStatusChecks: boolean;
10
+ requiredStatusCheckContexts: string[];
11
+ requiredDeploymentEnvironments: string[];
12
+ requiresMergeQueue: boolean;
13
+ requiresWorkflows: boolean;
14
+ requiresCodeScanning: boolean;
15
+ }
16
+ export interface MergeQueueEntryStatus {
17
+ position: number;
18
+ state: string;
19
+ estimatedTimeToMerge: number | null;
20
+ }
21
+ export interface StackStatus {
22
+ number: number;
23
+ size: number;
24
+ position: number;
25
+ baseRefName: string;
26
+ }
27
+ /** Extra batch-PR fields for merge-queue, stacks, and folded branch rules. */
28
+ export interface BatchPrMergeFields {
29
+ branchRules?: BranchRules;
30
+ isInMergeQueue?: boolean;
31
+ isMergeQueueEnabled?: boolean;
32
+ mergeQueueEntry?: MergeQueueEntryStatus | null;
33
+ stack?: StackStatus | null;
34
+ }
35
+ /** Snapshot of "why can't I merge" requirements vs current PR state. */
36
+ export interface MergeRequirements {
37
+ approvals: {
38
+ current: number;
39
+ requiredCount: number;
40
+ };
41
+ conversationsResolved: {
42
+ resolved: boolean;
43
+ unresolvedCount: number;
44
+ required: boolean;
45
+ };
46
+ codeOwnerReview?: {
47
+ required: true;
48
+ };
49
+ lastPushApproval?: {
50
+ required: true;
51
+ };
52
+ signedCommits?: {
53
+ required: true;
54
+ };
55
+ linearHistory?: {
56
+ required: true;
57
+ };
58
+ branchUpToDate?: {
59
+ current: boolean;
60
+ required: true;
61
+ };
62
+ requiredStatusChecks?: {
63
+ contexts: string[];
64
+ };
65
+ requiredDeployments?: {
66
+ environments: string[];
67
+ };
68
+ requiredWorkflows?: {
69
+ required: true;
70
+ };
71
+ codeScanning?: {
72
+ required: true;
73
+ };
74
+ mergeQueue?: {
75
+ required: boolean;
76
+ enabled: boolean;
77
+ inQueue: boolean;
78
+ position?: number;
79
+ state?: string;
80
+ };
81
+ stack?: StackStatus;
82
+ }
@@ -0,0 +1,2 @@
1
+ /** Branch-rule and "why can't I merge" types shared by batch data and merge status. */
2
+ export {};
@@ -0,0 +1,6 @@
1
+ export interface ProtectedRun {
2
+ runId: string;
3
+ matchedPattern: string;
4
+ checkNames: string[];
5
+ workflowName?: string;
6
+ }