@osdlc/typed-gh 0.5.0 → 0.7.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/dist/verbs.d.ts CHANGED
@@ -7,21 +7,69 @@
7
7
  * asynchronous fan-out drive the same definitions without either duplicating
8
8
  * the other's parsing.
9
9
  *
10
- * `checked` marks a verb whose failure is thrown with stderr: every mutation,
11
- * and `prDiff`, which is a read. Other queries are unchecked and fold failure
12
- * into an absence value.
10
+ * `checked` marks a verb the runner throws for on a non-zero exit, with
11
+ * stderr: every mutation, and `prDiff`, which is a read. Other queries are run
12
+ * unchecked and `parse` folds a failure into `null`, which is the verb's
13
+ * *soft* reading. The clients' plain door reads them through `settle` (see
14
+ * `doors.ts`) instead: a failure throws, except where the verb declares
15
+ * `absent` or is a `probe`.
13
16
  */
14
17
  import { type CommandResult } from '@osdlc/command-seam';
15
- import type { IssueRow, Label, PullRequest } from './types.ts';
18
+ import type { IssueRow, Label, PrSearchHit, PullRequest, Repository } from './types.ts';
16
19
  /** One `gh` invocation: what to run, and how to read what came back. */
17
20
  export interface GhVerb<T> {
18
21
  argv: string[];
19
22
  /** True for every mutation and for `prDiff` — throw on a non-zero exit instead of parsing. */
20
23
  checked: boolean;
24
+ /**
25
+ * True when the call only reads: it changes nothing on GitHub. Every query
26
+ * is read-only, and so is `prDiff`; every mutation is not. A caller that
27
+ * keeps an allowlist of safe calls can check this before running a verb.
28
+ */
29
+ readOnly: boolean;
21
30
  /** Written to the child's stdin, for a verb whose payload is too large or structured for argv. */
22
31
  input?: string | undefined;
32
+ /**
33
+ * Variables to set on the child, for a target gh takes no flag for: `GH_HOST`
34
+ * on `gh search` and `gh repo list`.
35
+ */
36
+ env?: Record<string, string> | undefined;
37
+ /**
38
+ * True for a read whose failure is part of its answer: `installed`,
39
+ * `authStatus` and `api` return what `parse` makes of any result, in every
40
+ * door. Other reads fail the plain door when gh exits non-zero.
41
+ */
42
+ probe?: boolean | undefined;
43
+ /**
44
+ * For a read of one thing: whether a non-zero result means GitHub has no such
45
+ * thing (`prView`, `issueView`, `repoView`). The plain door then returns what
46
+ * `parse` makes of it, `null`, because absence is an answer. Other non-zero
47
+ * results fail the call.
48
+ */
49
+ absent?: ((result: CommandResult) => boolean) | undefined;
23
50
  parse(result: CommandResult): T;
24
51
  }
52
+ /**
53
+ * The repository and host a verb talks to. Both are optional: with no `repo`,
54
+ * gh uses the repository of the clone at the client's working directory, and
55
+ * with no `hostname`, gh's default host.
56
+ */
57
+ export interface GhTarget {
58
+ /** `owner/name`. */
59
+ repo?: string | undefined;
60
+ /**
61
+ * A GitHub host: `github.com`, a GitHub Enterprise Server host such as
62
+ * `github.acme.com`, or a `<tenant>.ghe.com` host. Other forges are out of
63
+ * reach: gh speaks only GitHub's API.
64
+ */
65
+ hostname?: string | undefined;
66
+ }
67
+ /**
68
+ * Throw `RangeError` unless `target.repo` is `owner/name` and
69
+ * `target.hostname` is a bare host. Run by every verb that uses a target, so
70
+ * no text can reach gh as a flag or change the endpoint a call hits.
71
+ */
72
+ export declare function checkTarget(target: GhTarget | undefined): void;
25
73
  /**
26
74
  * The cheapest useful set: enough to identify a PR and nothing more.
27
75
  *
@@ -42,6 +90,15 @@ export declare const PR_REF_FIELDS: readonly ["number", "state", "headRefName",
42
90
  export declare const PR_LIST_FIELDS: readonly ["number", "state", "title", "url", "isDraft", "baseRefName", "headRefName", "headRefOid", "isCrossRepository", "mergeable", "mergeStateStatus", "reviewDecision", "author", "labels", "mergedAt", "createdAt", "updatedAt"];
43
91
  /** {@link PR_LIST_FIELDS} plus the heavy ones a single PR can afford. */
