@osdlc/typed-gh 0.9.0 → 0.9.2

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
@@ -1,66 +1,67 @@
1
1
  /**
2
- * The verb table — every `gh` invocation this library knows, as data.
2
+ * The verb table: every `gh` call this library knows, as data.
3
3
  *
4
- * Same shape and same reasoning as `@osdlc/typed-git`'s: a {@link GhVerb}
5
- * pairs the argv to run with the function that reads the result, and nothing
6
- * here spawns anything. That is what lets a synchronous client and an
7
- * asynchronous fan-out drive the same definitions without either duplicating
8
- * the other's parsing.
4
+ * It has the same shape as `@osdlc/typed-git`'s. A {@link GhVerb} pairs the
5
+ * argv to run with the function that reads the result, and nothing here
6
+ * starts a process. So the sync client, the async client and callers with
7
+ * their own runner all use the same definitions and the same parsing.
9
8
  *
10
9
  * `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`.
10
+ * stderr. That is every mutation, and `prDiff`, which is a read. Other
11
+ * queries run unchecked, and `parse` turns a failure into `null`, which is
12
+ * what `soft` returns. The clients' methods that throw read them through
13
+ * `settle` (see `doors.ts`) instead. There a failure throws, except where the
14
+ * verb declares `absent` or is a `probe`.
16
15
  */
17
16
  import { type CommandResult } from '@osdlc/command-seam';
18
17
  import type { IssueRow, Label, PrSearchHit, PullRequest, Repository } from './types.ts';
19
18
  /** One `gh` invocation: what to run, and how to read what came back. */
20
19
  export interface GhVerb<T> {
21
20
  argv: string[];
22
- /** True for every mutation and for `prDiff` — throw on a non-zero exit instead of parsing. */
21
+ /** True for every mutation and for `prDiff`: throw on a non-zero exit instead of parsing. */
23
22
  checked: boolean;
24
23
  /**
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
24
+ * True when the call only reads and changes nothing on GitHub. Every query
25
+ * is read-only, and so is `prDiff`. No mutation is. A caller that
27
26
  * keeps an allowlist of safe calls can check this before running a verb.
28
27
  */
29
28
  readOnly: boolean;
30
29
  /** Written to the child's stdin, for a verb whose payload is too large or structured for argv. */
31
30
  input?: string | undefined;
32
31
  /**
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`.
32
+ * Variables to set on the child process, for a target gh has no flag for:
33
+ * `GH_HOST` on `gh search` and `gh repo list`.
35
34
  */
36
35
  env?: Record<string, string> | undefined;
37
36
  /**
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.
37
+ * True for a read whose failure is part of its answer. `installed`,
38
+ * `authStatus` and `api` return what `parse` makes of any result, in all
39
+ * three call styles. Other reads throw from the plain method when gh exits
40
+ * non-zero.
41
41
  */
42
42
  probe?: boolean | undefined;
43
43
  /**
44
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.
45
+ * thing (`prView`, `issueView`, `repoView`). The plain method then returns
46
+ * what `parse` makes of it, `null`, because a missing item is an answer.
47
+ * Other non-zero results fail the call.
48
48
  */
49
49
  absent?: ((result: CommandResult) => boolean) | undefined;
50
50
  parse(result: CommandResult): T;
51
51
  }
52
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.
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. With
55
+ * no `hostname`, it uses gh's default host.
56
56
  */
57
57
  export interface GhTarget {
58
58
  /** `owner/name`. */
59
59
  repo?: string | undefined;
60
60
  /**
61
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.
62
+ * `github.acme.com`, or a `<tenant>.ghe.com` host. Other forges are not
63
+ * supported, because gh supports only GitHub's API. `''` means the same as
64
+ * `undefined`, so a value read from config can be passed as it is.
64
65
  */
65
66
  hostname?: string | undefined;
66
67
  }
