pr-shepherd 0.60.0 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +7 -5
- package/bin/api.d.mts +35 -24
- package/bin/api.mjs +68 -48
- package/bin/checks/classify.d.mts +1 -1
- package/bin/checks/classify.mjs +4 -4
- package/bin/checks/log-excerpt.mjs +1 -1
- package/bin/classify/standard/codecov-report.d.mts +1 -1
- package/bin/classify/standard/codecov-report.mjs +7 -2
- package/bin/classify/standard/coderabbit-notices.d.mts +4 -3
- package/bin/classify/standard/coderabbit-notices.mjs +29 -47
- package/bin/classify/standard/codex-notices.mjs +34 -7
- package/bin/classify/standard/dependabot-notices.mjs +5 -1
- package/bin/classify/standard/gemini-notices.d.mts +1 -1
- package/bin/classify/standard/gemini-notices.mjs +16 -5
- package/bin/classify/standard/kilo-no-issues.d.mts +1 -1
- package/bin/classify/standard/kilo-no-issues.mjs +37 -10
- package/bin/classify/standard/sourcery-notices.mjs +1 -1
- package/bin/cli/arg-flags.mjs +0 -3
- package/bin/cli/clean-handler.d.mts +1 -1
- package/bin/cli/clean-handler.mjs +5 -15
- package/bin/cli/default-poll.d.mts +2 -0
- package/bin/cli/default-poll.mjs +9 -6
- package/bin/cli/formatters.d.mts +2 -3
- package/bin/cli/formatters.mjs +0 -26
- package/bin/cli/handlers.d.mts +3 -3
- package/bin/cli/handlers.mjs +45 -35
- package/bin/cli/help-command-pages.d.mts +13 -158
- package/bin/cli/help-command-pages.mjs +12 -157
- package/bin/cli/help-iterate-poll-pages.d.mts +4 -3
- package/bin/cli/help-iterate-poll-pages.mjs +76 -36
- package/bin/cli/help-log-file-page.d.mts +1 -1
- package/bin/cli/help-log-file-page.mjs +3 -5
- package/bin/cli/help-top-page.d.mts +1 -1
- package/bin/cli/help-top-page.mjs +19 -20
- package/bin/cli/help.d.mts +14 -159
- package/bin/cli/iterate-checks-formatter.mjs +1 -1
- package/bin/cli/iterate-flags.d.mts +2 -4
- package/bin/cli/iterate-flags.mjs +4 -20
- package/bin/cli/iterate-formatter.d.mts +1 -1
- package/bin/cli/iterate-formatter.mjs +6 -6
- package/bin/cli/iterate-instructions.d.mts +1 -1
- package/bin/cli/iterate-instructions.mjs +5 -6
- package/bin/cli/iterate-lean.mjs +32 -40
- package/bin/cli/iterate-verbose.mjs +1 -1
- package/bin/cli/journal-formatter.mjs +0 -3
- package/bin/cli/journal-handler.d.mts +1 -1
- package/bin/cli/journal-handler.mjs +2 -1
- package/bin/cli/mutate-formatter.mjs +0 -9
- package/bin/cli/next-check-format.d.mts +0 -4
- package/bin/cli/next-check-format.mjs +0 -4
- package/bin/cli/poll-handler.d.mts +3 -0
- package/bin/cli/poll-handler.mjs +88 -47
- package/bin/cli/poll-summary-emitter.mjs +2 -2
- package/bin/cli/poll-summary-formatter.mjs +2 -2
- package/bin/cli/poll-targets.d.mts +2 -2
- package/bin/cli/poll-targets.mjs +15 -35
- package/bin/cli/removed-flags.d.mts +3 -0
- package/bin/cli/removed-flags.mjs +24 -0
- package/bin/cli/runner.d.mts +1 -1
- package/bin/cli/runner.mjs +2 -2
- package/bin/cli/stack-overview.d.mts +0 -1
- package/bin/cli/stack-overview.mjs +1 -2
- package/bin/cli/{fix-formatter-extra.d.mts → triage-formatter-extra.d.mts} +1 -2
- package/bin/cli/{fix-formatter-extra.mjs → triage-formatter-extra.mjs} +0 -6
- package/bin/cli/triage-formatter.d.mts +4 -0
- package/bin/cli/{fix-formatter.mjs → triage-formatter.mjs} +31 -42
- package/bin/cli/unknown-flags.d.mts +6 -0
- package/bin/cli/unknown-flags.mjs +29 -0
- package/bin/cli-parser.mjs +41 -62
- package/bin/commands/check-annotations.d.mts +1 -1
- package/bin/commands/check-annotations.mjs +1 -1
- package/bin/commands/check-review-budget.d.mts +1 -1
- package/bin/commands/check-review-budget.mjs +1 -1
- package/bin/commands/check-wait-detectors.d.mts +1 -1
- package/bin/commands/check-wait-detectors.mjs +1 -1
- package/bin/commands/check.d.mts +1 -1
- package/bin/commands/check.mjs +7 -7
- package/bin/commands/commit-suggestion-instruction.d.mts +2 -2
- package/bin/commands/commit-suggestion-instruction.mjs +3 -3
- package/bin/commands/iterate/api-usage.mjs +8 -8
- package/bin/commands/iterate/check-instructions.d.mts +4 -4
- package/bin/commands/iterate/check-instructions.mjs +8 -8
- package/bin/commands/iterate/classify.mjs +2 -2
- package/bin/commands/iterate/escalate.mjs +6 -6
- package/bin/commands/iterate/index.mjs +20 -23
- package/bin/commands/iterate/merge-plan.mjs +3 -3
- package/bin/commands/iterate/merge-state.mjs +4 -7
- package/bin/commands/iterate/native-stack-rebase.mjs +1 -1
- package/bin/commands/iterate/render.d.mts +1 -1
- package/bin/commands/iterate/render.mjs +2 -2
- package/bin/commands/iterate/stall.mjs +11 -9
- package/bin/commands/iterate/{fix-loop-instruction.mjs → triage-loop-instruction.mjs} +7 -3
- package/bin/commands/iterate/{fix-code.d.mts → triage.d.mts} +2 -2
- package/bin/commands/iterate/{fix-code.mjs → triage.mjs} +14 -23
- package/bin/commands/iterate/unreported-required.mjs +2 -5
- package/bin/commands/journal/index.d.mts +1 -3
- package/bin/commands/journal/index.mjs +1 -1
- package/bin/commands/mark-files-as-viewed.d.mts +1 -3
- package/bin/commands/mark-files-as-viewed.mjs +1 -1
- package/bin/commands/next-check.d.mts +2 -2
- package/bin/commands/next-check.mjs +4 -2
- package/bin/commands/poll-progress.mjs +1 -1
- package/bin/commands/poll-summary-explicit-instructions.mjs +1 -1
- package/bin/commands/poll-summary-instructions.mjs +7 -7
- package/bin/commands/poll-summary.mjs +4 -4
- package/bin/commands/poll.d.mts +1 -1
- package/bin/commands/poll.mjs +4 -4
- package/bin/commands/resolve-mutate.d.mts +1 -1
- package/bin/commands/resolve-mutate.mjs +1 -1
- package/bin/commands/rest-stack-merge-readiness.mjs +1 -1
- package/bin/commands/single-tick.d.mts +5 -0
- package/bin/commands/single-tick.mjs +7 -0
- package/bin/commands/stack-drain.mjs +1 -1
- package/bin/commands/stack-merge-flag.mjs +1 -1
- package/bin/commands/stack-stall.d.mts +2 -2
- package/bin/commands/stack-stall.mjs +2 -2
- package/bin/commands/stack-work.d.mts +2 -2
- package/bin/commands/stack-work.mjs +2 -2
- package/bin/commands/suggestion-patch-item.d.mts +0 -1
- package/bin/commands/suggestion-patch-item.mjs +0 -12
- package/bin/commands/suggestion-patches.d.mts +2 -2
- package/bin/commands/suggestion-patches.mjs +1 -1
- package/bin/commands/tick-instructions.d.mts +9 -0
- package/bin/commands/tick-instructions.mjs +23 -0
- package/bin/commands/tick.d.mts +15 -0
- package/bin/commands/{event-mode.mjs → tick.mjs} +39 -55
- package/bin/comments/minimize-policy.mjs +1 -3
- package/bin/comments/resolve.d.mts +0 -23
- package/bin/comments/resolve.mjs +0 -4
- package/bin/comments/review-output-budget.d.mts +1 -1
- package/bin/comments/review-output-budget.mjs +1 -1
- package/bin/comments/sha-poll.mjs +3 -1
- package/bin/config/default-bot-usernames.d.mts +2 -0
- package/bin/config/default-bot-usernames.mjs +15 -0
- package/bin/config/load.d.mts +4 -138
- package/bin/config/load.mjs +88 -443
- package/bin/config/merge-command-args.mjs +2 -2
- package/bin/config/merge-method.d.mts +1 -2
- package/bin/config/merge-method.mjs +1 -8
- package/bin/config/renames.d.mts +8 -0
- package/bin/config/renames.mjs +87 -0
- package/bin/config/resolve.d.mts +31 -0
- package/bin/config/resolve.mjs +89 -0
- package/bin/config/schema.d.mts +161 -0
- package/bin/config/schema.mjs +168 -0
- package/bin/exit-codes.d.mts +1 -1
- package/bin/exit-codes.mjs +3 -3
- package/bin/github/poll-summary-check-blockers.mjs +1 -1
- package/bin/github/poll-summary-command.mjs +8 -6
- package/bin/github/poll-summary-projector.mjs +2 -2
- package/bin/github/poll-summary-review.mjs +1 -1
- package/bin/github/poll-summary-route.mjs +9 -9
- package/bin/github/poll-summary-unreported.mjs +1 -1
- package/bin/github/poll-summary.mjs +1 -1
- package/bin/github/queries.d.mts +1 -1
- package/bin/github/queries.mjs +1 -1
- package/bin/mcp/server.mjs +48 -54
- package/bin/merge-status/derive.mjs +1 -1
- package/bin/state/durable-state.d.mts +1 -3
- package/bin/state/durable-state.mjs +2 -8
- package/bin/state/fix-attempts.d.mts +2 -2
- package/bin/state/fix-attempts.mjs +1 -1
- package/bin/state/merge-request.mjs +1 -1
- package/bin/state/pr-fingerprint.mjs +4 -11
- package/bin/state/seen-comments.d.mts +4 -5
- package/bin/state/seen-comments.mjs +8 -14
- package/bin/state/stack-stall.d.mts +1 -1
- package/bin/state/stack-stall.mjs +1 -1
- package/bin/state/stall-state-store.d.mts +1 -1
- package/bin/state/stall-state-store.mjs +1 -1
- package/bin/types/escalate.d.mts +2 -2
- package/bin/types/iterate.d.mts +12 -26
- package/bin/types/merge-queue.d.mts +2 -2
- package/bin/types/next-check.d.mts +1 -1
- package/bin/types/poll-summary.d.mts +3 -6
- package/bin/types/report.d.mts +2 -2
- package/bin/types/suggestion-patch.d.mts +1 -8
- package/package.json +2 -1
- package/plugins/pr-shepherd/.claude-plugin/plugin.json +1 -1
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
- package/plugins/pr-shepherd/.codex.mcp.json +1 -1
- package/plugins/pr-shepherd/.mcp.json +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -6
- package/plugins/pr-shepherd/skills/pr-shepherd/references/ci-failure-triage.md +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/references/{cloud-event-loop.md → event-loop.md} +5 -5
- package/plugins/pr-shepherd/skills/pr-shepherd/references/mcp-fallback.md +3 -3
- package/plugins/pr-shepherd/skills/pr-shepherd/references/merge-queue-ejection.md +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/references/suggestion-patches.md +1 -1
- package/plugins/pr-shepherd/skills/pr-shepherd/references/{fix-code-loop.md → triage-loop.md} +3 -3
- package/plugins/pr-shepherd/skills/reduce-pr-noise/SKILL.md +1 -1
- package/plugins/pr-shepherd/skills/reduce-pr-noise/references/classifiers.md +2 -2
- package/plugins/pr-shepherd/skills/reduce-pr-noise/references/settings.md +11 -11
- package/pr-shepherd.schema.json +361 -0
- package/bin/cli/event-state-scope.d.mts +0 -19
- package/bin/cli/event-state-scope.mjs +0 -60
- package/bin/cli/fix-formatter.d.mts +0 -4
- package/bin/commands/commit-suggestion.d.mts +0 -8
- package/bin/commands/commit-suggestion.mjs +0 -26
- package/bin/commands/event-instructions.d.mts +0 -11
- package/bin/commands/event-instructions.mjs +0 -27
- package/bin/commands/event-mode.d.mts +0 -14
- package/bin/commands/poll-mode.d.mts +0 -8
- package/bin/commands/poll-mode.mjs +0 -14
- package/bin/config.json +0 -68
- package/bin/types/protected-run.d.mts +0 -6
- package/bin/types/protected-run.mjs +0 -1
- /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 {
|
|
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 {
|
|
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
|
|
18
|
-
*
|
|
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
|
|
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
|
-
...
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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 (
|
|
60
|
+
if (result.action !== "wait")
|
|
79
61
|
return undefined;
|
|
80
|
-
const timeout = stallTimeoutSeconds ?? loadConfig().iterate
|
|
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
|
|
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
|
|
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
|
-
...
|
|
77
|
+
...result,
|
|
97
78
|
nextCheck,
|
|
98
79
|
instructions: [
|
|
99
80
|
...instructions,
|
|
100
|
-
`${instructions.length + 1}. ${
|
|
81
|
+
`${instructions.length + 1}. ${tickAggregateStep(nextCheck, waiting)}`,
|
|
101
82
|
],
|
|
102
83
|
};
|
|
103
84
|
}
|
|
104
|
-
/** The appended
|
|
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
|
|
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[];
|
package/bin/comments/resolve.mjs
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
|
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,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
|
+
];
|
package/bin/config/load.d.mts
CHANGED
|
@@ -1,143 +1,9 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
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
|
-
*
|
|
10
|
-
*
|
|
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 {};
|