pr-shepherd 0.2.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 +14 -0
- package/LICENSE +21 -0
- package/README.md +154 -0
- package/marketplace.json +8 -0
- package/package.json +62 -0
- package/skills/check/SKILL.md +70 -0
- package/skills/monitor/SKILL.md +108 -0
- package/skills/resolve/SKILL.md +85 -0
- package/src/cache/file-cache.mts +101 -0
- package/src/cache/file-cache.test.mts +91 -0
- package/src/cache/fix-attempts.mts +86 -0
- package/src/checks/classify.mts +80 -0
- package/src/checks/classify.test.mts +164 -0
- package/src/checks/triage.mock.test.mts +202 -0
- package/src/checks/triage.mts +88 -0
- package/src/cli.mts +423 -0
- package/src/commands/check.mts +188 -0
- package/src/commands/iterate.mock.test.mts +1111 -0
- package/src/commands/iterate.mts +371 -0
- package/src/commands/ready-delay.mts +117 -0
- package/src/commands/ready-delay.test.mts +116 -0
- package/src/commands/resolve.mts +92 -0
- package/src/commands/status.mts +173 -0
- package/src/comments/outdated.mts +18 -0
- package/src/comments/resolve.mts +179 -0
- package/src/config/load.mts +240 -0
- package/src/config.json +52 -0
- package/src/github/batch.mts +351 -0
- package/src/github/client.mts +207 -0
- package/src/github/client.test.mts +19 -0
- package/src/github/gql/batch-pr.gql +130 -0
- package/src/github/gql/dismiss-review.gql +7 -0
- package/src/github/gql/minimize-comment.gql +7 -0
- package/src/github/gql/multi-pr-status-paged.gql +31 -0
- package/src/github/gql/multi-pr-status.gql +32 -0
- package/src/github/gql/resolve-thread.gql +7 -0
- package/src/github/pagination.mts +86 -0
- package/src/github/pagination.test.mts +140 -0
- package/src/github/queries.mts +30 -0
- package/src/index.mts +17 -0
- package/src/merge-status/derive.mts +74 -0
- package/src/merge-status/derive.test.mts +130 -0
- package/src/reporters/json.mts +12 -0
- package/src/reporters/text.mts +140 -0
- package/src/types.mts +309 -0
- package/src/util/path-segment.mts +2 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable text reporter for shepherd check output.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ShepherdReport, TriagedCheck } from "../types.mts";
|
|
6
|
+
|
|
7
|
+
export function formatText(report: ShepherdReport): string {
|
|
8
|
+
const lines: string[] = [];
|
|
9
|
+
|
|
10
|
+
// Header
|
|
11
|
+
lines.push(`\nPR #${report.pr} — ${report.repo}`);
|
|
12
|
+
lines.push(`Status: ${report.status}`);
|
|
13
|
+
lines.push("");
|
|
14
|
+
|
|
15
|
+
// Merge status
|
|
16
|
+
const ms = report.mergeStatus;
|
|
17
|
+
lines.push(`Merge Status: ${ms.status}`);
|
|
18
|
+
lines.push(` mergeStateStatus: ${ms.mergeStateStatus}`);
|
|
19
|
+
lines.push(` mergeable: ${ms.mergeable}`);
|
|
20
|
+
lines.push(` reviewDecision: ${ms.reviewDecision ?? "(none)"}`);
|
|
21
|
+
lines.push(` isDraft: ${ms.isDraft}`);
|
|
22
|
+
lines.push(` copilotReviewInProgress:${ms.copilotReviewInProgress}`);
|
|
23
|
+
lines.push("");
|
|
24
|
+
|
|
25
|
+
// CI checks
|
|
26
|
+
const { passing, failing, inProgress, skipped } = report.checks;
|
|
27
|
+
const total = passing.length + failing.length + inProgress.length + skipped.length;
|
|
28
|
+
lines.push(`CI Checks: ${passing.length}/${total} passed`);
|
|
29
|
+
|
|
30
|
+
if (failing.length > 0) {
|
|
31
|
+
lines.push(`\nFailed Checks (${failing.length}):`);
|
|
32
|
+
for (const c of failing) {
|
|
33
|
+
const triaged = c as TriagedCheck;
|
|
34
|
+
const kind = triaged.failureKind ? ` [${triaged.failureKind}]` : "";
|
|
35
|
+
lines.push(` - ${c.name}${kind}: ${c.conclusion ?? c.status}`);
|
|
36
|
+
if (triaged.logExcerpt) {
|
|
37
|
+
lines.push(indent(triaged.logExcerpt.split("\n").slice(-10).join("\n"), " "));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (inProgress.length > 0) {
|
|
43
|
+
lines.push(`\nIn Progress (${inProgress.length}):`);
|
|
44
|
+
for (const c of inProgress) {
|
|
45
|
+
lines.push(` - ${c.name}: ${c.status}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (skipped.length > 0) {
|
|
50
|
+
lines.push(`\nSkipped (${skipped.length}): ${skipped.map((c) => c.name).join(", ")}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (report.checks.filtered.length > 0) {
|
|
54
|
+
lines.push(
|
|
55
|
+
`\nFiltered (non-PR-trigger) (${report.checks.filtered.length}): ${report.checks.filtered.map((c) => c.name).join(", ")}`,
|
|
56
|
+
);
|
|
57
|
+
if (report.checks.blockedByFilteredCheck) {
|
|
58
|
+
lines.push(
|
|
59
|
+
" Note: PR is BLOCKED and all filtered checks are non-PR-trigger — one of these filtered checks may be a required status check blocking merge.",
|
|
60
|
+
);
|
|
61
|
+
} else if (report.mergeStatus.status === "BLOCKED") {
|
|
62
|
+
lines.push(
|
|
63
|
+
" Note: one or more of these filtered checks may be a required status check blocking merge.",
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
lines.push("");
|
|
69
|
+
|
|
70
|
+
// Review threads
|
|
71
|
+
const { actionable: actionableThreads, autoResolved, autoResolveErrors } = report.threads;
|
|
72
|
+
if (autoResolved.length > 0) {
|
|
73
|
+
lines.push(`Auto-resolved outdated threads (${autoResolved.length}):`);
|
|
74
|
+
for (const t of autoResolved) {
|
|
75
|
+
lines.push(` - threadId=${t.id} ${t.path ?? ""}:${t.line ?? "?"} (@${t.author})`);
|
|
76
|
+
}
|
|
77
|
+
lines.push("");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (autoResolveErrors.length > 0) {
|
|
81
|
+
lines.push(`Auto-resolve errors (${autoResolveErrors.length}):`);
|
|
82
|
+
for (const e of autoResolveErrors) {
|
|
83
|
+
lines.push(` - ${e}`);
|
|
84
|
+
}
|
|
85
|
+
lines.push("");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (actionableThreads.length > 0) {
|
|
89
|
+
lines.push(`Actionable Review Threads (${actionableThreads.length}):`);
|
|
90
|
+
for (const t of actionableThreads) {
|
|
91
|
+
const label = t.path ? `${t.path}:${t.line ?? "?"}` : "(general)";
|
|
92
|
+
lines.push(` - threadId=${t.id} ${label} (@${t.author})`);
|
|
93
|
+
lines.push(` ${firstLine(t.body)}`);
|
|
94
|
+
}
|
|
95
|
+
lines.push("");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// PR comments
|
|
99
|
+
const { actionable: actionableComments } = report.comments;
|
|
100
|
+
if (actionableComments.length > 0) {
|
|
101
|
+
lines.push(`Actionable PR Comments (${actionableComments.length}):`);
|
|
102
|
+
for (const c of actionableComments) {
|
|
103
|
+
lines.push(` - commentId=${c.id} (@${c.author}): ${firstLine(c.body)}`);
|
|
104
|
+
}
|
|
105
|
+
lines.push("");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// CHANGES_REQUESTED reviews
|
|
109
|
+
if (report.changesRequestedReviews.length > 0) {
|
|
110
|
+
lines.push(`Pending CHANGES_REQUESTED reviews (${report.changesRequestedReviews.length}):`);
|
|
111
|
+
for (const r of report.changesRequestedReviews) {
|
|
112
|
+
lines.push(` - reviewId=${r.id} (@${r.author}): ${firstLine(r.body)}`);
|
|
113
|
+
}
|
|
114
|
+
lines.push("");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Summary
|
|
118
|
+
const totalActionable =
|
|
119
|
+
actionableThreads.length + actionableComments.length + report.changesRequestedReviews.length;
|
|
120
|
+
lines.push(
|
|
121
|
+
`Summary: ${totalActionable === 0 ? "0 actionable — all threads resolved/minimized" : `${totalActionable} actionable item(s) remaining`}`,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return lines.join("\n");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Helpers
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
function firstLine(text: string): string {
|
|
132
|
+
return (text.split("\n")[0] ?? "").trim().slice(0, 120);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function indent(text: string, prefix: string): string {
|
|
136
|
+
return text
|
|
137
|
+
.split("\n")
|
|
138
|
+
.map((l) => prefix + l)
|
|
139
|
+
.join("\n");
|
|
140
|
+
}
|
package/src/types.mts
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/** Shared type definitions for the shepherd CLI. */
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// GitHub primitives
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
export type CheckConclusion =
|
|
8
|
+
| "ACTION_REQUIRED"
|
|
9
|
+
| "CANCELLED"
|
|
10
|
+
| "FAILURE"
|
|
11
|
+
| "NEUTRAL"
|
|
12
|
+
| "SKIPPED"
|
|
13
|
+
| "STALE"
|
|
14
|
+
| "STARTUP_FAILURE"
|
|
15
|
+
| "SUCCESS"
|
|
16
|
+
| "TIMED_OUT"
|
|
17
|
+
| null;
|
|
18
|
+
|
|
19
|
+
export type CheckStatus =
|
|
20
|
+
| "COMPLETED"
|
|
21
|
+
| "IN_PROGRESS"
|
|
22
|
+
| "PENDING"
|
|
23
|
+
| "QUEUED"
|
|
24
|
+
| "REQUESTED"
|
|
25
|
+
| "WAITING";
|
|
26
|
+
|
|
27
|
+
export type MergeableState = "CONFLICTING" | "MERGEABLE" | "UNKNOWN";
|
|
28
|
+
|
|
29
|
+
export type MergeStateStatus =
|
|
30
|
+
| "BEHIND"
|
|
31
|
+
| "BLOCKED"
|
|
32
|
+
| "CLEAN"
|
|
33
|
+
| "DIRTY"
|
|
34
|
+
| "DRAFT"
|
|
35
|
+
| "HAS_HOOKS"
|
|
36
|
+
| "UNKNOWN"
|
|
37
|
+
| "UNSTABLE";
|
|
38
|
+
|
|
39
|
+
export type ReviewDecision = "APPROVED" | "CHANGES_REQUESTED" | "REVIEW_REQUIRED" | null;
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Check runs
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
export interface CheckRun {
|
|
46
|
+
name: string;
|
|
47
|
+
status: CheckStatus;
|
|
48
|
+
conclusion: CheckConclusion;
|
|
49
|
+
detailsUrl: string;
|
|
50
|
+
/** The workflow event that triggered this run (e.g. pull_request, push, schedule). */
|
|
51
|
+
event: string | null;
|
|
52
|
+
/** GitHub Actions run ID extracted from detailsUrl. */
|
|
53
|
+
runId: string | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type CheckCategory = "passed" | "failing" | "in_progress" | "skipped" | "filtered";
|
|
57
|
+
|
|
58
|
+
export interface ClassifiedCheck extends CheckRun {
|
|
59
|
+
category: CheckCategory;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type FailureKind = "timeout" | "infrastructure" | "actionable" | "flaky";
|
|
63
|
+
|
|
64
|
+
export interface TriagedCheck extends ClassifiedCheck {
|
|
65
|
+
failureKind?: FailureKind;
|
|
66
|
+
/** Log excerpt for actionable failures. */
|
|
67
|
+
logExcerpt?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Review threads and comments
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
export interface ReviewThread {
|
|
75
|
+
id: string;
|
|
76
|
+
isResolved: boolean;
|
|
77
|
+
isOutdated: boolean;
|
|
78
|
+
path: string | null;
|
|
79
|
+
line: number | null;
|
|
80
|
+
author: string;
|
|
81
|
+
body: string;
|
|
82
|
+
createdAtUnix: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface PrComment {
|
|
86
|
+
id: string;
|
|
87
|
+
isMinimized: boolean;
|
|
88
|
+
author: string;
|
|
89
|
+
body: string;
|
|
90
|
+
createdAtUnix: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface Review {
|
|
94
|
+
id: string;
|
|
95
|
+
author: string;
|
|
96
|
+
body: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Merge status
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
export type ShepherdMergeStatus =
|
|
104
|
+
| "CLEAN"
|
|
105
|
+
| "BEHIND"
|
|
106
|
+
| "CONFLICTS"
|
|
107
|
+
| "BLOCKED"
|
|
108
|
+
| "UNSTABLE"
|
|
109
|
+
| "DRAFT"
|
|
110
|
+
| "UNKNOWN";
|
|
111
|
+
|
|
112
|
+
export interface MergeStatusResult {
|
|
113
|
+
status: ShepherdMergeStatus;
|
|
114
|
+
state: "OPEN" | "CLOSED" | "MERGED";
|
|
115
|
+
isDraft: boolean;
|
|
116
|
+
mergeable: MergeableState;
|
|
117
|
+
reviewDecision: ReviewDecision;
|
|
118
|
+
copilotReviewInProgress: boolean;
|
|
119
|
+
mergeStateStatus: MergeStateStatus;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Batch query response (the combined GraphQL shape)
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
export interface BatchPrData {
|
|
127
|
+
number: number;
|
|
128
|
+
state: "OPEN" | "CLOSED" | "MERGED";
|
|
129
|
+
isDraft: boolean;
|
|
130
|
+
mergeable: MergeableState;
|
|
131
|
+
mergeStateStatus: MergeStateStatus;
|
|
132
|
+
reviewDecision: ReviewDecision;
|
|
133
|
+
headRefOid: string;
|
|
134
|
+
reviewRequests: Array<{ login: string }>;
|
|
135
|
+
latestReviews: Array<{ login: string; state: string }>;
|
|
136
|
+
reviewThreads: ReviewThread[];
|
|
137
|
+
comments: PrComment[];
|
|
138
|
+
changesRequestedReviews: Review[];
|
|
139
|
+
checks: CheckRun[];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Shepherd check report (output of the check command)
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
export type ShepherdStatus =
|
|
147
|
+
| "READY"
|
|
148
|
+
| "FAILING"
|
|
149
|
+
| "IN_PROGRESS"
|
|
150
|
+
| "UNRESOLVED_COMMENTS"
|
|
151
|
+
| "UNKNOWN";
|
|
152
|
+
|
|
153
|
+
export interface ShepherdReport {
|
|
154
|
+
pr: number;
|
|
155
|
+
repo: string;
|
|
156
|
+
status: ShepherdStatus;
|
|
157
|
+
mergeStatus: MergeStatusResult;
|
|
158
|
+
checks: {
|
|
159
|
+
passing: ClassifiedCheck[];
|
|
160
|
+
failing: TriagedCheck[];
|
|
161
|
+
inProgress: ClassifiedCheck[];
|
|
162
|
+
skipped: ClassifiedCheck[];
|
|
163
|
+
/** Checks filtered out because they were triggered by a non-PR event (push, schedule, etc.). */
|
|
164
|
+
filtered: ClassifiedCheck[];
|
|
165
|
+
filteredNames: string[];
|
|
166
|
+
blockedByFilteredCheck: boolean;
|
|
167
|
+
};
|
|
168
|
+
threads: {
|
|
169
|
+
actionable: ReviewThread[];
|
|
170
|
+
autoResolved: ReviewThread[];
|
|
171
|
+
autoResolveErrors: string[];
|
|
172
|
+
};
|
|
173
|
+
comments: {
|
|
174
|
+
actionable: PrComment[];
|
|
175
|
+
};
|
|
176
|
+
changesRequestedReviews: Review[];
|
|
177
|
+
lastPushTime?: number;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// Resolve command input
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
export interface ResolveOptions {
|
|
185
|
+
resolveThreadIds?: string[];
|
|
186
|
+
minimizeCommentIds?: string[];
|
|
187
|
+
dismissReviewIds?: string[];
|
|
188
|
+
dismissMessage?: string;
|
|
189
|
+
/** When set, shepherd verifies GitHub has received this commit before resolving. */
|
|
190
|
+
requireSha?: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Iterate command types
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
export type ShepherdAction =
|
|
198
|
+
| "cooldown"
|
|
199
|
+
| "wait"
|
|
200
|
+
| "fix_code"
|
|
201
|
+
| "rerun_ci"
|
|
202
|
+
| "rebase"
|
|
203
|
+
| "mark_ready"
|
|
204
|
+
| "cancel"
|
|
205
|
+
| "escalate";
|
|
206
|
+
|
|
207
|
+
export interface EscalateDetails {
|
|
208
|
+
triggers: string[];
|
|
209
|
+
unresolvedThreads: ReviewThread[];
|
|
210
|
+
ambiguousComments: PrComment[];
|
|
211
|
+
changesRequestedReviews: Review[];
|
|
212
|
+
/** Populated when fix-thrash triggered — threads that have been attempted too many times. */
|
|
213
|
+
attemptHistory?: Array<{ threadId: string; attempts: number }>;
|
|
214
|
+
/** One-line hint for the human on what to do. */
|
|
215
|
+
suggestion: string;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface IterateResultSummary {
|
|
219
|
+
passing: number;
|
|
220
|
+
skipped: number;
|
|
221
|
+
filtered: number;
|
|
222
|
+
inProgress: number;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface IterateResultBase {
|
|
226
|
+
pr: number;
|
|
227
|
+
repo: string;
|
|
228
|
+
status: ShepherdStatus;
|
|
229
|
+
/** `'UNKNOWN'` during the cooldown early-return (no sweep has been run yet). */
|
|
230
|
+
state: "OPEN" | "CLOSED" | "MERGED" | "UNKNOWN";
|
|
231
|
+
mergeStateStatus: MergeStateStatus;
|
|
232
|
+
copilotReviewInProgress: boolean;
|
|
233
|
+
isDraft: boolean;
|
|
234
|
+
shouldCancel: boolean;
|
|
235
|
+
remainingSeconds: number;
|
|
236
|
+
summary: IterateResultSummary;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface IterateResultCooldown extends IterateResultBase {
|
|
240
|
+
action: "cooldown";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface IterateResultWait extends IterateResultBase {
|
|
244
|
+
action: "wait";
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export interface IterateResultCancel extends IterateResultBase {
|
|
248
|
+
action: "cancel";
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export interface IterateResultFixCode extends IterateResultBase {
|
|
252
|
+
action: "fix_code";
|
|
253
|
+
fix: {
|
|
254
|
+
threads: ReviewThread[];
|
|
255
|
+
comments: PrComment[];
|
|
256
|
+
checks: TriagedCheck[];
|
|
257
|
+
changesRequestedReviews: Review[];
|
|
258
|
+
};
|
|
259
|
+
cancelled: string[];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface IterateResultRerunCi extends IterateResultBase {
|
|
263
|
+
action: "rerun_ci";
|
|
264
|
+
reran: string[];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface IterateResultRebase extends IterateResultBase {
|
|
268
|
+
action: "rebase";
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface IterateResultMarkReady extends IterateResultBase {
|
|
272
|
+
action: "mark_ready";
|
|
273
|
+
markedReady: boolean;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface IterateResultEscalate extends IterateResultBase {
|
|
277
|
+
action: "escalate";
|
|
278
|
+
escalate: EscalateDetails;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export type IterateResult =
|
|
282
|
+
| IterateResultCooldown
|
|
283
|
+
| IterateResultWait
|
|
284
|
+
| IterateResultCancel
|
|
285
|
+
| IterateResultFixCode
|
|
286
|
+
| IterateResultRerunCi
|
|
287
|
+
| IterateResultRebase
|
|
288
|
+
| IterateResultMarkReady
|
|
289
|
+
| IterateResultEscalate;
|
|
290
|
+
|
|
291
|
+
export interface IterateCommandOptions extends GlobalOptions {
|
|
292
|
+
cooldownSeconds?: number;
|
|
293
|
+
readyDelaySeconds?: number;
|
|
294
|
+
lastPushTime?: number;
|
|
295
|
+
noAutoRerun?: boolean;
|
|
296
|
+
noAutoMarkReady?: boolean;
|
|
297
|
+
noAutoCancelActionable?: boolean;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
// CLI options
|
|
302
|
+
// ---------------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
export interface GlobalOptions {
|
|
305
|
+
prNumber?: number;
|
|
306
|
+
format: "text" | "json";
|
|
307
|
+
noCache: boolean;
|
|
308
|
+
cacheTtlSeconds: number;
|
|
309
|
+
}
|