pr-shepherd 0.60.1 → 1.0.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 (197) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +7 -5
  3. package/bin/api.d.mts +35 -24
  4. package/bin/api.mjs +68 -48
  5. package/bin/checks/classify.d.mts +1 -1
  6. package/bin/checks/classify.mjs +4 -4
  7. package/bin/checks/log-excerpt.mjs +1 -1
  8. package/bin/cli/arg-flags.mjs +0 -3
  9. package/bin/cli/clean-handler.d.mts +1 -1
  10. package/bin/cli/clean-handler.mjs +5 -15
  11. package/bin/cli/default-poll.d.mts +2 -0
  12. package/bin/cli/default-poll.mjs +9 -6
  13. package/bin/cli/formatters.d.mts +2 -3
  14. package/bin/cli/formatters.mjs +0 -26
  15. package/bin/cli/handlers.d.mts +3 -3
  16. package/bin/cli/handlers.mjs +45 -35
  17. package/bin/cli/help-command-pages.d.mts +13 -158
  18. package/bin/cli/help-command-pages.mjs +12 -157
  19. package/bin/cli/help-iterate-poll-pages.d.mts +4 -3
  20. package/bin/cli/help-iterate-poll-pages.mjs +76 -36
  21. package/bin/cli/help-log-file-page.d.mts +1 -1
  22. package/bin/cli/help-log-file-page.mjs +3 -5
  23. package/bin/cli/help-top-page.d.mts +1 -1
  24. package/bin/cli/help-top-page.mjs +19 -20
  25. package/bin/cli/help.d.mts +14 -159
  26. package/bin/cli/iterate-checks-formatter.mjs +1 -1
  27. package/bin/cli/iterate-flags.d.mts +2 -4
  28. package/bin/cli/iterate-flags.mjs +4 -20
  29. package/bin/cli/iterate-formatter.d.mts +1 -1
  30. package/bin/cli/iterate-formatter.mjs +6 -6
  31. package/bin/cli/iterate-instructions.d.mts +1 -1
  32. package/bin/cli/iterate-instructions.mjs +5 -6
  33. package/bin/cli/iterate-lean.mjs +32 -40
  34. package/bin/cli/iterate-verbose.mjs +1 -1
  35. package/bin/cli/journal-formatter.mjs +0 -3
  36. package/bin/cli/journal-handler.d.mts +1 -1
  37. package/bin/cli/journal-handler.mjs +2 -1
  38. package/bin/cli/mutate-formatter.mjs +0 -9
  39. package/bin/cli/next-check-format.d.mts +0 -4
  40. package/bin/cli/next-check-format.mjs +0 -4
  41. package/bin/cli/poll-handler.d.mts +3 -0
  42. package/bin/cli/poll-handler.mjs +88 -47
  43. package/bin/cli/poll-summary-emitter.mjs +2 -2
  44. package/bin/cli/poll-summary-formatter.mjs +2 -2
  45. package/bin/cli/poll-targets.d.mts +2 -2
  46. package/bin/cli/poll-targets.mjs +15 -35
  47. package/bin/cli/removed-flags.d.mts +3 -0
  48. package/bin/cli/removed-flags.mjs +24 -0
  49. package/bin/cli/runner.d.mts +1 -1
  50. package/bin/cli/runner.mjs +2 -2
  51. package/bin/cli/stack-overview.d.mts +0 -1
  52. package/bin/cli/stack-overview.mjs +1 -2
  53. package/bin/cli/{fix-formatter-extra.d.mts → triage-formatter-extra.d.mts} +1 -2
  54. package/bin/cli/{fix-formatter-extra.mjs → triage-formatter-extra.mjs} +0 -6
  55. package/bin/cli/triage-formatter.d.mts +4 -0
  56. package/bin/cli/{fix-formatter.mjs → triage-formatter.mjs} +31 -42
  57. package/bin/cli/unknown-flags.d.mts +6 -0
  58. package/bin/cli/unknown-flags.mjs +29 -0
  59. package/bin/cli-parser.mjs +41 -62
  60. package/bin/commands/check-annotations.d.mts +1 -1
  61. package/bin/commands/check-annotations.mjs +1 -1
  62. package/bin/commands/check-review-budget.d.mts +1 -1
  63. package/bin/commands/check-review-budget.mjs +1 -1
  64. package/bin/commands/check-wait-detectors.d.mts +1 -1
  65. package/bin/commands/check-wait-detectors.mjs +1 -1
  66. package/bin/commands/check.d.mts +1 -1
  67. package/bin/commands/check.mjs +7 -7
  68. package/bin/commands/commit-suggestion-instruction.d.mts +2 -2
  69. package/bin/commands/commit-suggestion-instruction.mjs +3 -3
  70. package/bin/commands/iterate/api-usage.mjs +8 -8
  71. package/bin/commands/iterate/check-instructions.d.mts +4 -4
  72. package/bin/commands/iterate/check-instructions.mjs +8 -8
  73. package/bin/commands/iterate/classify.mjs +2 -2
  74. package/bin/commands/iterate/escalate.mjs +6 -6
  75. package/bin/commands/iterate/index.mjs +20 -23
  76. package/bin/commands/iterate/merge-plan.mjs +3 -3
  77. package/bin/commands/iterate/merge-state.mjs +4 -7
  78. package/bin/commands/iterate/native-stack-rebase.mjs +1 -1
  79. package/bin/commands/iterate/render.d.mts +1 -1
  80. package/bin/commands/iterate/render.mjs +2 -2
  81. package/bin/commands/iterate/stall.mjs +11 -9
  82. package/bin/commands/iterate/{fix-loop-instruction.mjs → triage-loop-instruction.mjs} +7 -3
  83. package/bin/commands/iterate/{fix-code.d.mts → triage.d.mts} +2 -2
  84. package/bin/commands/iterate/{fix-code.mjs → triage.mjs} +14 -23
  85. package/bin/commands/iterate/unreported-required.mjs +2 -5
  86. package/bin/commands/journal/index.d.mts +1 -3
  87. package/bin/commands/journal/index.mjs +1 -1
  88. package/bin/commands/mark-files-as-viewed.d.mts +1 -3
  89. package/bin/commands/mark-files-as-viewed.mjs +1 -1
  90. package/bin/commands/next-check.d.mts +2 -2
  91. package/bin/commands/next-check.mjs +4 -2
  92. package/bin/commands/poll-progress.mjs +1 -1
  93. package/bin/commands/poll-summary-explicit-instructions.mjs +1 -1
  94. package/bin/commands/poll-summary-instructions.mjs +7 -7
  95. package/bin/commands/poll-summary.mjs +4 -4
  96. package/bin/commands/poll.d.mts +1 -1
  97. package/bin/commands/poll.mjs +4 -4
  98. package/bin/commands/resolve-mutate.d.mts +1 -1
  99. package/bin/commands/resolve-mutate.mjs +1 -1
  100. package/bin/commands/rest-stack-merge-readiness.mjs +1 -1
  101. package/bin/commands/single-tick.d.mts +5 -0
  102. package/bin/commands/single-tick.mjs +7 -0
  103. package/bin/commands/stack-drain.mjs +1 -1
  104. package/bin/commands/stack-merge-flag.mjs +1 -1
  105. package/bin/commands/stack-stall.d.mts +2 -2
  106. package/bin/commands/stack-stall.mjs +2 -2
  107. package/bin/commands/stack-work.d.mts +2 -2
  108. package/bin/commands/stack-work.mjs +2 -2
  109. package/bin/commands/suggestion-patch-item.d.mts +0 -1
  110. package/bin/commands/suggestion-patch-item.mjs +0 -12
  111. package/bin/commands/suggestion-patches.d.mts +2 -2
  112. package/bin/commands/suggestion-patches.mjs +1 -1
  113. package/bin/commands/tick-instructions.d.mts +9 -0
  114. package/bin/commands/tick-instructions.mjs +23 -0
  115. package/bin/commands/tick.d.mts +15 -0
  116. package/bin/commands/{event-mode.mjs → tick.mjs} +39 -55
  117. package/bin/comments/minimize-policy.mjs +1 -3
  118. package/bin/comments/resolve.d.mts +0 -23
  119. package/bin/comments/resolve.mjs +0 -4
  120. package/bin/comments/review-output-budget.d.mts +1 -1
  121. package/bin/comments/review-output-budget.mjs +1 -1
  122. package/bin/comments/sha-poll.mjs +3 -1
  123. package/bin/config/default-bot-usernames.d.mts +2 -0
  124. package/bin/config/default-bot-usernames.mjs +15 -0
  125. package/bin/config/load.d.mts +4 -138
  126. package/bin/config/load.mjs +88 -443
  127. package/bin/config/merge-command-args.mjs +2 -2
  128. package/bin/config/merge-method.d.mts +1 -2
  129. package/bin/config/merge-method.mjs +1 -8
  130. package/bin/config/renames.d.mts +8 -0
  131. package/bin/config/renames.mjs +87 -0
  132. package/bin/config/resolve.d.mts +31 -0
  133. package/bin/config/resolve.mjs +89 -0
  134. package/bin/config/schema.d.mts +161 -0
  135. package/bin/config/schema.mjs +168 -0
  136. package/bin/exit-codes.d.mts +1 -1
  137. package/bin/exit-codes.mjs +3 -3
  138. package/bin/github/poll-summary-check-blockers.mjs +1 -1
  139. package/bin/github/poll-summary-command.mjs +8 -6
  140. package/bin/github/poll-summary-projector.mjs +2 -2
  141. package/bin/github/poll-summary-review.mjs +1 -1
  142. package/bin/github/poll-summary-route.mjs +9 -9
  143. package/bin/github/poll-summary-unreported.mjs +1 -1
  144. package/bin/github/poll-summary.mjs +1 -1
  145. package/bin/github/queries.d.mts +1 -1
  146. package/bin/github/queries.mjs +1 -1
  147. package/bin/mcp/server.mjs +48 -54
  148. package/bin/merge-status/derive.mjs +1 -1
  149. package/bin/state/durable-state.d.mts +1 -3
  150. package/bin/state/durable-state.mjs +2 -8
  151. package/bin/state/fix-attempts.d.mts +2 -2
  152. package/bin/state/fix-attempts.mjs +1 -1
  153. package/bin/state/merge-request.mjs +1 -1
  154. package/bin/state/pr-fingerprint.mjs +4 -11
  155. package/bin/state/seen-comments.d.mts +4 -5
  156. package/bin/state/seen-comments.mjs +8 -14
  157. package/bin/state/stack-stall.d.mts +1 -1
  158. package/bin/state/stack-stall.mjs +1 -1
  159. package/bin/state/stall-state-store.d.mts +1 -1
  160. package/bin/state/stall-state-store.mjs +1 -1
  161. package/bin/types/escalate.d.mts +2 -2
  162. package/bin/types/iterate.d.mts +12 -26
  163. package/bin/types/merge-queue.d.mts +2 -2
  164. package/bin/types/next-check.d.mts +1 -1
  165. package/bin/types/poll-summary.d.mts +3 -6
  166. package/bin/types/report.d.mts +2 -2
  167. package/bin/types/suggestion-patch.d.mts +1 -8
  168. package/package.json +2 -1
  169. package/plugins/pr-shepherd/.claude-plugin/plugin.json +1 -1
  170. package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
  171. package/plugins/pr-shepherd/.codex.mcp.json +1 -1
  172. package/plugins/pr-shepherd/.mcp.json +1 -1
  173. package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -6
  174. package/plugins/pr-shepherd/skills/pr-shepherd/references/ci-failure-triage.md +1 -1
  175. package/plugins/pr-shepherd/skills/pr-shepherd/references/{cloud-event-loop.md → event-loop.md} +5 -5
  176. package/plugins/pr-shepherd/skills/pr-shepherd/references/mcp-fallback.md +3 -3
  177. package/plugins/pr-shepherd/skills/pr-shepherd/references/merge-queue-ejection.md +1 -1
  178. package/plugins/pr-shepherd/skills/pr-shepherd/references/suggestion-patches.md +1 -1
  179. package/plugins/pr-shepherd/skills/pr-shepherd/references/{fix-code-loop.md → triage-loop.md} +3 -3
  180. package/plugins/pr-shepherd/skills/reduce-pr-noise/SKILL.md +1 -1
  181. package/plugins/pr-shepherd/skills/reduce-pr-noise/references/classifiers.md +2 -2
  182. package/plugins/pr-shepherd/skills/reduce-pr-noise/references/settings.md +11 -11
  183. package/pr-shepherd.schema.json +361 -0
  184. package/bin/cli/event-state-scope.d.mts +0 -19
  185. package/bin/cli/event-state-scope.mjs +0 -60
  186. package/bin/cli/fix-formatter.d.mts +0 -4
  187. package/bin/commands/commit-suggestion.d.mts +0 -8
  188. package/bin/commands/commit-suggestion.mjs +0 -26
  189. package/bin/commands/event-instructions.d.mts +0 -11
  190. package/bin/commands/event-instructions.mjs +0 -27
  191. package/bin/commands/event-mode.d.mts +0 -14
  192. package/bin/commands/poll-mode.d.mts +0 -8
  193. package/bin/commands/poll-mode.mjs +0 -14
  194. package/bin/config.json +0 -68
  195. package/bin/types/protected-run.d.mts +0 -6
  196. package/bin/types/protected-run.mjs +0 -1
  197. /package/bin/commands/iterate/{fix-loop-instruction.d.mts → triage-loop-instruction.d.mts} +0 -0