@@ -71,35 +72,35 @@ export interface GhTarget {
71
72
  */
72
73
  export declare function checkTarget(target: GhTarget | undefined): void;
73
74
  /**
74
- * The cheapest useful set: enough to identify a PR and nothing more.
75
+ * The smallest useful set: enough to identify a PR and nothing more.
75
76
  *
76
- * Reach for this whenever the question is "which PR is this branch?".
77
- * `mergeable` and `mergeStateStatus` are absent on purpose — GitHub computes
78
- * them per PR on demand, so asking for them across a fan-out of branches
79
- * turns a cheap listing into a rate-limit incident.
77
+ * Use it when the question is "which PR is this branch?". `mergeable` and
78
+ * `mergeStateStatus` are left out on purpose. GitHub computes them per PR
79
+ * when asked, so asking for them across many branches can hit the rate
80
+ * limit.
80
81
  */
81
82
  export declare const PR_REF_FIELDS: readonly ["number", "state", "headRefName", "url"];
82
83
  /**
83
- * The light field set for triage: everything needed to decide what to do with
84
- * a PR without paying for its body, comments, reviews, or check rollup.
84
+ * The smaller field set for triage: enough to decide what to do with a PR,
85
+ * without its body, comments, reviews, or check rollup.
85
86
  *
86
- * `mergeable` and `mergeStateStatus` are the expensive pair — GitHub computes
87
- * them lazily and answers `UNKNOWN` until it has, so a cold query over many
88
- * PRs commonly needs a retry. `prViewSettled` on the clients does it.
87
+ * `mergeable` and `mergeStateStatus` are the costly pair. GitHub computes
88
+ * them only when asked and answers `UNKNOWN` until it has. So a first query
89
+ * over many PRs often needs a retry. `prViewSettled` on the clients does it.
89
90
  */
90
91
  export declare const PR_LIST_FIELDS: readonly ["number", "state", "title", "url", "isDraft", "baseRefName", "headRefName", "headRefOid", "isCrossRepository", "mergeable", "mergeStateStatus", "reviewDecision", "author", "labels", "mergedAt", "createdAt", "updatedAt"];
91
- /** {@link PR_LIST_FIELDS} plus the heavy ones a single PR can afford. */
92
+ /** {@link PR_LIST_FIELDS} plus the costly fields, for a single PR. */
92
93
  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
  /**
94
95
  * 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
+ * The verb asks gh for one row more than `limit`. `truncated` is true when
96
97
  * that row came back, and `rows` holds at most `limit`.
97
98
  */
98
99
  export interface ListResult<T> {
99
100
  rows: T[];
100
101
  truncated: boolean;
101
102
  }
102
- /** What to narrow a listing to. Every filter is optional; none means "all open". */
103
+ /** What to narrow a listing to. Every filter is optional. None means "all open". */
103
104
  export interface PrListOptions {
104
105
  /**
105
106
  * `owner/name` to list from, instead of the repository at the client's cwd.
@@ -112,7 +113,7 @@ export interface PrListOptions {
112
113
  /**
113
114
  * Head branch filter, exact: `task/foo` does not match `task/foo-2`. Passed
114
115
  * 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
+ * forks can share a branch name. Ask for `headRepositoryOwner` to tell them
116
117
  * apart.
117
118
  */
118
119
  head?: string | undefined;
@@ -120,13 +121,13 @@ export interface PrListOptions {
120
121
  search?: string | undefined;
121
122
  author?: string | undefined;
122
123
  limit?: number | undefined;
123
- /** Field subset; defaults to {@link PR_LIST_FIELDS}. `number` is always requested. */
124
+ /** Field subset. Defaults to {@link PR_LIST_FIELDS}. `number` is always requested. */
124
125
  fields?: readonly string[] | undefined;
125
126
  }
126
- /** `gh pr list …` — open PRs by default. `opts.repo` overrides the target's repo. */
127
+ /** `gh pr list …`: open PRs by default. `opts.repo` overrides the target's repo. */
127
128
  export declare function prList(opts?: PrListOptions, target?: GhTarget): GhVerb<ListResult<PullRequest> | null>;
128
129
  /**
129
- * `gh pr view <number|branch|url> --json …` — one PR, with the heavy fields
130
+ * `gh pr view <number|branch|url> --json …`: one PR, with the full field set
130
131
  * by default.
131
132
  *
132
133
  * A branch is the PR whose head is that branch, as gh picks it. A URL names
@@ -137,13 +138,13 @@ export declare function prView(ref: number | string, fields?: readonly string[],
137
138
  /**
138
139
  * Open PRs whose head is exactly `branch`.
139
140
  *
140
- * The common shape behind "which PR is this branch?", bundling the cheap
141
- * field set with a small limit. More than one row comes back only when forks
141
+ * The usual way to ask "which PR is this branch?". It uses the smallest field
142
+ * set and a small limit. More than one row comes back only when forks
142
143
  * share the branch name.
143
144
  */
144
145
  export declare function openPrsForBranch(branch: string, limit?: number, target?: GhTarget): GhVerb<ListResult<PullRequest> | null>;
145
146
  /**
146
- * `gh pr view <n> --json body -q .body` — just the PR body. Null when gh
147
+ * `gh pr view <n> --json body -q .body`: just the PR body. Null when gh
147
148
  * failed. gh's `-q` output ends with a newline that is not part of the body,
148
149
  * so every trailing `\r` and `\n` is trimmed (including any that were part of
149
150
  * the body, such as the `\r\n` of a body saved with CRLF line endings).
@@ -153,15 +154,15 @@ export declare function prBody(number: number, target?: GhTarget): GhVerb<string
153
154
  export interface ApiResponse {
154
155
  /** True iff gh exited 0 and the status is below 400 (2xx, or a 304 on a conditional GET). */
155
156
  ok: boolean;
156
- /** HTTP status; set only when headers were requested (`-i`, `etag` or `includeHeaders`). Without them it is synthesized (200 on exit 0, 0 on failure), not observed. */
157
+ /** HTTP status, read only when headers were requested (`etag` or `includeHeaders`, which pass `-i`). Without them it is made up from the exit code (200 on exit 0, 0 on failure). */
157
158
  status: number;
158
159
  /** The response `ETag`, when headers were requested and one came back. */
159
160
  etag: string | null;
160
- /** The decoded JSON body, whatever gh's exit code (on failure, GitHub's error object); null when empty (e.g. a 304) or unparseable. */
161
+ /** The decoded JSON body, whatever gh's exit code (on failure, GitHub's error object). Null when empty (such as a 304) or not valid JSON. */
161
162
  body: unknown;
162
163
  /** `body.message` when the body is an object with a string `message` (GitHub's error text), else null. */
163
164
  message: string | null;
164
- /** True when a non-empty body arrived but was not valid JSON (`body` is then null); also true on a failed call with a non-JSON body. */
165
+ /** True when a non-empty body arrived but was not valid JSON (`body` is then null). This includes a failed call with a non-JSON body. */
165
166
  malformed: boolean;
166
167
  /** gh's stderr, trimmed. */
167
168
  stderr: string;
@@ -169,7 +170,7 @@ export interface ApiResponse {
169
170
  error?: string | undefined;
170
171
  }
171
172
  /**
172
- * Options for {@link api}. Both are optional; with neither, the call is a plain
173
+ * Options for {@link api}. All are optional. With none, the call is a plain
173
174
  * `gh api <endpoint>` and the response carries no status or ETag.
174
175
  */
175
176
  export interface ApiOptions {
@@ -180,21 +181,22 @@ export interface ApiOptions {
180
181
  /**
181
182
  * Fetch every page (`--paginate --slurp`). `body` is then the pages joined
182
183
  * into one array when every page is an array, else the list of pages.
183
- * Cannot be combined with `etag` or `includeHeaders`: with `-i` gh prints
184
- * a header block per page. `status` is synthesized, as without `-i`.
184
+ * Cannot be combined with `etag` or `includeHeaders`, because with `-i` gh
185
+ * prints a header block per page. `status` is made up from the exit code, as
186
+ * without `-i`.
185
187
  */
186
188
  paginate?: boolean | undefined;
187
189
  }
188
190
  /**
189
- * `gh api [-i] [-H If-None-Match: …] <endpoint>` — a GET against the REST API. `{owner}` and
191
+ * `gh api [-i] [-H If-None-Match: …] <endpoint>`: a GET against the REST API. `{owner}` and
190
192
  * `{repo}` placeholders in the endpoint are filled from the target's repo, or by gh from the
191
193
  * cwd's repo when the target names none.
192
- * Unchecked: failure is a value (`ok: false`), so a caller can tell a 304
194
+ * Unchecked. Failure is a value (`ok: false`), so a caller can tell a 304
193
195
  * from an outage.
194
196
  */
195
197
  export declare function api(endpoint: string, opts?: ApiOptions, target?: GhTarget): GhVerb<ApiResponse>;
196
198
  /**
197
- * A GraphQL variable: gh sends a string with `-f` and the rest with `-F`.
199
+ * A GraphQL variable. gh sends a string with `-f` and the rest with `-F`.
198
200
  *
199
201
  * @experimental
200
202
  */
@@ -208,35 +210,35 @@ export interface GraphqlOptions {
208
210
  /**
209
211
  * Follow every page (`--paginate --slurp`). The query must take
210
212
  * `$endCursor: String` and select `pageInfo { hasNextPage endCursor }` on
211
- * the one connection it pages through; gh follows only that connection.
213
+ * the one connection it pages through. gh follows only that connection.
212
214
  */
213
215
  paginate?: boolean | undefined;
214
216
  }
215
217
  /**
216
- * `gh api graphql -f query=… [--paginate --slurp]` — a GraphQL query.
218
+ * `gh api graphql -f query=… [--paginate --slurp]`: a GraphQL query.
217
219
  *
218
- * Returns each page's `data`, one entry per page (one without `paginate`),
219
- * or null when the call failed, the output did not parse, or any page
220
- * carries `errors` or lacks `data`: a partial answer is no answer. Read one
220
+ * Returns each page's `data`, one entry per page (one without `paginate`).
221
+ * Returns null when the call failed, the output did not parse, or any page
222
+ * carries `errors` or lacks `data`. A partial answer counts as a failure. Read one
221
223
  * connection across the pages with {@link nodesAt}.
222
224
  *
223
225
  * A string variable of exactly `{owner}` or `{repo}` is filled from the
224
226
  * target's repo, or by gh from the clone. A mutation document throws
225
- * `RangeError`: this is a read, and changes go through `raw`.
227
+ * `RangeError`. This is a read, and changes go through `raw`.
226
228
  *
227
229
  * @experimental
228
230
  */
229
231
  export declare function graphql(query: string, variables?: Record<string, GraphqlVariable>, opts?: GraphqlOptions, target?: GhTarget): GhVerb<unknown[] | null>;
230
232
  /**
231
- * The `nodes` of one connection, joined across {@link graphql} pages: walk
232
- * `path` into each page and take its `nodes` array. Null when `pages` is
233
+ * The `nodes` of one connection, joined across {@link graphql} pages. It
234
+ * follows `path` into each page and takes its `nodes` array. Null when `pages` is
233
235
  * null, or any page lacks the path or a `nodes` array, so a page that came
234
236
  * back short is never read as fewer rows.
235
237
  *
236
238
  * @experimental
237
239
  */
238
240
  export declare function nodesAt(pages: unknown[] | null, path: readonly string[]): unknown[] | null;
239
- /** `gh --version` — the install probe. True when `gh` runs. */
241
+ /** `gh --version`: checks that `gh` is installed. True when `gh` runs. */
240
242
  export declare function installed(): GhVerb<boolean>;
241
243
  /**
242
244
  * What `gh auth status` said: whether it passed, and its output (stderr, else the runner's
@@ -246,11 +248,11 @@ export interface AuthStatus {
246
248
  ok: boolean;
247
249
  detail: string;
248
250
  }
249
- /** `gh auth status [--hostname <host>]` — the credential probe, for one host when the target names it. */
251
+ /** `gh auth status [--hostname <host>]`: checks credentials, for one host when the target names it. */
250
252
  export declare function authStatus(target?: GhTarget): GhVerb<AuthStatus>;
251
253
  /**
252
- * `gh label list --json name,color,description` — every label on the repo,
253
- * up to `limit` (default 1000; `gh`'s own default is 30).
254
+ * `gh label list --json name,color,description`: every label on the repo,
255
+ * up to `limit` (default 1000. `gh`'s own default is 30).
254
256
  */
255
257
  export declare function labelList(opts?: {
256
258
  limit?: number | undefined;
@@ -262,9 +264,9 @@ export interface IssueListOptions {
262
264
  /** The most issues to return. Defaults to 200. */
263
265
  limit?: number | undefined;
264
266
  }
265
- /** `gh issue list --json …` — open issues by default, optionally by label. */
267
+ /** `gh issue list --json …`: open issues, optionally by label. */
266
268
  export declare function issueList(opts?: IssueListOptions, target?: GhTarget): GhVerb<ListResult<IssueRow> | null>;
267
- /** `gh issue view <n> --json …` — one issue, same field set as {@link issueList}. */
269
+ /** `gh issue view <n> --json …`: one issue, same field set as {@link issueList}. */
268
270
  export declare function issueView(number: number, target?: GhTarget): GhVerb<IssueRow | null>;
269
271
  /** The `gh repo list`/`view --json` fields a {@link Repository} reads. */
270
272
  export declare const REPO_FIELDS: readonly ["nameWithOwner", "description", "defaultBranchRef", "visibility", "isArchived", "url"];
@@ -272,21 +274,21 @@ export declare const REPO_FIELDS: readonly ["nameWithOwner", "description", "def
272
274
  export declare const SEARCH_PR_FIELDS: readonly ["number", "title", "state", "url", "isDraft", "repository", "author", "labels", "createdAt", "updatedAt", "closedAt"];
273
275
  /** What to narrow a repository listing to. Every filter is optional. */
274
276
  export interface RepoListOptions {
275
- /** True for archived repositories only, false to leave them out; both when absent. */
277
+ /** True for archived repositories only, false to leave them out. Both when absent. */
276
278
  archived?: boolean | undefined;
277
279
  visibility?: 'public' | 'private' | 'internal' | undefined;
278
280
  /** The most repositories to return. Defaults to 100. */
279
281
  limit?: number | undefined;
280
- /** Field subset; defaults to {@link REPO_FIELDS}. `nameWithOwner` is always asked for. */
282
+ /** Field subset. Defaults to {@link REPO_FIELDS}. `nameWithOwner` is always asked for. */
281
283
  fields?: readonly string[] | undefined;
282
284
  }
283
285
  /**
284
- * `gh repo list <owner> --json …` — an owner's repositories. The host comes
285
- * from the target (`GH_HOST`); the target's repo is not used.
286
+ * `gh repo list <owner> --json …`: an owner's repositories. The host comes
287
+ * from the target (`GH_HOST`). The target's repo is not used.
286
288
  */
287
289
  export declare function repoList(owner: string, opts?: RepoListOptions, target?: GhTarget): GhVerb<ListResult<Repository> | null>;
288
290
  /**
289
- * `gh repo view [<[host/]owner/name>] --json …` — one repository: `repo`,
291
+ * `gh repo view [<[host/]owner/name>] --json …`: one repository. That is `repo`,
290
292
  * else the target's repo, else the clone at the client's cwd.
291
293
  */
292
294
  export declare function repoView(repo?: string | undefined, fields?: readonly string[], target?: GhTarget): GhVerb<Repository | null>;
@@ -296,17 +298,17 @@ export interface SearchPrsOptions {
296
298
  owner?: string | undefined;
297
299
  /** Only this `owner/name` repository. */
298
300
  repo?: string | undefined;
299
- /** `merged` is `--merged`; `open` and `closed` are `--state`. */
301
+ /** `merged` is `--merged`. `open` and `closed` are `--state`. */
300
302
  state?: 'open' | 'closed' | 'merged' | undefined;
301
303
  /** The most hits to return. Defaults to 100. */
302
304
  limit?: number | undefined;
303
- /** Field subset; defaults to {@link SEARCH_PR_FIELDS}. `number` is always asked for. */
305
+ /** Field subset. Defaults to {@link SEARCH_PR_FIELDS}. `number` is always asked for. */
304
306
  fields?: readonly string[] | undefined;
305
307
  }
306
308
  /**
307
- * `gh search prs [flags] -- <query>` — pull requests across repositories,
309
+ * `gh search prs [flags] -- <query>`: pull requests across repositories,
308
310
  * with GitHub's search syntax in `query` (it may start with `-`, as in
309
- * `-label:bug`). The host comes from the target (`GH_HOST`); the target's
311
+ * `-label:bug`). The host comes from the target (`GH_HOST`). The target's
310
312
  * repo is not used, so pass `opts.repo` or `opts.owner` to narrow.
311
313
  */
312
314
  export declare function searchPrs(query: string, opts?: SearchPrsOptions, target?: GhTarget): GhVerb<ListResult<PrSearchHit> | null>;
@@ -327,25 +329,25 @@ export interface CreatePrOptions {
327
329
  * {@link prComment} does. A line after the URL, such as a tip, is skipped.
328
330
  */
329
331
  export declare function createPr(opts: CreatePrOptions, target?: GhTarget): GhVerb<string>;
330
- /** `gh pr edit <n>` — retitle or rewrite the body. */
332
+ /** `gh pr edit <n>`: change the title or the body. */
331
333
  export declare function editPr(number: number, opts: {
332
334
  title?: string | undefined;
333
335
  body?: string | undefined;
334
336
  }, target?: GhTarget): GhVerb<void>;
335
- /** `gh pr edit <n> --body` — rewrite just the body. */
337
+ /** `gh pr edit <n> --body`: rewrite just the body. */
336
338
  export declare function editPrBody(number: number, body: string, target?: GhTarget): GhVerb<void>;
337
- /** `gh pr update-branch <n> [--rebase]` — bring the head up to date with its base. */
339
+ /** `gh pr update-branch <n> [--rebase]`: bring the head up to date with its base. */
338
340
  export declare function prUpdateBranch(number: number, style?: 'merge' | 'rebase', target?: GhTarget): GhVerb<void>;
339
- /** `gh pr ready <n> [--undo]` — mark a draft PR ready for review, or (with `draft`) convert it back to a draft. */
341
+ /** `gh pr ready <n> [--undo]`: mark a draft PR ready for review, or (with `draft`) convert it back to a draft. */
340
342
  export declare function prSetDraft(number: number, draft: boolean, target?: GhTarget): GhVerb<void>;
341
343
  /**
342
- * `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<id> -f body=…` — rewrite one
344
+ * `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<id> -f body=…`: rewrite one
343
345
  * conversation comment.
344
346
  *
345
- * `commentId` is the comment's numeric REST id, as text: the `id` that
347
+ * `commentId` is the comment's numeric REST id, as text. That is the `id` that
346
348
  * `gh api repos/{owner}/{repo}/issues/<n>/comments` returns. It is not the
347
349
  * GraphQL node id (such as `IC_kw…`) that `gh pr view --json comments` gives
348
- * in `Comment.id`; the REST path answers 404 for a node id.
350
+ * in `Comment.id`. The REST path answers 404 for a node id.
349
351
  *
350
352
  * Throws `RangeError` when `commentId` is not all digits, so a node id fails
351
353
  * at once and no text can change which endpoint the PATCH reaches.
@@ -357,10 +359,10 @@ export declare function issueCommentEdit(commentId: string, body: string, target
357
359
  export type PrMergeMethod = 'squash' | 'merge' | 'rebase';
358
360
  /**
359
361
  * `gh pr merge <n> --<method> --match-head-commit <sha>`. The head sha is
360
- * required, not optional: GitHub refuses the merge when the PR head moved
361
- * since the caller judged it, so a push that lands between a gate and the
362
- * merge can never ride in unreviewed. The branch is left alone (no
363
- * `--delete-branch`); deleting it is the caller's job.
362
+ * required. GitHub refuses the merge when the PR head moved since the caller
363
+ * checked it. So a push that lands between the check and the merge cannot be
364
+ * merged without review. The branch is left alone (no `--delete-branch`).
365
+ * Deleting it is the caller's job.
364
366
  */
365
367
  export declare function prMerge(number: number, opts: {
366
368
  method: PrMergeMethod;
@@ -370,15 +372,14 @@ export declare function prMerge(number: number, opts: {
370
372
  export interface ReviewThread {
371
373
  isResolved: boolean;
372
374
  isOutdated: boolean;
373
- /** Login of the thread's newest comment; null when the account is gone. */
375
+ /** Login of the author of the thread's newest comment. Null when the account is gone. */
374
376
  lastCommentAuthor: string | null;
375
377
  }
376
378
  /**
377
379
  * A PR's review threads over GraphQL (`gh pr view --json` has no thread
378
- * field). Null — never `[]` — when the call failed, the payload was not the
379
- * expected shape, or more than 100 threads exist: a caller deciding whether a
380
- * PR is clear to merge must read "could not tell" differently from "no
381
- * threads".
380
+ * field). Null, never `[]`, when the call failed, the payload was not the
381
+ * expected shape, or more than 100 threads exist. A caller deciding whether a
382
+ * PR is clear to merge must tell "could not tell" from "no threads".
382
383
  */
383
384
  export declare function prReviewThreads(number: number, target?: GhTarget): GhVerb<ReviewThread[] | null>;
384
385
  /** A label to create. `color` is hex digits such as `d73a4a`. */
@@ -389,36 +390,33 @@ export interface CreateLabelOptions {
389
390
  }
390
391
  /**
391
392
  * `gh label create <name> --color <hex> --description <text> --force`.
392
- * `--force` makes it safe to repeat: when the label already exists, its color
393
+ * `--force` makes it safe to repeat. When the label already exists, its color
393
394
  * and description are set to these instead of failing.
394
395
  */
395
396
  export declare function createLabel(opts: CreateLabelOptions, target?: GhTarget): GhVerb<void>;
396
- /** `gh label edit <name>` — recolor or redescribe; omits a flag not given. */
397
+ /** `gh label edit <name>`: change the color or description. A flag not given is left out. */
397
398
  export declare function editLabel(name: string, opts: {
398
399
  color?: string | undefined;
399
400
  description?: string | undefined;
400
401
  }, target?: GhTarget): GhVerb<void>;
401
402
  /**
402
- * `gh issue edit <n> [--remove-label <current>] --add-label <new>` — swap
403
- * one label for another on an issue in ONE call, so the issue is never
404
- * briefly unlabeled or briefly holding both labels BETWEEN the remove and the
405
- * add — that atomicity is real and is this one call's own guarantee. It does
406
- * NOT cover the window before the call: `currentLabel` is whatever the caller
407
- * already read (perhaps minutes earlier, from a `gh issue list` snapshot),
408
- * never re-read here. If the issue's live label changed since then (a human,
409
- * or another process, relabeled it in between), `--remove-label
410
- * <currentLabel>` targets a label the issue no longer carries — `gh` no-ops
411
- * that removal silently rather than erroring — so the call still adds
412
- * `newLabel`, and the issue ends up holding BOTH the label it actually has
413
- * now and `newLabel`. A caller that cares about that race re-reads the live
414
- * label immediately before calling this. `currentLabel` is `null` when the
415
- * issue carries no prior label to remove — the `--remove-label` flag is then
416
- * omitted rather than passed empty.
403
+ * `gh issue edit <n> [--remove-label <current>] --add-label <new>`: swap one
404
+ * label for another on an issue in one call. The issue is never left with
405
+ * neither label or both labels between the remove and the add.
406
+ *
407
+ * That covers only the call itself. `currentLabel` is whatever the caller
408
+ * read earlier, perhaps from a `gh issue list` minutes before. It is not read
409
+ * again here. If someone relabeled the issue since then, `--remove-label
410
+ * <currentLabel>` names a label the issue no longer has. `gh` skips that
411
+ * removal with no error and still adds `newLabel`. The issue then has both
412
+ * its current label and `newLabel`. A caller that cares reads the label again
413
+ * just before calling this. Pass `null` for `currentLabel` when there is no
414
+ * label to remove. The `--remove-label` flag is then left out.
417
415
  */
418
416
  export declare function setIssueLabel(number: number, currentLabel: string | null, newLabel: string, target?: GhTarget): GhVerb<void>;
419
- /** `gh pr diff <n>` — the PR's unified diff, as text. Checked: an empty diff is a value, a failed call is not. */
417
+ /** `gh pr diff <n>`: the PR's unified diff, as text. Checked, so an empty diff is a value and a failed call throws. */
420
418
  export declare function prDiff(number: number, target?: GhTarget): GhVerb<string>;
421
- /** `gh pr comment <n> --body <body>` — post a conversation comment, returning the URL gh prints ('' if none). */
419
+ /** `gh pr comment <n> --body <body>`: post a conversation comment, returning the URL gh prints ('' if none). */
422
420
  export declare function prComment(number: number, body: string, target?: GhTarget): GhVerb<string>;
423
421
  /**
424
422
  * One inline comment of a review: a line on the right (new) side of the diff.
@@ -437,7 +435,7 @@ export interface ReviewComment {
437
435
  * @experimental
438
436
  */
439
437
  export interface CreateReviewOptions {
440
- /** The commit the review is anchored to; line numbers refer to the diff at this sha. */
438
+ /** The commit the review is on. Line numbers refer to the diff at this sha. */
441
439
  commitId: string;
442
440
  /** The review summary. GitHub rejects a review whose body and comments are both empty. */
443
441
  body: string;
@@ -445,10 +443,10 @@ export interface CreateReviewOptions {
445
443
  }
446
444
  /**
447
445
  * Create a PR review with inline comments, returning the review's URL (empty
448
- * when GitHub's reply carried none). The event is always `COMMENT`: this
449
- * library does not offer a way to approve or request changes. Goes through
446
+ * when GitHub's reply carried none). The event is always `COMMENT`. This
447
+ * library does not offer a way to approve or request changes. It goes through
450
448
  * `gh api` with the payload on stdin, because `gh pr review` cannot attach
451
- * line-anchored comments; `{owner}`/`{repo}` come from the target's repo, or
449
+ * comments to lines. `{owner}`/`{repo}` come from the target's repo, or
452
450
  * are filled in by `gh` from the client's working directory.
453
451
  *
454
452
  * @experimental
@@ -473,9 +471,9 @@ export declare function branchPrFields(fields: readonly string[]): string[];
473
471
  /**
474
472
  * True when GitHub has not finished computing this PR's mergeability.
475
473
  *
476
- * The answer is not stable on a cold query: GitHub kicks off the merge
477
- * computation when asked and answers `UNKNOWN` until it lands. A caller that
478
- * treats the first `UNKNOWN` as final will mis-triage a PR that is merely
479
- * slow, so re-ask a few times before believing it.
474
+ * The first answer may not be final. GitHub starts the merge computation when
475
+ * asked and answers `UNKNOWN` until it finishes. A caller that treats the
476
+ * first `UNKNOWN` as final misjudges a PR whose computation is slow. So ask a
477
+ * few times before trusting it.
480
478
  */
481
479
  export declare function needsMergeStateRetry(pr: PullRequest): boolean;