44
92
  export declare const PR_VIEW_FIELDS: readonly ["number", "state", "title", "url", "isDraft", "baseRefName", "headRefName", "headRefOid", "isCrossRepository", "mergeable", "mergeStateStatus", "reviewDecision", "author", "labels", "mergedAt", "createdAt", "updatedAt", "body", "comments", "reviews", "statusCheckRollup"];
93
+ /**
94
+ * A list query's answer: the rows, and whether `limit` cut the list short.
95
+ * The verb asks gh for one row more than `limit`; `truncated` is true when
96
+ * that row came back, and `rows` holds at most `limit`.
97
+ */
98
+ export interface ListResult<T> {
99
+ rows: T[];
100
+ truncated: boolean;
101
+ }
45
102
  /** What to narrow a listing to. Every filter is optional; none means "all open". */
46
103
  export interface PrListOptions {
47
104
  /**
@@ -53,8 +110,10 @@ export interface PrListOptions {
53
110
  /** Exact base branch filter (gh-side). */
54
111
  base?: string | undefined;
55
112
  /**
56
- * Head branch filter. gh matches this as a prefix, so a caller needing an
57
- * exact match filters the rows itself — {@link pickPrForBranch} does.
113
+ * Head branch filter, exact: `task/foo` does not match `task/foo-2`. Passed
114
+ * as gh's `--head`, and the rows are filtered again on `headRefName`. Two
115
+ * forks can share a branch name; ask for `headRepositoryOwner` to tell them
116
+ * apart.
58
117
  */
59
118
  head?: string | undefined;
60
119
  /** Raw `--search` query, for anything the flags do not cover. */
@@ -64,25 +123,32 @@ export interface PrListOptions {
64
123
  /** Field subset; defaults to {@link PR_LIST_FIELDS}. */
65
124
  fields?: readonly string[] | undefined;
66
125
  }
67
- /** `gh pr list …` — open PRs by default. */
68
- export declare function prList(opts?: PrListOptions): GhVerb<PullRequest[] | null>;
69
- /** `gh pr view <n> --json …` — one PR, with the heavy fields by default. */
70
- export declare function prView(number: number, fields?: readonly string[]): GhVerb<PullRequest | null>;
126
+ /** `gh pr list …` — open PRs by default. `opts.repo` overrides the target's repo. */
127
+ export declare function prList(opts?: PrListOptions, target?: GhTarget): GhVerb<ListResult<PullRequest> | null>;
71
128
  /**
72
- * Open PRs whose head *starts with* `branch` — gh's own search semantics.
129
+ * `gh pr view <number|branch|url> --json …` — one PR, with the heavy fields
130
+ * by default.
131
+ *
132
+ * A branch is the PR whose head is that branch, as gh picks it. A URL names
133
+ * its own repository and host, so the target is not passed with one. A
134
+ * string that starts with `-` throws `RangeError`.
135
+ */
136
+ export declare function prView(ref: number | string, fields?: readonly string[], target?: GhTarget): GhVerb<PullRequest | null>;
137
+ /**
138
+ * Open PRs whose head is exactly `branch`.
73
139
  *
74
140
  * The common shape behind "which PR is this branch?", bundling the cheap
75
- * field set with a small limit. Pair it with {@link pickPrForBranch}, which
76
- * is what turns the prefix match into an exact one.
141
+ * field set with a small limit. More than one row comes back only when forks
142
+ * share the branch name.
77
143
  */
78
- export declare function openPrsForBranch(branch: string, limit?: number): GhVerb<PullRequest[] | null>;
144
+ export declare function openPrsForBranch(branch: string, limit?: number, target?: GhTarget): GhVerb<ListResult<PullRequest> | null>;
79
145
  /**
80
146
  * `gh pr view <n> --json body -q .body` — just the PR body. Null when gh
81
147
  * failed. gh's `-q` output ends with a newline that is not part of the body,
82
148
  * so every trailing `\r` and `\n` is trimmed (including any that were part of
83
149
  * the body, such as the `\r\n` of a body saved with CRLF line endings).
84
150
  */
85
- export declare function prBody(number: number): GhVerb<string | null>;
151
+ export declare function prBody(number: number, target?: GhTarget): GhVerb<string | null>;
86
152
  /** One `gh api` answer: HTTP status, entity tag, and the decoded JSON body. */
87
153
  export interface ApiResponse {
88
154
  /** True iff gh exited 0 and the status is below 400 (2xx, or a 304 on a conditional GET). */
@@ -109,14 +175,65 @@ export interface ApiOptions {
109
175
  etag?: string | null | undefined;
110
176
  /** Pass `-i` and read status/ETag off the header block (the last one, if several). */
111
177
  includeHeaders?: boolean | undefined;
178
+ /**
179
+ * Fetch every page (`--paginate --slurp`). `body` is then the pages joined
180
+ * into one array when every page is an array, else the list of pages.
181
+ * Cannot be combined with `etag` or `includeHeaders`: with `-i` gh prints
182
+ * a header block per page. `status` is synthesized, as without `-i`.
183
+ */
184
+ paginate?: boolean | undefined;
112
185
  }
113
186
  /**
114
187
  * `gh api [-i] [-H If-None-Match: …] <endpoint>` — a GET against the REST API. `{owner}` and
115
- * `{repo}` placeholders in the endpoint are filled by gh from the cwd's repo.
188
+ * `{repo}` placeholders in the endpoint are filled from the target's repo, or by gh from the
189
+ * cwd's repo when the target names none.
116
190
  * Unchecked: failure is a value (`ok: false`), so a caller can tell a 304
117
191
  * from an outage.
118
192
  */
119
- export declare function api(endpoint: string, opts?: ApiOptions): GhVerb<ApiResponse>;
193
+ export declare function api(endpoint: string, opts?: ApiOptions, target?: GhTarget): GhVerb<ApiResponse>;
194
+ /**
195
+ * A GraphQL variable: gh sends a string with `-f` and the rest with `-F`.
196
+ *
197
+ * @experimental
198
+ */
199
+ export type GraphqlVariable = string | number | boolean | null;
200
+ /**
201
+ * Options for {@link graphql}.
202
+ *
203
+ * @experimental
204
+ */
205
+ export interface GraphqlOptions {
206
+ /**
207
+ * Follow every page (`--paginate --slurp`). The query must take
208
+ * `$endCursor: String` and select `pageInfo { hasNextPage endCursor }` on
209
+ * the one connection it pages through; gh follows only that connection.
210
+ */
211
+ paginate?: boolean | undefined;
212
+ }
213
+ /**
214
+ * `gh api graphql -f query=… [--paginate --slurp]` — a GraphQL query.
215
+ *
216
+ * Returns each page's `data`, one entry per page (one without `paginate`),
217
+ * or null when the call failed, the output did not parse, or any page
218
+ * carries `errors` or lacks `data`: a partial answer is no answer. Read one
219
+ * connection across the pages with {@link nodesAt}.
220
+ *
221
+ * A string variable of exactly `{owner}` or `{repo}` is filled from the
222
+ * target's repo, or by gh from the clone. A mutation document throws
223
+ * `RangeError`: this is a read, and changes go through `raw`.
224
+ *
225
+ * @experimental
226
+ */
227
+ export declare function graphql(query: string, variables?: Record<string, GraphqlVariable>, opts?: GraphqlOptions, target?: GhTarget): GhVerb<unknown[] | null>;
228
+ /**
229
+ * The `nodes` of one connection, joined across {@link graphql} pages: walk
230
+ * `path` into each page and take its `nodes` array. Null when `pages` is
231
+ * null, or any page lacks the path or a `nodes` array, so a page that came
232
+ * back short is never read as fewer rows.
233
+ *
234
+ * @experimental
235
+ */
236
+ export declare function nodesAt(pages: unknown[] | null, path: readonly string[]): unknown[] | null;
120
237
  /** `gh --version` — the install probe. True when `gh` runs. */
121
238
  export declare function installed(): GhVerb<boolean>;
122
239
  /**
@@ -127,16 +244,15 @@ export interface AuthStatus {
127
244
  ok: boolean;
128
245
  detail: string;
129
246
  }
130
- /** `gh auth status` — the credential probe. */
131
- export declare function authStatus(): GhVerb<AuthStatus>;
247
+ /** `gh auth status [--hostname <host>]` — the credential probe, for one host when the target names it. */
248
+ export declare function authStatus(target?: GhTarget): GhVerb<AuthStatus>;
132
249
  /**
133
- * `gh label list --json name,color,description` — every label on the repo.
134
- * `limit` defaults to 1000. `gh`'s own default is 30, which would cut off a
135
- * repository with more labels than that without saying so.
250
+ * `gh label list --json name,color,description` — every label on the repo,
251
+ * up to `limit` (default 1000; `gh`'s own default is 30).
136
252
  */
137
253
  export declare function labelList(opts?: {
138
254
  limit?: number | undefined;
139
- }): GhVerb<Label[] | null>;
255
+ }, target?: GhTarget): GhVerb<ListResult<Label> | null>;
140
256
  /** What to narrow an issue listing to. Every filter is optional. */