@@ -1,54 +1,30 @@
1
1
  import { loadConfig } from "../config/load.mjs";
2
2
  import { readStallState } from "../state/iterate-stall.mjs";
3
- import { runWithDurableState } from "../state/durable-state.mjs";
4
- import { eventAggregateStep, eventFixContinuation } from "./event-instructions.mjs";
3
+ import { tickAggregateStep } from "./tick-instructions.mjs";
5
4
  import { earliestNextCheck, MERGE_QUEUE_RECHECK_SECONDS, nextCheckCandidates, SAFETY_NET_SECONDS, } from "./next-check.mjs";
6
- import { isFixCodeContinuation } from "./iterate/check-instructions.mjs";
7
5
  import { isHandedOffSelection, onlyDraftVerificationSelection, } from "./poll-summary-explicit-instructions.mjs";
8
6
  import { runIterate } from "./iterate/index.mjs";
9
- import { resolvePollMode } from "./poll-mode.mjs";
7
+ import { runsSingleTick } from "./single-tick.mjs";
10
8
  import { readStackStallDeadline } from "./stack-stall.mjs";
11
9
  import { runPoll } from "./poll.mjs";
12
10
  import { runAggregatePoll, runPollSummary, } from "./poll-summary.mjs";
13
- function isEventMode(requested) {
14
- return resolvePollMode(requested, loadConfig().poll.mode) === "event";
15
- }
16
11
  /**
17
- * One iterate tick. In event mode the tick runs exactly once with no settle window and no
18
- * sleeping, persists seen markers immediately, and reports when to come back.
12
+ * One iterate tick: no settle window and no sleeping, seen markers persist immediately, and
13
+ * `nextCheck` reports when to come back if no GitHub event arrives first. The tick's result is
14
+ * never discarded, so edited-comment markers are written on the result it returns.
19
15
  */