141
257
  export interface IssueListOptions {
142
258
  /** Exact label filter, applied by `gh`. */
@@ -145,9 +261,53 @@ export interface IssueListOptions {
145
261
  limit?: number | undefined;
146
262
  }
147
263
  /** `gh issue list --json …` — open issues by default, optionally by label. */
148
- export declare function issueList(opts?: IssueListOptions): GhVerb<IssueRow[] | null>;
264
+ export declare function issueList(opts?: IssueListOptions, target?: GhTarget): GhVerb<ListResult<IssueRow> | null>;
149
265
  /** `gh issue view <n> --json …` — one issue, same field set as {@link issueList}. */
150
- export declare function issueView(number: number): GhVerb<IssueRow | null>;
266
+ export declare function issueView(number: number, target?: GhTarget): GhVerb<IssueRow | null>;
267
+ /** The `gh repo list`/`view --json` fields a {@link Repository} reads. */
268
+ export declare const REPO_FIELDS: readonly ["nameWithOwner", "description", "defaultBranchRef", "visibility", "isArchived", "url"];
269
+ /** The `gh search prs --json` fields a {@link PrSearchHit} reads. */
270
+ export declare const SEARCH_PR_FIELDS: readonly ["number", "title", "state", "url", "isDraft", "repository", "author", "labels", "createdAt", "updatedAt", "closedAt"];
271
+ /** What to narrow a repository listing to. Every filter is optional. */
272
+ export interface RepoListOptions {
273
+ /** True for archived repositories only, false to leave them out; both when absent. */
274
+ archived?: boolean | undefined;
275
+ visibility?: 'public' | 'private' | 'internal' | undefined;
276
+ /** The most repositories to return. Defaults to 100. */
277
+ limit?: number | undefined;
278
+ /** Field subset; defaults to {@link REPO_FIELDS}. `nameWithOwner` is always asked for. */
279
+ fields?: readonly string[] | undefined;
280
+ }
281
+ /**
282
+ * `gh repo list <owner> --json …` — an owner's repositories. The host comes
283
+ * from the target (`GH_HOST`); the target's repo is not used.
284
+ */
285
+ export declare function repoList(owner: string, opts?: RepoListOptions, target?: GhTarget): GhVerb<ListResult<Repository> | null>;
286
+ /**
287
+ * `gh repo view [<[host/]owner/name>] --json …` — one repository: `repo`,
288
+ * else the target's repo, else the clone at the client's cwd.
289
+ */
290
+ export declare function repoView(repo?: string | undefined, fields?: readonly string[], target?: GhTarget): GhVerb<Repository | null>;
291
+ /** What to narrow a pull request search to. Every filter is optional. */
292
+ export interface SearchPrsOptions {
293
+ /** Only repositories this user or organization owns. */
294
+ owner?: string | undefined;
295
+ /** Only this `owner/name` repository. */
296
+ repo?: string | undefined;
297
+ /** `merged` is `--merged`; `open` and `closed` are `--state`. */
298
+ state?: 'open' | 'closed' | 'merged' | undefined;
299
+ /** The most hits to return. Defaults to 100. */
300
+ limit?: number | undefined;
301
+ /** Field subset; defaults to {@link SEARCH_PR_FIELDS}. `number` is always asked for. */
302
+ fields?: readonly string[] | undefined;
303
+ }
304
+ /**
305
+ * `gh search prs [flags] -- <query>` — pull requests across repositories,
306
+ * with GitHub's search syntax in `query` (it may start with `-`, as in
307
+ * `-label:bug`). The host comes from the target (`GH_HOST`); the target's
308
+ * repo is not used, so pass `opts.repo` or `opts.owner` to narrow.
309
+ */
310
+ export declare function searchPrs(query: string, opts?: SearchPrsOptions, target?: GhTarget): GhVerb<ListResult<PrSearchHit> | null>;
151
311
  /**
152
312
  * Options for {@link createPr}. `head` is the branch to merge from and `base`
153
313
  * the branch to merge into. `draft` opens the PR as a draft.
@@ -164,18 +324,18 @@ export interface CreatePrOptions {
164
324
  * starts with `http://` or `https://`. `''` when it printed none, as
165
325
  * {@link prComment} does. A line after the URL, such as a tip, is skipped.
166
326
  */
167
- export declare function createPr(opts: CreatePrOptions): GhVerb<string>;
327
+ export declare function createPr(opts: CreatePrOptions, target?: GhTarget): GhVerb<string>;
168
328
  /** `gh pr edit <n>` — retitle or rewrite the body. */
169
329
  export declare function editPr(number: number, opts: {
170
330
  title?: string | undefined;
171
331
  body?: string | undefined;
172
- }): GhVerb<void>;
332
+ }, target?: GhTarget): GhVerb<void>;
173
333
  /** `gh pr edit <n> --body` — rewrite just the body. */