20
- export function runIterateForMode(opts) {
21
- if (!isEventMode(opts.pollMode))
22
- return runIterate(opts);
23
- return runWithDurableState(() => runIterateEvent(opts));
24
- }
25
- /** One aggregate tick; event mode adds `pollMode` and `nextCheck`. */
26
- export function runPollSummaryForMode(opts) {
27
- if (!isEventMode(opts.pollMode))
28
- return runPollSummary(opts);
29
- const eventOpts = { ...opts, pollMode: "event" };
30
- return runWithDurableState(async () => withAggregateNextCheck(await runPollSummary(eventOpts), eventOpts));
31
- }
32
- /** The default poll command: the sleeping loop in poll mode, one tick in event mode. */
33
- export function runPollForMode(opts) {
34
- if (!isEventMode(opts.pollMode))
35
- return runPoll(opts);
36
- const { intervalSeconds: _intervalSeconds, timeoutSeconds: _timeoutSeconds, debounceSeconds: _debounceSeconds, quietStatus: _quietStatus, untilTerminal: _untilTerminal, ...tick } = opts;
37
- return runIterateForMode(tick);
38
- }
39
- /** The aggregate poll command: the sleeping loop in poll mode, one tick in event mode. */
40
- export function runAggregatePollForMode(opts) {
41
- return isEventMode(opts.pollMode) ? runPollSummaryForMode(opts) : runAggregatePoll(opts);
42
- }
43
- async function runIterateEvent(opts) {
44
- const { pollMode: _pollMode, ...iterateOpts } = opts;
16
+ export async function runIterateTick(opts) {
45
17
  const sink = {};
46
18
  const result = await runIterate({
47
- ...iterateOpts,
19
+ ...opts,
48
20
  persistSeen: true,
21
+ deferEditedCommentMarkers: false,
49
22
  fingerprintCache: false,
50
23
  stallDeadlineSink: sink,
51
24
  });
25
+ // `[TRIAGE]` already reruns at once, and that rerun reports its own `nextCheck`.
26
+ if (result.action === "triage")
27
+ return result;
52
28
  const nowMs = Date.now();
53
29
  const stallDeadlineSeconds = earliestDeadline(await readStallDeadline(result, opts.stallTimeoutSeconds), result.action === "wait" ? sink.ciStartDeadlineSeconds : undefined);
54
30
  const nextCheck = earliestNextCheck(nextCheckCandidates({
@@ -57,17 +33,23 @@ async function runIterateEvent(opts) {
57
33
  queued: result.mergeQueue?.inQueue === true,
58
34
  restMerge: result.action === "merge" && result.merge.mode === "rest",
59
35
  stallDeadlineSeconds,
60
- }, nowMs), nowMs);
61
- const tagged = { ...result, pollMode: "event", ...(nextCheck && { nextCheck }) };
62
- if (tagged.action !== "fix_code" || !nextCheck)
63
- return tagged;
64
- return {
65
- ...tagged,
66
- fix: {
67
- ...tagged.fix,
68
- instructions: tagged.fix.instructions.map((step) => isFixCodeContinuation(step) ? eventFixContinuation(nextCheck) : step),
69
- },
70
- };
36
+ }, nowMs), nowMs, quotaFloorSeconds(result.quotaWarning));
37
+ return nextCheck ? { ...result, nextCheck } : result;
38
+ }
39
+ /** One aggregate tick, with `nextCheck` unless nothing remains to wait for. */
40
+ export async function runPollSummaryTick(opts) {
41
+ return withAggregateNextCheck(await runPollSummary({ ...opts, tick: true }), opts);
42
+ }
43
+ /** The default command: the sleeping loop, or one tick in a cloud session. */
44
+ export function runPollCommand(opts) {
45
+ if (!runsSingleTick())
46
+ return runPoll(opts);
47
+ const { intervalSeconds: _intervalSeconds, timeoutSeconds: _timeoutSeconds, debounceSeconds: _debounceSeconds, quietStatus: _quietStatus, untilTerminal: _untilTerminal, ...tick } = opts;
48
+ return runIterateTick(tick);
49
+ }
50
+ /** The aggregate loop (`stack`, several PRs), or one tick in a cloud session. */
51
+ export function runAggregatePollCommand(opts) {
52
+ return runsSingleTick() ? runPollSummaryTick(opts) : runAggregatePoll(opts);
71
53
  }