174
- export declare function editPrBody(number: number, body: string): GhVerb<void>;
334
+ export declare function editPrBody(number: number, body: string, target?: GhTarget): GhVerb<void>;
175
335
  /** `gh pr update-branch <n> [--rebase]` — bring the head up to date with its base. */
176
- export declare function prUpdateBranch(number: number, style?: 'merge' | 'rebase'): GhVerb<void>;
336
+ export declare function prUpdateBranch(number: number, style?: 'merge' | 'rebase', target?: GhTarget): GhVerb<void>;
177
337
  /** `gh pr ready <n> [--undo]` — mark a draft PR ready for review, or (with `draft`) convert it back to a draft. */
178
- export declare function prSetDraft(number: number, draft: boolean): GhVerb<void>;
338
+ export declare function prSetDraft(number: number, draft: boolean, target?: GhTarget): GhVerb<void>;
179
339
  /**
180
340
  * `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<id> -f body=…` — rewrite one
181
341
  * conversation comment.
@@ -190,7 +350,7 @@ export declare function prSetDraft(number: number, draft: boolean): GhVerb<void>
190
350
  *
191
351
  * @experimental
192
352
  */
193
- export declare function issueCommentEdit(commentId: string, body: string): GhVerb<void>;
353
+ export declare function issueCommentEdit(commentId: string, body: string, target?: GhTarget): GhVerb<void>;
194
354
  /** How {@link prMerge} lands the commits: `squash` into one, `merge` with a merge commit, or `rebase`. */
195
355
  export type PrMergeMethod = 'squash' | 'merge' | 'rebase';
196
356
  /**
@@ -203,7 +363,7 @@ export type PrMergeMethod = 'squash' | 'merge' | 'rebase';
203
363
  export declare function prMerge(number: number, opts: {
204
364
  method: PrMergeMethod;
205
365
  headSha: string;
206
- }): GhVerb<void>;
366
+ }, target?: GhTarget): GhVerb<void>;
207
367
  /** One review thread: whether it is resolved and who spoke last. */
208
368
  export interface ReviewThread {
209
369
  isResolved: boolean;
@@ -218,7 +378,7 @@ export interface ReviewThread {
218
378
  * PR is clear to merge must read "could not tell" differently from "no
219
379
  * threads".
220
380
  */
221
- export declare function prReviewThreads(number: number): GhVerb<ReviewThread[] | null>;
381
+ export declare function prReviewThreads(number: number, target?: GhTarget): GhVerb<ReviewThread[] | null>;
222
382
  /** A label to create. `color` is hex digits such as `d73a4a`. */
223
383
  export interface CreateLabelOptions {
224
384
  name: string;
@@ -230,12 +390,12 @@ export interface CreateLabelOptions {
230
390
  * `--force` makes it safe to repeat: when the label already exists, its color
231
391
  * and description are set to these instead of failing.
232
392
  */
233
- export declare function createLabel(opts: CreateLabelOptions): GhVerb<void>;
393
+ export declare function createLabel(opts: CreateLabelOptions, target?: GhTarget): GhVerb<void>;
234
394
  /** `gh label edit <name>` — recolor or redescribe; omits a flag not given. */
235
395
  export declare function editLabel(name: string, opts: {
236
396
  color?: string | undefined;
237
397
  description?: string | undefined;
238
- }): GhVerb<void>;
398
+ }, target?: GhTarget): GhVerb<void>;
239
399
  /**
240
400
  * `gh issue edit <n> [--remove-label <current>] --add-label <new>` — swap
241
401
  * one label for another on an issue in ONE call, so the issue is never
@@ -253,11 +413,11 @@ export declare function editLabel(name: string, opts: {
253
413
  * issue carries no prior label to remove — the `--remove-label` flag is then
254
414
  * omitted rather than passed empty.
255
415
  */
256
- export declare function setIssueLabel(number: number, currentLabel: string | null, newLabel: string): GhVerb<void>;
416
+ export declare function setIssueLabel(number: number, currentLabel: string | null, newLabel: string, target?: GhTarget): GhVerb<void>;
257
417
  /** `gh pr diff <n>` — the PR's unified diff, as text. Checked: an empty diff is a value, a failed call is not. */
258
- export declare function prDiff(number: number): GhVerb<string>;
418
+ export declare function prDiff(number: number, target?: GhTarget): GhVerb<string>;
259
419
  /** `gh pr comment <n> --body <body>` — post a conversation comment, returning the URL gh prints ('' if none). */
260
- export declare function prComment(number: number, body: string): GhVerb<string>;
420
+ export declare function prComment(number: number, body: string, target?: GhTarget): GhVerb<string>;
261
421
  /**
262
422
  * One inline comment of a review: a line on the right (new) side of the diff.
263
423
  *
@@ -286,19 +446,28 @@ export interface CreateReviewOptions {
286
446
  * when GitHub's reply carried none). The event is always `COMMENT`: this
287
447
  * library does not offer a way to approve or request changes. Goes through
288
448
  * `gh api` with the payload on stdin, because `gh pr review` cannot attach
289
- * line-anchored comments; `{owner}`/`{repo}` are filled in by `gh` from the
290
- * client's working directory.
449
+ * line-anchored comments; `{owner}`/`{repo}` come from the target's repo, or
450
+ * are filled in by `gh` from the client's working directory.
291
451
  *
292
452
  * @experimental
293
453
  */
294
- export declare function createReview(number: number, opts: CreateReviewOptions): GhVerb<string>;
454
+ export declare function createReview(number: number, opts: CreateReviewOptions, target?: GhTarget): GhVerb<string>;
295
455
  /**
296
- * The row whose `headRefName` exactly equals `branch`, or null.
456
+ * The first row whose `headRefName` exactly equals `branch`, or null.
297
457
  *
298
- * gh's `head:` search is a prefix match, so `task/foo` also returns
299
- * `task/foo-2`. Every caller that means one branch needs this filter.
458
+ * `prList({ head })` already filters exactly. This is for rows from anywhere
459
+ * else, such as a `search` query with gh's `head:` qualifier, which matches
460
+ * `task/foo-2` for `task/foo`.
300
461
  */
301
462
  export declare function pickPrForBranch(rows: PullRequest[] | null, branch: string): PullRequest | null;
463
+ /**
464
+ * The PR a branch names, from `prList({ head, state: 'all' })` rows: the open
465
+ * one, or else the first row (gh lists newest first). Null when there are no
466
+ * rows or the call failed.
467
+ */
468
+ export declare function branchPr(result: ListResult<PullRequest> | null): PullRequest | null;
469
+ /** The field set {@link branchPr} needs, ahead of `fields`. */
470
+ export declare function branchPrFields(fields: readonly string[]): string[];
302
471
  /**
303
472
  * True when GitHub has not finished computing this PR's mergeability.
304
473
  *
@@ -308,4 +477,3 @@ export declare function pickPrForBranch(rows: PullRequest[] | null, branch: stri
308
477
  * slow, so re-ask a few times before believing it.
309
478
  */
310
479
  export declare function needsMergeStateRetry(pr: PullRequest): boolean;
311
- //# sourceMappingURL=verbs.d.ts.map