72
54
  function earliestDeadline(...deadlines) {
73
55
  const known = deadlines.filter((d) => d !== undefined);
@@ -75,9 +57,9 @@ function earliestDeadline(...deadlines) {
75
57
  }
76
58
  /** When an unchanged state would trip the stall timeout, or undefined when no timer is running. */
77
59
  async function readStallDeadline(result, stallTimeoutSeconds) {
78
- if (!["wait", "fix_code"].includes(result.action))
60
+ if (result.action !== "wait")
79
61
  return undefined;
80
- const timeout = stallTimeoutSeconds ?? loadConfig().iterate.stallTimeoutMinutes * 60;
62
+ const timeout = stallTimeoutSeconds ?? loadConfig().iterate["stall-timeout-minutes"] * 60;
81
63
  const [owner, repo] = result.repo.split("/");
82
64
  if (timeout <= 0 || !owner || !repo)
83
65
  return undefined;
@@ -85,23 +67,22 @@ async function readStallDeadline(result, stallTimeoutSeconds) {
85
67
  return read.ok && read.state ? read.state.firstSeenAt + timeout : undefined;
86
68
  }
87
69
  async function withAggregateNextCheck(result, opts) {
88
- const tagged = { ...result, pollMode: "event" };
89
- const stallDeadlineSeconds = await readStackStallDeadline(result, opts.stallTimeoutSeconds ?? loadConfig().iterate.stallTimeoutMinutes * 60);
70
+ const stallDeadlineSeconds = await readStackStallDeadline(result, opts.stallTimeoutSeconds ?? loadConfig().iterate["stall-timeout-minutes"] * 60);
90
71
  const nextCheck = aggregateNextCheck(result, stallDeadlineSeconds);
91
72
  if (!nextCheck)
92
- return tagged;
73
+ return result;
93
74
  const instructions = (result.instructions ?? []).map(withoutPollingCadence);
94
75
  const waiting = result.reason === "waiting" || result.reason === "timeout";
95
76
  return {
96
- ...tagged,
77
+ ...result,
97
78
  nextCheck,
98
79
  instructions: [
99
80
  ...instructions,
100
- `${instructions.length + 1}. ${eventAggregateStep(nextCheck, waiting)}`,
81
+ `${instructions.length + 1}. ${tickAggregateStep(nextCheck, waiting)}`,
101
82
  ],
102
83
  };
103
84
  }
104
- /** The appended event step owns timing, including pending stack merges. */
85
+ /** The appended tick step owns timing, including pending stack merges. */
105
86
  function withoutPollingCadence(step) {
106
87
  return step
107
88
  .replace(/ Recheck(?: them)? at the configured polling cadence\./g, "")
@@ -130,5 +111,8 @@ function aggregateNextCheck(result, stallDeadlineSeconds) {
130
111
  if (stallDeadlineSeconds !== undefined) {
131
112
  candidates.push({ reason: "stall-timeout", seconds: stallDeadlineSeconds - nowMs / 1000 });
132
113
  }
133
- return earliestNextCheck(candidates, nowMs);
114
+ return earliestNextCheck(candidates, nowMs, quotaFloorSeconds(result.quotaWarning));
115
+ }
116
+ function quotaFloorSeconds(warning) {
117
+ return warning === undefined ? 0 : warning.pollIntervalMinutes * 60;
134
118
  }
@@ -9,11 +9,9 @@ export function shouldMinimizeAuthor(authorType, policy, author, botUsernames =
9
9
  return authorType !== "User" || isConfiguredBot;
10
10
  case "bots":
11
11
  return isConfiguredBot;
12
- case "users":
13
- return false;
14
12
  case "none":
15
13
  return false;
16
14
  default:
17
- throw new Error(`Invalid minimizeComments policy: ${String(policy)}`);
15
+ throw new Error(`Invalid iterate.minimize-comments policy: ${String(policy)}`);
18
16
  }
19
17
  }
@@ -8,24 +8,6 @@ export interface ResolveResult {
8
8
  minimizedComments: string[];
9
9
  dismissedReviews: string[];
10
10
  errors: string[];
11
- /** @deprecated Direct apply forwards every supplied dismissal ID to GitHub. */
12
- skippedDismissals?: string[];
13
- /** @deprecated Direct apply no longer applies author policy. */
14
- skippedHumanResolves?: string[];
15
- /** @deprecated Direct apply no longer applies author policy. */
16
- skippedHumanMinimizes?: string[];
17
- /** @deprecated Direct apply no longer applies author policy. */
18
- skippedHumanDismissals?: string[];
19
- /** @deprecated Direct apply forwards every supplied reply ID to GitHub. */
20
- skippedNonHumanReplies?: string[];
21
- /** @deprecated Direct apply requests now rely on GitHub's mutation response. */
22
- skippedUnauthorizedReplies?: string[];
23
- /** @deprecated Direct apply requests now rely on GitHub's mutation response. */
24
- skippedUnauthorizedResolves?: string[];
25
- /** @deprecated Direct apply requests now rely on GitHub's mutation response. */
26
- skippedUnauthorizedMinimizes?: string[];
27
- /** @deprecated Direct apply requests now rely on GitHub's mutation response. */
28
- skippedUnauthorizedDismissals?: string[];
29
11
  rateLimit?: ResolveRateLimitStop;
30
12
  sessionRefusal?: string;
31
13
  instructions?: string[];
@@ -38,11 +20,6 @@ export declare function applyResolveOptions(pr: number, repo: RepoInfo, opts: Re
38
20
  headSha?: string;
39
21
  evidence: Map<string, ReplyEvidence>;
40
22
  }): Promise<ResolveResult>;
41
- /** @deprecated Compatibility alias; use `autoResolveThreads`. */
42
- export declare function autoResolveOutdated(threadIds: string[]): Promise<{
43
- resolved: string[];
44
- errors: string[];
45
- }>;
46
23
  export declare function autoResolveThreads(threadIds: string[]): Promise<{
47
24
  resolved: string[];
48
25
  errors: string[];
@@ -88,10 +88,6 @@ export async function applyResolveOptions(pr, repo, opts, preflight) {
88
88
  ];
89
89
  return result;
90
90
  }
91
- /** @deprecated Compatibility alias; use `autoResolveThreads`. */
92
- export async function autoResolveOutdated(threadIds) {
93
- return autoResolveThreads(threadIds);
94
- }
95
91
  export async function autoResolveThreads(threadIds) {
96
92
  if (threadIds.length === 0)
97
93
  return { resolved: [], errors: [] };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Per-tick output budget for review items (see `iterate.reviewOutputMaxChars`).
2
+ * Per-tick output budget for review items (see `iterate.review-output-max-chars`).
3
3
  *
4
4
  * Fetching is complete; only the rendered volume is capped. When the bodies of every surfaced
5
5
  * review item fit the budget, nothing changes. Otherwise items are taken in a fixed priority
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Per-tick output budget for review items (see `iterate.reviewOutputMaxChars`).
2
+ * Per-tick output budget for review items (see `iterate.review-output-max-chars`).
3
3
  *
4
4
  * Fetching is complete; only the rendered volume is capped. When the bodies of every surfaced
5
5
  * review item fit the budget, nothing changes. Otherwise items are taken in a fixed priority
@@ -2,7 +2,9 @@ import { getPrHeadSha } from "../github/client.mjs";
2
2
  import { loadConfig } from "../config/load.mjs";
3
3
  import { sleep } from "../util/sleep.mjs";
4
4
  export async function waitForSha(pr, repo, expectedSha) {
5
- const { intervalMs: SHA_POLL_INTERVAL_MS, maxAttempts: SHA_POLL_MAX_ATTEMPTS } = loadConfig().resolve.shaPoll;
5
+ const apply = loadConfig().apply;
6
+ const SHA_POLL_INTERVAL_MS = apply["sha-poll-interval-seconds"] * 1000;
7
+ const SHA_POLL_MAX_ATTEMPTS = apply["sha-poll-max-attempts"];
6
8
  let lastSha;
7
9
  for (let attempt = 0; attempt < SHA_POLL_MAX_ATTEMPTS; attempt++) {
8
10
  try {
@@ -0,0 +1,2 @@
1
+ /** Built-in `bot-usernames`: known code-review bot logins treated as bots. */
2
+ export declare const DEFAULT_BOT_USERNAMES: string[];
@@ -0,0 +1,15 @@
1
+ /** Built-in `bot-usernames`: known code-review bot logins treated as bots. */
2
+ export const DEFAULT_BOT_USERNAMES = [
3
+ "chatgpt-connector",
4
+ "openai-codex",
5
+ "codex",
6
+ "claude",
7
+ "copilot-pull-request-reviewer",
8
+ "gemini-code-assist",
9
+ "coderabbitai",
10
+ "greptile-apps",
11
+ "qodo-merge-pro",
12
+ "deepsource-io",
13
+ "sonarqubecloud",
14
+ "what-the-diff",
15
+ ];
@@ -1,143 +1,9 @@
1
- import { type MergeMethod } from "./merge-method.mts";
2
- import { type GithubTransport } from "../github/transport-mode.mts";
3
- declare const MINIMIZE_COMMENTS_POLICIES: readonly ["all", "bots", "users", "none"];
4
- export type MinimizeCommentsPolicy = (typeof MINIMIZE_COMMENTS_POLICIES)[number];
5
- declare const RESOLVE_OTHER_HUMAN_THREADS: readonly ["none", "outdated", "always"];
6
- export type ResolveOtherHumanThreads = (typeof RESOLVE_OTHER_HUMAN_THREADS)[number];
7
- export declare const INSTRUCTION_STYLES: readonly ["playbook", "inline"];
1
+ import { type PrShepherdConfig } from "./resolve.mts";
2
+ export type { GraphqlQuotaWarningBand, InstructionStyle, MinimizeCommentsPolicy, PrShepherdConfig, ResolveOtherHumanThreads, } from "./resolve.mts";
8
3
  /**
9
- * How `fix_code` `## Instructions` render invariant procedure text. `inline` (default)
10
- * prints every step each tick; `playbook` points at the shipped "Fix-code loop" playbook.
4
+ * Load the config for the effective cwd: built-in defaults, then `$HOME`, then each ancestor
5
+ * down to cwd, closest file winning. Any invalid file throws a `ShepherdError` (exit 78).
11
6
  */
12
- export type InstructionStyle = (typeof INSTRUCTION_STYLES)[number];
13
- export declare function isInstructionStyle(value: unknown): value is InstructionStyle;
14
- export declare const POLL_MODES: readonly ["auto", "poll", "event"];
15
- /**
16
- * `poll` blocks and loops. `event` runs one tick and reports `nextCheck`. `auto` resolves to
17
- * `event` when `CLAUDE_CODE_REMOTE=true` and to `poll` everywhere else.
18
- */
19
- export type PollMode = (typeof POLL_MODES)[number];
20
- export declare function isPollMode(value: unknown): value is PollMode;
21
- export interface GraphqlQuotaWarningBand {
22
- remainingPercent: number;
23
- pollIntervalMinutes: number;
24
- }
25
- interface PollConfig {
26
- intervalSeconds: number;
27
- /** Multiplier for aggregate polls when `--interval` is omitted. Finite and at least 1. */
28
- stackIntervalFactor: number;
29
- timeoutSeconds: number;
30
- debounceSeconds: number;
31
- quietStatus: boolean;
32
- mode: PollMode;
33
- /**
34
- * Longest gap between GraphQL snapshots while conditional REST reads report an idle PR
35
- * unchanged. `0` disables the REST change detectors on the GraphQL transport.
36
- */
37
- reconcileSeconds: number;
38
- }
39
- export interface PrShepherdConfig {
40
- /** GitHub API settings; auto prefers GraphQL outside Claude Code cloud sessions. */
41
- github?: {
42
- transport?: GithubTransport;
43
- };
44
- /**
45
- * Optional user classification configuration; preserved for rule consumers. Shepherd reads
46
- * only `classify.standard`, a map of bundled rule name (or `all`) to boolean.
47
- */
48
- classify?: unknown;
49
- /** Bundled classification rules enabled by `classify.standard`, resolved and sorted by name. */
50
- standardRules: string[];
51
- /** Argv prefix for every pr-shepherd command Shepherd emits, e.g. `["pnpm", "exec", "pr-shepherd"]`. */
52
- cliCommand: string[];
53
- /** GitHub logins that should be treated as bots even when GitHub reports User/Unknown. */
54
- botUsernames: string[];
55
- /** Case-insensitive glob patterns for check/status context names Shepherd should ignore. */
56
- ignoreChecks: string[];
57
- iterate: {
58
- fixAttemptsPerThread: number;
59
- stallTimeoutMinutes: number;
60
- /**
61
- * When `true`, APPROVED-state reviews are also eligible for minimization — defaults to `false`
62
- * so approvals stay visible. `minimizeComments` still filters by GitHub author type.
63
- */
64
- minimizeApprovals: boolean;
65
- /**
66
- * Which GitHub author classes should be auto-minimized for minimizable PR comments and review
67
- * summaries. Items excluded by this policy are still surfaced once (and after edits) via seen
68
- * markers so they do not repeat forever.
69
- */
70
- minimizeComments: MinimizeCommentsPolicy;
71
- /**
72
- * One-liner hint appended to the `fix_code` push instruction when the branch is behind its
73
- * base — e.g. "rebase --force-with-lease" or "see .agents/skills/git-and-prs.md". Empty
74
- * (default) omits the hint entirely; the CLI never prescribes rebase/merge mechanics itself.
75
- */
76
- behindBaseHint: string;
77
- /**
78
- * Per-tick budget for review-item bodies in `fix_code` output, in characters. Over budget,
79
- * iterate shows a priority-ordered subset and holds the rest (unmarked) for later ticks.
80
- * `0` disables the cap.
81
- */
82
- reviewOutputMaxChars: number;
83
- /**
84
- * When to resolve other-human inline threads after Shepherd replies. Own and bot threads
85
- * always reply-and-resolve. `none` (default) keeps other humans reply-only; `outdated`
86
- * also resolves when GitHub reports `isOutdated`; `always` pairs reply-and-resolve.
87
- */
88
- resolveOtherHumanThreads: ResolveOtherHumanThreads;
89
- /**
90
- * `inline` (default) prints the commit/push step of `fix_code` instructions
91
- * every tick; `playbook` folds it into one `Playbook: "Fix-code loop"` pointer. The
92
- * default is inline because the token bench measured playbook as a net cost: it adds a read. The `--instructions` flag and MCP `instructions` input override per call.
93
- */
94
- instructions: InstructionStyle;
95
- };
96
- poll: PollConfig;
97
- watch: {
98
- readyDelayMinutes: number;
99
- graphqlQuotaWarnings: GraphqlQuotaWarningBand[];
100
- };
101
- resolve: {
102
- shaPoll: {
103
- intervalMs: number;
104
- maxAttempts: number;
105
- };
106
- };
107
- checks: {
108
- ciTriggerEvents: string[];
109
- /** Regex patterns matched against each raw log line; matching lines are dropped from log excerpts. Empty by default — no lines are stripped unless configured. */
110
- ignoreLogLines: string[];
111
- };
112
- mergeStatus: {
113
- blockingReviewerLogins: string[];
114
- };
115
- merge?: {
116
- /** Preferred merge method. Used only when the repository allows it. */
117
- method?: MergeMethod;
118
- /** Options added to ordinary `gh pr merge` commands. Queue commands never use these. */
119
- commandArgs: string[];
120
- };
121
- actions: {
122
- autoMinimizeSuppressed: boolean;
123
- autoMarkReady: boolean;
124
- /** Legacy-named patterns that keep matching Actions checks visible despite ignoreChecks. */
125
- neverCancelRuns: string[];
126
- /**
127
- * When `false` (default), `iterate --merge` defers non-CI actionable work
128
- * (review threads, comments, changes-requested reviews, review summaries)
129
- * while the PR sits in the merge queue, since a Shepherd-initiated push
130
- * would eject it. When `true`, restores pre-existing behavior: actionable
131
- * work is handled immediately regardless of queue membership.
132
- */
133
- workWhileQueued: boolean;
134
- /** @deprecated Accepted for compatibility, ignored by the loader. */
135
- autoResolveOutdated?: boolean;
136
- /** @deprecated Accepted for compatibility, ignored by the loader. */
137
- commitSuggestions?: boolean;
138
- };
139
- }
140
7
  export declare function loadConfig(): PrShepherdConfig;
141
8
  /** Reset the config cache — for use in tests that change directories. */
142
9
  export declare function _resetConfigCache(): void;
143
- export {};