pr-shepherd 0.34.0 → 0.36.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 +3 -2
- package/.grok-plugin/marketplace.json +17 -0
- package/README.md +80 -43
- package/bin/api.d.mts +80 -0
- package/bin/api.mjs +236 -0
- package/bin/checks/classify.d.mts +41 -0
- package/bin/checks/startup-failures.d.mts +2 -0
- package/bin/checks/superseded.d.mts +21 -0
- package/bin/checks/triage.d.mts +4 -0
- package/bin/checks/triage.mjs +11 -3
- package/bin/classify/apply.d.mts +18 -0
- package/bin/classify/apply.mjs +4 -0
- package/bin/classify/loader.d.mts +10 -0
- package/bin/classify/types.d.mts +35 -0
- package/bin/cli/args.d.mts +18 -0
- package/bin/cli/args.mjs +1 -0
- package/bin/cli/clean-formatter.d.mts +2 -0
- package/bin/cli/default-poll.d.mts +2 -0
- package/bin/cli/default-poll.mjs +1 -0
- package/bin/cli/duration-flag.d.mts +2 -0
- package/bin/cli/duration.d.mts +13 -0
- package/bin/cli/fence.d.mts +1 -0
- package/bin/cli/fix-formatter-extra.d.mts +3 -0
- package/bin/cli/fix-formatter.d.mts +2 -0
- package/bin/cli/fix-formatter.mjs +6 -6
- package/bin/cli/formatters.d.mts +7 -0
- package/bin/cli/handlers.d.mts +4 -0
- package/bin/cli/handlers.mjs +11 -10
- package/bin/cli/help-command-pages.d.mts +231 -0
- package/bin/cli/help-command-pages.mjs +106 -1
- package/bin/cli/help-iterate-poll-pages.d.mts +4 -0
- package/bin/cli/help-iterate-poll-pages.mjs +14 -7
- package/bin/cli/help-log-file-page.d.mts +1 -0
- package/bin/cli/help-top-page.d.mts +1 -0
- package/bin/cli/help-top-page.mjs +16 -16
- package/bin/cli/help.d.mts +236 -0
- package/bin/cli/help.mjs +17 -0
- package/bin/cli/iterate-emitter.d.mts +8 -0
- package/bin/cli/iterate-flags.d.mts +11 -0
- package/bin/cli/iterate-formatter.d.mts +19 -0
- package/bin/cli/iterate-formatter.mjs +11 -2
- package/bin/cli/iterate-instructions.d.mts +6 -0
- package/bin/cli/iterate-lean.d.mts +12 -0
- package/bin/cli/iterate-lean.mjs +1 -0
- package/bin/cli/journal-formatter.d.mts +2 -0
- package/bin/cli/journal-formatter.mjs +15 -0
- package/bin/cli/journal-handler.d.mts +1 -0
- package/bin/cli/journal-handler.mjs +7 -20
- package/bin/cli/list-formatters.d.mts +76 -0
- package/bin/cli/list-formatters.mjs +9 -9
- package/bin/cli/mark-files-as-viewed-flags.d.mts +11 -0
- package/bin/cli/mark-files-as-viewed-formatter.d.mts +2 -0
- package/bin/cli/mutate-formatter.d.mts +2 -0
- package/bin/cli/poll-handler.d.mts +1 -0
- package/bin/cli/poll-handler.mjs +9 -2
- package/bin/cli/resolve-validators.d.mts +3 -0
- package/bin/cli/resolve-validators.mjs +3 -3
- package/bin/cli/runner.d.mts +7 -0
- package/bin/cli/suggestion-renderer.d.mts +3 -0
- package/bin/cli/validate-default-args.d.mts +6 -0
- package/bin/cli-parser.d.mts +2 -0
- package/bin/cli-parser.mjs +72 -16
- package/bin/commands/check-annotations.d.mts +5 -0
- package/bin/commands/check-status.d.mts +3 -0
- package/bin/commands/check-terminal-report.d.mts +5 -0
- package/bin/commands/check.d.mts +7 -0
- package/bin/commands/check.mjs +28 -23
- package/bin/commands/clean.d.mts +21 -0
- package/bin/commands/commit-suggestion-instruction.d.mts +8 -0
- package/bin/commands/commit-suggestion-instruction.mjs +3 -3
- package/bin/commands/commit-suggestion.d.mts +8 -0
- package/bin/commands/commit-suggestion.mjs +20 -13
- package/bin/commands/iterate/check-instructions.d.mts +16 -0
- package/bin/commands/iterate/check-instructions.mjs +3 -3
- package/bin/commands/iterate/classify.d.mts +18 -0
- package/bin/commands/iterate/classify.mjs +4 -4
- package/bin/commands/iterate/escalate.d.mts +31 -0
- package/bin/commands/iterate/escalate.mjs +7 -4
- package/bin/commands/iterate/fix-code.d.mts +25 -0
- package/bin/commands/iterate/fix-code.mjs +1 -1
- package/bin/commands/iterate/helpers.d.mts +14 -0
- package/bin/commands/iterate/helpers.mjs +19 -7
- package/bin/commands/iterate/index.d.mts +2 -0
- package/bin/commands/iterate/index.mjs +8 -12
- package/bin/commands/iterate/render.d.mts +5 -0
- package/bin/commands/iterate/render.mjs +8 -6
- package/bin/commands/iterate/reruns.d.mts +20 -0
- package/bin/commands/iterate/stall.d.mts +6 -0
- package/bin/commands/journal/index.d.mts +14 -0
- package/bin/commands/journal/index.mjs +1 -0
- package/bin/commands/journal/transform.d.mts +22 -0
- package/bin/commands/log-file.d.mts +5 -0
- package/bin/commands/mark-files-as-viewed.d.mts +26 -0
- package/bin/commands/mark-files-as-viewed.mjs +1 -0
- package/bin/commands/poll.d.mts +12 -0
- package/bin/commands/poll.mjs +52 -17
- package/bin/commands/ready-delay.d.mts +29 -0
- package/bin/commands/ready-delay.mjs +3 -13
- package/bin/commands/ready-mergeability.d.mts +15 -0
- package/bin/commands/resolve-mutate.d.mts +4 -0
- package/bin/commands/resolve-mutate.mjs +1 -0
- package/bin/commands/resolve.d.mts +4 -0
- package/bin/commands/shepherd-journal.d.mts +7 -0
- package/bin/commands/shepherd-journal.mjs +2 -2
- package/bin/comments/authors.d.mts +14 -0
- package/bin/comments/marker.d.mts +2 -0
- package/bin/comments/minimize-policy.d.mts +4 -0
- package/bin/comments/pending-ops.d.mts +15 -0
- package/bin/comments/rate-limit.d.mts +18 -0
- package/bin/comments/resolve.d.mts +34 -0
- package/bin/comments/resolve.mjs +1 -0
- package/bin/comments/review-thread-markers.d.mts +8 -0
- package/bin/comments/review-visibility.d.mts +28 -0
- package/bin/comments/sha-poll.d.mts +2 -0
- package/bin/comments/thread-visibility.d.mts +11 -0
- package/bin/comments/visible-comments.d.mts +11 -0
- package/bin/config/load.d.mts +60 -0
- package/bin/config/load.mjs +129 -16
- package/bin/config.json +0 -2
- package/bin/execution-context.d.mts +9 -0
- package/bin/execution-context.mjs +19 -0
- package/bin/exit-codes.d.mts +51 -0
- package/bin/github/activity.d.mts +3 -0
- package/bin/github/activity.mjs +7 -0
- package/bin/github/batch-page-helpers.d.mts +45 -0
- package/bin/github/batch-page-helpers.mjs +63 -0
- package/bin/github/batch-page.d.mts +14 -0
- package/bin/github/batch-page.mjs +62 -0
- package/bin/github/batch-parse-suites.d.mts +4 -0
- package/bin/github/batch-parse-suites.mjs +25 -0
- package/bin/github/batch-parser-helpers.d.mts +22 -0
- package/bin/github/batch-parsers-rules.d.mts +6 -0
- package/bin/github/batch-parsers-rules.mjs +122 -0
- package/bin/github/batch-parsers.d.mts +3 -0
- package/bin/github/batch-parsers.mjs +12 -0
- package/bin/github/batch-raw-rules.d.mts +59 -0
- package/bin/github/batch-raw-rules.mjs +1 -0
- package/bin/github/batch-raw-types.d.mts +216 -0
- package/bin/github/batch-response.d.mts +4 -0
- package/bin/github/batch.d.mts +24 -0
- package/bin/github/batch.mjs +14 -120
- package/bin/github/branch-protection.d.mts +3 -0
- package/bin/github/check-annotations.d.mts +2 -0
- package/bin/github/client.d.mts +46 -0
- package/bin/github/client.mjs +7 -2
- package/bin/github/errors.d.mts +25 -0
- package/bin/github/gql/batch-pr-page.gql +189 -0
- package/bin/github/gql/batch-pr.gql +79 -21
- package/bin/github/gql/commit-suggestion-thread.gql +40 -0
- package/bin/github/gql/review-thread-comments.gql +1 -0
- package/bin/github/graphql-http.d.mts +19 -0
- package/bin/github/graphql-response.d.mts +7 -0
- package/bin/github/http-auth.d.mts +4 -0
- package/bin/github/http-request.d.mts +7 -0
- package/bin/github/http-utils.d.mts +11 -0
- package/bin/github/http.d.mts +6 -0
- package/bin/github/http.mjs +2 -1
- package/bin/github/pagination.d.mts +46 -0
- package/bin/github/pagination.mjs +3 -2
- package/bin/github/queries.d.mts +28 -0
- package/bin/github/queries.mjs +4 -0
- package/bin/github/rest-http.d.mts +7 -0
- package/bin/github/rest-http.mjs +25 -86
- package/bin/github/rest-text.d.mts +1 -0
- package/bin/github/rest-text.mjs +88 -0
- package/bin/github/suggestion-thread.d.mts +9 -0
- package/bin/github/suggestion-thread.mjs +45 -0
- package/bin/github/thread-comments.d.mts +2 -0
- package/bin/github/thread-comments.mjs +12 -8
- package/bin/index.d.mts +10 -0
- package/bin/index.mjs +1 -1
- package/bin/log/log-file.d.mts +28 -0
- package/bin/log/session.d.mts +31 -0
- package/bin/log/setup.d.mts +6 -0
- package/bin/mcp/index.d.mts +5 -0
- package/bin/mcp/index.mjs +8 -0
- package/bin/mcp/server.d.mts +8 -0
- package/bin/mcp/server.mjs +157 -0
- package/bin/mcp-stdio.d.mts +2 -0
- package/bin/mcp-stdio.mjs +7 -0
- package/bin/merge-status/derive.d.mts +19 -0
- package/bin/merge-status/derive.mjs +2 -0
- package/bin/merge-status/requirements-format.d.mts +3 -0
- package/bin/merge-status/requirements-format.mjs +88 -0
- package/bin/merge-status/requirements.d.mts +2 -0
- package/bin/merge-status/requirements.mjs +51 -0
- package/bin/reporters/agent.d.mts +23 -0
- package/bin/reporters/agent.mjs +3 -0
- package/bin/state/base.d.mts +10 -0
- package/bin/state/base.mjs +23 -0
- package/bin/state/bot-cr-seen.d.mts +51 -0
- package/bin/state/bot-cr-seen.mjs +4 -14
- package/bin/state/fix-attempts.d.mts +27 -0
- package/bin/state/fix-attempts.mjs +3 -13
- package/bin/state/iterate-stall.d.mts +27 -0
- package/bin/state/iterate-stall.mjs +3 -13
- package/bin/state/seen-comments.d.mts +62 -0
- package/bin/state/seen-comments.mjs +6 -13
- package/bin/suggestions/extract.d.mts +8 -0
- package/bin/suggestions/parse.d.mts +48 -0
- package/bin/suggestions/patch.d.mts +14 -0
- package/bin/threads/transcript.d.mts +14 -0
- package/bin/threads/transcript.mjs +4 -0
- package/bin/types/activity.d.mts +30 -0
- package/bin/types/agent-thread.d.mts +9 -0
- package/bin/types/check-annotations.d.mts +14 -0
- package/bin/types/check-classification.d.mts +19 -0
- package/bin/types/github.d.mts +136 -0
- package/bin/types/iterate.d.mts +156 -0
- package/bin/types/merge-requirements.d.mts +82 -0
- package/bin/types/merge-requirements.mjs +2 -0
- package/bin/types/protected-run.d.mts +6 -0
- package/bin/types/report.d.mts +176 -0
- package/bin/types/review-thread.d.mts +12 -0
- package/bin/types.d.mts +10 -0
- package/bin/types.mjs +1 -0
- package/bin/util/markdown.d.mts +1 -0
- package/bin/util/path-segment.d.mts +4 -0
- package/bin/util/path-segment.mjs +2 -0
- package/bin/util/pool.d.mts +2 -0
- package/bin/util/pool.mjs +18 -0
- package/bin/util/sleep.d.mts +1 -0
- package/bin/util/worktree.d.mts +9 -0
- package/bin/util/worktree.mjs +4 -1
- package/package.json +51 -37
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +3 -2
- package/plugins/pr-shepherd/.codex.mcp.json +8 -0
- package/plugins/pr-shepherd/.mcp.json +6 -0
- package/plugins/pr-shepherd/skills/mark-files-as-viewed/SKILL.md +5 -19
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -15
- package/src/classify/types.mts +12 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level GitHub client — wraps http.mts for application-level concerns.
|
|
3
|
+
*
|
|
4
|
+
* All GitHub I/O goes through native fetch (via http.mts); the `gh` CLI is no
|
|
5
|
+
* longer used for GitHub API calls, but may be invoked as an auth-token
|
|
6
|
+
* fallback via `gh auth token` when neither GH_TOKEN nor GITHUB_TOKEN is set.
|
|
7
|
+
*/
|
|
8
|
+
import type { MergeableState, MergeStateStatus } from "../types.mts";
|
|
9
|
+
export type { RateLimitInfo } from "./http.mts";
|
|
10
|
+
export { graphql, graphqlWithRateLimit } from "./http.mts";
|
|
11
|
+
export interface RepoInfo {
|
|
12
|
+
owner: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns the current repo's owner and name by parsing `git remote get-url origin`.
|
|
17
|
+
* Handles https://, git@, and ssh:// remote URL formats.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getRepoInfo(): Promise<RepoInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Derives the PR number for the current HEAD branch.
|
|
22
|
+
* Returns null if no open PR is found.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getCurrentPrNumber(): Promise<number | null>;
|
|
25
|
+
/** Returns the PR number for a given branch, or null if no open PR is found. */
|
|
26
|
+
export declare function getPrNumberForBranch(branch: string, owner: string, repo: string): Promise<number | null>;
|
|
27
|
+
/** Returns the `headRefOid` (commit SHA) of the given PR as reported by GitHub. */
|
|
28
|
+
export declare function getPrHeadSha(pr: number, owner: string, name: string): Promise<string>;
|
|
29
|
+
/** Fetches the node ID and body text for a PR. GitHub returns null body for empty bodies — coerced to "". */
|
|
30
|
+
export declare function getPullRequestBody(pr: number, owner: string, name: string): Promise<{
|
|
31
|
+
nodeId: string;
|
|
32
|
+
body: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Overwrites the PR body. */
|
|
35
|
+
export declare function updatePullRequestBody(pullRequestId: string, body: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Fetches `mergeable` and `mergeStateStatus` via the REST API.
|
|
38
|
+
*
|
|
39
|
+
* Used as a fallback when the GraphQL API returns `UNKNOWN` for these fields —
|
|
40
|
+
* a known GitHub quirk where GraphQL lags behind the REST layer.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getMergeableState(pr: number, owner: string, repo: string): Promise<{
|
|
43
|
+
mergeable: MergeableState;
|
|
44
|
+
mergeStateStatus: MergeStateStatus;
|
|
45
|
+
}>;
|
|
46
|
+
export declare function getCurrentBranch(): Promise<string>;
|
package/bin/github/client.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import { execFile as execFileCb } from "node:child_process";
|
|
|
9
9
|
import { promisify } from "node:util";
|
|
10
10
|
import { graphql as httpGraphql, rest } from "./http.mjs";
|
|
11
11
|
import { PR_NUMBER_BY_BRANCH_QUERY, GET_PR_HEAD_SHA_QUERY, GET_PR_BODY_QUERY, UPDATE_PR_BODY_MUTATION, } from "./queries.mjs";
|
|
12
|
+
import { getExecutionCwd } from "../execution-context.mjs";
|
|
12
13
|
const execFile = promisify(execFileCb);
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// GraphQL — thin re-exports so callers don't need to import http.mts directly
|
|
@@ -19,7 +20,9 @@ export { graphql, graphqlWithRateLimit } from "./http.mjs";
|
|
|
19
20
|
* Handles https://, git@, and ssh:// remote URL formats.
|
|
20
21
|
*/
|
|
21
22
|
export async function getRepoInfo() {
|
|
22
|
-
const { stdout } = await execFile("git", ["remote", "get-url", "origin"]
|
|
23
|
+
const { stdout } = await execFile("git", ["remote", "get-url", "origin"], {
|
|
24
|
+
cwd: getExecutionCwd(),
|
|
25
|
+
});
|
|
23
26
|
const url = stdout.trim();
|
|
24
27
|
return parseRemoteUrl(url);
|
|
25
28
|
}
|
|
@@ -95,7 +98,9 @@ export async function getMergeableState(pr, owner, repo) {
|
|
|
95
98
|
// Internal helpers
|
|
96
99
|
// ---------------------------------------------------------------------------
|
|
97
100
|
export async function getCurrentBranch() {
|
|
98
|
-
const { stdout } = await execFile("git", ["rev-parse", "--abbrev-ref", "HEAD"]
|
|
101
|
+
const { stdout } = await execFile("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
102
|
+
cwd: getExecutionCwd(),
|
|
103
|
+
});
|
|
99
104
|
return stdout.trim();
|
|
100
105
|
}
|
|
101
106
|
function parseRemoteUrl(url) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ShepherdError } from "../exit-codes.mts";
|
|
2
|
+
import type { RateLimitInfo } from "./http.mts";
|
|
3
|
+
export interface GitHubGraphQlError {
|
|
4
|
+
message: string;
|
|
5
|
+
path?: unknown;
|
|
6
|
+
}
|
|
7
|
+
export declare class GitHubRequestError extends ShepherdError {
|
|
8
|
+
readonly status: number;
|
|
9
|
+
readonly rateLimit?: RateLimitInfo;
|
|
10
|
+
readonly retryAfterSeconds?: number;
|
|
11
|
+
readonly graphqlErrors?: GitHubGraphQlError[];
|
|
12
|
+
constructor(message: string, opts: {
|
|
13
|
+
status: number;
|
|
14
|
+
rateLimit?: RateLimitInfo;
|
|
15
|
+
retryAfterSeconds?: number;
|
|
16
|
+
graphqlErrors?: GitHubGraphQlError[];
|
|
17
|
+
/**
|
|
18
|
+
* Bypasses status-based classification entirely — for callers that already
|
|
19
|
+
* know the failure kind better than the HTTP status can express (e.g. a
|
|
20
|
+
* response that failed to parse at all, which is an internal failure, not
|
|
21
|
+
* an availability or permission problem).
|
|
22
|
+
*/
|
|
23
|
+
exitCodeOverride?: number;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Follow-up pages only — skipped connections are omitted via @include so extra
|
|
2
|
+
# pages do not re-pay the full batch-pr.gql node cost. Outstanding cursors are
|
|
3
|
+
# sent together in one request.
|
|
4
|
+
query BatchPrPage(
|
|
5
|
+
$owner: String!
|
|
6
|
+
$repo: String!
|
|
7
|
+
$pr: Int!
|
|
8
|
+
$includeThreads: Boolean!
|
|
9
|
+
$threadsCursor: String
|
|
10
|
+
$includeComments: Boolean!
|
|
11
|
+
$commentsCursor: String
|
|
12
|
+
$includeChangesRequested: Boolean!
|
|
13
|
+
$changesRequestedCursor: String
|
|
14
|
+
$includeReviewSummaries: Boolean!
|
|
15
|
+
$reviewSummariesCursor: String
|
|
16
|
+
$includeApprovedReviews: Boolean!
|
|
17
|
+
$approvedReviewsCursor: String
|
|
18
|
+
$includeChecks: Boolean!
|
|
19
|
+
$checksCursor: String
|
|
20
|
+
) {
|
|
21
|
+
repository(owner: $owner, name: $repo) {
|
|
22
|
+
pullRequest(number: $pr) {
|
|
23
|
+
reviewThreads(last: 100, before: $threadsCursor) @include(if: $includeThreads) {
|
|
24
|
+
pageInfo {
|
|
25
|
+
hasPreviousPage
|
|
26
|
+
startCursor
|
|
27
|
+
}
|
|
28
|
+
nodes {
|
|
29
|
+
id
|
|
30
|
+
isResolved
|
|
31
|
+
isOutdated
|
|
32
|
+
path
|
|
33
|
+
line
|
|
34
|
+
startLine
|
|
35
|
+
comments(first: 100) {
|
|
36
|
+
pageInfo {
|
|
37
|
+
hasNextPage
|
|
38
|
+
endCursor
|
|
39
|
+
}
|
|
40
|
+
nodes {
|
|
41
|
+
id
|
|
42
|
+
isMinimized
|
|
43
|
+
url
|
|
44
|
+
authorAssociation
|
|
45
|
+
author {
|
|
46
|
+
__typename
|
|
47
|
+
login
|
|
48
|
+
}
|
|
49
|
+
pullRequestReview {
|
|
50
|
+
id
|
|
51
|
+
}
|
|
52
|
+
body
|
|
53
|
+
path
|
|
54
|
+
line
|
|
55
|
+
startLine
|
|
56
|
+
createdAt
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
comments(last: 100, before: $commentsCursor) @include(if: $includeComments) {
|
|
62
|
+
pageInfo {
|
|
63
|
+
hasPreviousPage
|
|
64
|
+
startCursor
|
|
65
|
+
}
|
|
66
|
+
nodes {
|
|
67
|
+
id
|
|
68
|
+
isMinimized
|
|
69
|
+
url
|
|
70
|
+
authorAssociation
|
|
71
|
+
author {
|
|
72
|
+
__typename
|
|
73
|
+
login
|
|
74
|
+
}
|
|
75
|
+
body
|
|
76
|
+
createdAt
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
changesRequestedReviews: reviews(
|
|
80
|
+
states: CHANGES_REQUESTED
|
|
81
|
+
last: 50
|
|
82
|
+
before: $changesRequestedCursor
|
|
83
|
+
) @include(if: $includeChangesRequested) {
|
|
84
|
+
pageInfo {
|
|
85
|
+
hasPreviousPage
|
|
86
|
+
startCursor
|
|
87
|
+
}
|
|
88
|
+
nodes {
|
|
89
|
+
id
|
|
90
|
+
authorAssociation
|
|
91
|
+
author {
|
|
92
|
+
__typename
|
|
93
|
+
login
|
|
94
|
+
}
|
|
95
|
+
body
|
|
96
|
+
createdAt
|
|
97
|
+
commit {
|
|
98
|
+
oid
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
reviewSummaries: reviews(states: COMMENTED, last: 50, before: $reviewSummariesCursor)
|
|
103
|
+
@include(if: $includeReviewSummaries) {
|
|
104
|
+
pageInfo {
|
|
105
|
+
hasPreviousPage
|
|
106
|
+
startCursor
|
|
107
|
+
}
|
|
108
|
+
nodes {
|
|
109
|
+
id
|
|
110
|
+
isMinimized
|
|
111
|
+
authorAssociation
|
|
112
|
+
author {
|
|
113
|
+
__typename
|
|
114
|
+
login
|
|
115
|
+
}
|
|
116
|
+
body
|
|
117
|
+
createdAt
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
approvedReviews: reviews(states: APPROVED, last: 50, before: $approvedReviewsCursor)
|
|
121
|
+
@include(if: $includeApprovedReviews) {
|
|
122
|
+
pageInfo {
|
|
123
|
+
hasPreviousPage
|
|
124
|
+
startCursor
|
|
125
|
+
}
|
|
126
|
+
nodes {
|
|
127
|
+
id
|
|
128
|
+
isMinimized
|
|
129
|
+
authorAssociation
|
|
130
|
+
author {
|
|
131
|
+
__typename
|
|
132
|
+
login
|
|
133
|
+
}
|
|
134
|
+
body
|
|
135
|
+
createdAt
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
commits(last: 1) @include(if: $includeChecks) {
|
|
139
|
+
nodes {
|
|
140
|
+
commit {
|
|
141
|
+
oid
|
|
142
|
+
statusCheckRollup {
|
|
143
|
+
contexts(first: 100, after: $checksCursor) {
|
|
144
|
+
pageInfo {
|
|
145
|
+
hasNextPage
|
|
146
|
+
endCursor
|
|
147
|
+
}
|
|
148
|
+
nodes {
|
|
149
|
+
__typename
|
|
150
|
+
... on CheckRun {
|
|
151
|
+
id
|
|
152
|
+
name
|
|
153
|
+
status
|
|
154
|
+
conclusion
|
|
155
|
+
detailsUrl
|
|
156
|
+
completedAt
|
|
157
|
+
startedAt
|
|
158
|
+
title
|
|
159
|
+
summary
|
|
160
|
+
checkSuite {
|
|
161
|
+
createdAt
|
|
162
|
+
updatedAt
|
|
163
|
+
workflowRun {
|
|
164
|
+
event
|
|
165
|
+
createdAt
|
|
166
|
+
updatedAt
|
|
167
|
+
workflow {
|
|
168
|
+
name
|
|
169
|
+
databaseId
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
... on StatusContext {
|
|
175
|
+
context
|
|
176
|
+
state
|
|
177
|
+
createdAt
|
|
178
|
+
targetUrl
|
|
179
|
+
description
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
$pr: Int!
|
|
5
|
-
$threadsCursor: String
|
|
6
|
-
$checksCursor: String
|
|
7
|
-
$commentsCursor: String
|
|
8
|
-
$changesRequestedCursor: String
|
|
9
|
-
$reviewSummariesCursor: String
|
|
10
|
-
$approvedReviewsCursor: String
|
|
11
|
-
) {
|
|
1
|
+
# First page only. Extra pages use batch-pr-page.gql so follow-ups do not
|
|
2
|
+
# re-select every connection (GraphQL points scale with possible nodes).
|
|
3
|
+
query BatchPr($owner: String!, $repo: String!, $pr: Int!) {
|
|
12
4
|
repository(owner: $owner, name: $repo) {
|
|
13
5
|
pullRequest(number: $pr) {
|
|
14
6
|
id
|
|
@@ -24,13 +16,62 @@ query BatchPr(
|
|
|
24
16
|
nameWithOwner
|
|
25
17
|
}
|
|
26
18
|
baseRefName
|
|
19
|
+
isInMergeQueue
|
|
20
|
+
isMergeQueueEnabled
|
|
21
|
+
mergeQueueEntry {
|
|
22
|
+
position
|
|
23
|
+
state
|
|
24
|
+
estimatedTimeToMerge
|
|
25
|
+
}
|
|
26
|
+
stack {
|
|
27
|
+
number
|
|
28
|
+
size
|
|
29
|
+
baseRefName
|
|
30
|
+
}
|
|
31
|
+
stackEntry {
|
|
32
|
+
position
|
|
33
|
+
}
|
|
27
34
|
baseRef {
|
|
28
35
|
branchProtectionRule {
|
|
29
36
|
requiresApprovingReviews
|
|
30
37
|
requiredApprovingReviewCount
|
|
31
38
|
requiresConversationResolution
|
|
39
|
+
requiresCodeOwnerReviews
|
|
40
|
+
requireLastPushApproval
|
|
41
|
+
requiresCommitSignatures
|
|
42
|
+
requiresLinearHistory
|
|
32
43
|
requiresStatusChecks
|
|
33
44
|
requiredStatusCheckContexts
|
|
45
|
+
requiresStrictStatusChecks
|
|
46
|
+
requiresDeployments
|
|
47
|
+
requiredDeploymentEnvironments
|
|
48
|
+
}
|
|
49
|
+
rules(first: 100) {
|
|
50
|
+
nodes {
|
|
51
|
+
type
|
|
52
|
+
parameters {
|
|
53
|
+
... on PullRequestParameters {
|
|
54
|
+
requiredApprovingReviewCount
|
|
55
|
+
requiredReviewThreadResolution
|
|
56
|
+
requireCodeOwnerReview
|
|
57
|
+
requireLastPushApproval
|
|
58
|
+
}
|
|
59
|
+
... on RequiredStatusChecksParameters {
|
|
60
|
+
strictRequiredStatusChecksPolicy
|
|
61
|
+
requiredStatusChecks {
|
|
62
|
+
context
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
... on RequiredDeploymentsParameters {
|
|
66
|
+
requiredDeploymentEnvironments
|
|
67
|
+
}
|
|
68
|
+
... on CodeScanningParameters {
|
|
69
|
+
codeScanningTools {
|
|
70
|
+
tool
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
34
75
|
}
|
|
35
76
|
}
|
|
36
77
|
# Not paginated — capped at 50; PRs with more pending reviewers truncate silently.
|
|
@@ -61,7 +102,7 @@ query BatchPr(
|
|
|
61
102
|
state
|
|
62
103
|
}
|
|
63
104
|
}
|
|
64
|
-
reviewThreads(last: 100
|
|
105
|
+
reviewThreads(last: 100) {
|
|
65
106
|
pageInfo {
|
|
66
107
|
hasPreviousPage
|
|
67
108
|
startCursor
|
|
@@ -82,6 +123,7 @@ query BatchPr(
|
|
|
82
123
|
id
|
|
83
124
|
isMinimized
|
|
84
125
|
url
|
|
126
|
+
authorAssociation
|
|
85
127
|
author {
|
|
86
128
|
__typename
|
|
87
129
|
login
|
|
@@ -98,7 +140,7 @@ query BatchPr(
|
|
|
98
140
|
}
|
|
99
141
|
}
|
|
100
142
|
}
|
|
101
|
-
comments(last: 100
|
|
143
|
+
comments(last: 100) {
|
|
102
144
|
pageInfo {
|
|
103
145
|
hasPreviousPage
|
|
104
146
|
startCursor
|
|
@@ -107,6 +149,7 @@ query BatchPr(
|
|
|
107
149
|
id
|
|
108
150
|
isMinimized
|
|
109
151
|
url
|
|
152
|
+
authorAssociation
|
|
110
153
|
author {
|
|
111
154
|
__typename
|
|
112
155
|
login
|
|
@@ -115,17 +158,14 @@ query BatchPr(
|
|
|
115
158
|
createdAt
|
|
116
159
|
}
|
|
117
160
|
}
|
|
118
|
-
changesRequestedReviews: reviews(
|
|
119
|
-
states: CHANGES_REQUESTED
|
|
120
|
-
last: 50
|
|
121
|
-
before: $changesRequestedCursor
|
|
122
|
-
) {
|
|
161
|
+
changesRequestedReviews: reviews(states: CHANGES_REQUESTED, last: 50) {
|
|
123
162
|
pageInfo {
|
|
124
163
|
hasPreviousPage
|
|
125
164
|
startCursor
|
|
126
165
|
}
|
|
127
166
|
nodes {
|
|
128
167
|
id
|
|
168
|
+
authorAssociation
|
|
129
169
|
author {
|
|
130
170
|
__typename
|
|
131
171
|
login
|
|
@@ -137,7 +177,7 @@ query BatchPr(
|
|
|
137
177
|
}
|
|
138
178
|
}
|
|
139
179
|
}
|
|
140
|
-
reviewSummaries: reviews(states: COMMENTED, last: 50
|
|
180
|
+
reviewSummaries: reviews(states: COMMENTED, last: 50) {
|
|
141
181
|
pageInfo {
|
|
142
182
|
hasPreviousPage
|
|
143
183
|
startCursor
|
|
@@ -145,6 +185,7 @@ query BatchPr(
|
|
|
145
185
|
nodes {
|
|
146
186
|
id
|
|
147
187
|
isMinimized
|
|
188
|
+
authorAssociation
|
|
148
189
|
author {
|
|
149
190
|
__typename
|
|
150
191
|
login
|
|
@@ -156,7 +197,7 @@ query BatchPr(
|
|
|
156
197
|
allReviews: reviews(last: 1) {
|
|
157
198
|
totalCount
|
|
158
199
|
}
|
|
159
|
-
approvedReviews: reviews(states: APPROVED, last: 50
|
|
200
|
+
approvedReviews: reviews(states: APPROVED, last: 50) {
|
|
160
201
|
pageInfo {
|
|
161
202
|
hasPreviousPage
|
|
162
203
|
startCursor
|
|
@@ -164,6 +205,7 @@ query BatchPr(
|
|
|
164
205
|
nodes {
|
|
165
206
|
id
|
|
166
207
|
isMinimized
|
|
208
|
+
authorAssociation
|
|
167
209
|
author {
|
|
168
210
|
__typename
|
|
169
211
|
login
|
|
@@ -178,8 +220,24 @@ query BatchPr(
|
|
|
178
220
|
commit {
|
|
179
221
|
oid
|
|
180
222
|
committedDate
|
|
223
|
+
checkSuites(first: 50) {
|
|
224
|
+
pageInfo {
|
|
225
|
+
hasNextPage
|
|
226
|
+
}
|
|
227
|
+
nodes {
|
|
228
|
+
conclusion
|
|
229
|
+
workflowRun {
|
|
230
|
+
databaseId
|
|
231
|
+
event
|
|
232
|
+
url
|
|
233
|
+
workflow {
|
|
234
|
+
name
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
181
239
|
statusCheckRollup {
|
|
182
|
-
contexts(first: 100
|
|
240
|
+
contexts(first: 100) {
|
|
183
241
|
pageInfo {
|
|
184
242
|
hasNextPage
|
|
185
243
|
endCursor
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
query CommitSuggestionThread($owner: String!, $repo: String!, $pr: Int!, $threadId: ID!) {
|
|
2
|
+
repository(owner: $owner, name: $repo) {
|
|
3
|
+
pullRequest(number: $pr) {
|
|
4
|
+
headRefOid
|
|
5
|
+
headRefName
|
|
6
|
+
headRepository {
|
|
7
|
+
nameWithOwner
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
node(id: $threadId) {
|
|
12
|
+
... on PullRequestReviewThread {
|
|
13
|
+
id
|
|
14
|
+
isResolved
|
|
15
|
+
isOutdated
|
|
16
|
+
path
|
|
17
|
+
line
|
|
18
|
+
startLine
|
|
19
|
+
pullRequest {
|
|
20
|
+
number
|
|
21
|
+
}
|
|
22
|
+
comments(first: 1) {
|
|
23
|
+
nodes {
|
|
24
|
+
isMinimized
|
|
25
|
+
url
|
|
26
|
+
authorAssociation
|
|
27
|
+
author {
|
|
28
|
+
__typename
|
|
29
|
+
login
|
|
30
|
+
}
|
|
31
|
+
body
|
|
32
|
+
path
|
|
33
|
+
line
|
|
34
|
+
startLine
|
|
35
|
+
createdAt
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type GitHubGraphQlError } from "./errors.mts";
|
|
2
|
+
import { type RateLimitInfo } from "./http-utils.mts";
|
|
3
|
+
interface GraphQlResult<T = unknown> {
|
|
4
|
+
data: T;
|
|
5
|
+
rateLimit?: RateLimitInfo;
|
|
6
|
+
retryAfterSeconds?: number;
|
|
7
|
+
errors?: GitHubGraphQlError[];
|
|
8
|
+
}
|
|
9
|
+
export interface GraphQlRequestOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Mutation batches use partial GraphQL data to preserve per-alias successes.
|
|
12
|
+
* Read paths must keep the strict default so incomplete snapshots never drive
|
|
13
|
+
* PR state transitions.
|
|
14
|
+
*/
|
|
15
|
+
allowPartialData?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function graphql<T = unknown>(query: string, vars?: Record<string, unknown>, opts?: GraphQlRequestOptions): Promise<GraphQlResult<T>>;
|
|
18
|
+
export declare function graphqlWithRateLimit<T = unknown>(query: string, vars?: Record<string, unknown>, opts?: GraphQlRequestOptions): Promise<GraphQlResult<T>>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type GitHubGraphQlError } from "./errors.mts";
|
|
2
|
+
import type { RateLimitInfo } from "./http-utils.mts";
|
|
3
|
+
export declare function parseGraphQlPayload<T>(parsed: unknown, status: number, rateLimit: RateLimitInfo | null, retryAfterSeconds: number | undefined): {
|
|
4
|
+
data: T | null;
|
|
5
|
+
errors?: GitHubGraphQlError[];
|
|
6
|
+
};
|
|
7
|
+
export declare function formatGraphQlErrors(errors: GitHubGraphQlError[] | undefined): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function isTransportError(err: unknown): boolean;
|
|
2
|
+
export interface RateLimitInfo {
|
|
3
|
+
remaining: number;
|
|
4
|
+
limit: number;
|
|
5
|
+
resetAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function sanitizeBody(body: string): string;
|
|
8
|
+
export declare function redactToken(body: string): string;
|
|
9
|
+
export declare function redactUrl(url: string): string;
|
|
10
|
+
export declare function parseRateLimit(headers: Headers): RateLimitInfo | null;
|
|
11
|
+
export declare function parseRetryAfter(headers: Headers): number | undefined;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { GitHubRequestError } from "./errors.mts";
|
|
2
|
+
export { _resetTokenCache } from "./http-auth.mts";
|
|
3
|
+
export { graphql, graphqlWithRateLimit } from "./graphql-http.mts";
|
|
4
|
+
export { rest, restWithRateLimit } from "./rest-http.mts";
|
|
5
|
+
export { restText } from "./rest-text.mts";
|
|
6
|
+
export type { RateLimitInfo } from "./http-utils.mts";
|
package/bin/github/http.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { GitHubRequestError } from "./errors.mjs";
|
|
2
2
|
export { _resetTokenCache } from "./http-auth.mjs";
|
|
3
3
|
export { graphql, graphqlWithRateLimit } from "./graphql-http.mjs";
|
|
4
|
-
export { rest,
|
|
4
|
+
export { rest, restWithRateLimit } from "./rest-http.mjs";
|
|
5
|
+
export { restText } from "./rest-text.mjs";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic GraphQL cursor-based paginator for shepherd.
|
|
3
|
+
*
|
|
4
|
+
* Both paginators accept a `fetchFn` instead of calling `graphql` directly,
|
|
5
|
+
* which makes them testable without any mocking — tests supply a pure function
|
|
6
|
+
* that returns pages of fake data.
|
|
7
|
+
*
|
|
8
|
+
* GitHub's GraphQL connections support two cursor directions:
|
|
9
|
+
* - Forward (`after` + `first`) — used by check contexts and nested thread comments.
|
|
10
|
+
* - Backward (`before` + `last`) — used by reviewThreads/comments/reviews extra pages
|
|
11
|
+
* (combined in `batch-page.mts`; `paginateBackward` remains the generic primitive).
|
|
12
|
+
*/
|
|
13
|
+
interface PageInfo {
|
|
14
|
+
hasNextPage?: boolean;
|
|
15
|
+
hasPreviousPage?: boolean;
|
|
16
|
+
endCursor?: string | null;
|
|
17
|
+
startCursor?: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface Connection<T> {
|
|
20
|
+
pageInfo: PageInfo;
|
|
21
|
+
nodes: T[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Paginate forward through a GraphQL connection (`first` / `after` cursors).
|
|
25
|
+
*
|
|
26
|
+
* @param fetchFn Called once per page. Receives the cursor (or null for
|
|
27
|
+
* the very first page) and returns a Connection<T>.
|
|
28
|
+
* @param initialCursor Start from this cursor instead of null. Pass the
|
|
29
|
+
* `endCursor` of an already-fetched page to fetch only
|
|
30
|
+
* the pages *after* it, avoiding a duplicate re-fetch.
|
|
31
|
+
*/
|
|
32
|
+
export declare function paginateForward<T>(fetchFn: (cursor: string | null) => Promise<Connection<T>>, initialCursor?: string | null): Promise<T[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Paginate backward through a GraphQL connection (`last` / `before` cursors).
|
|
35
|
+
*
|
|
36
|
+
* Used for `reviewThreads(last: 100, before: $before)`.
|
|
37
|
+
*
|
|
38
|
+
* @param fetchFn Called once per page. Receives the cursor (or null for
|
|
39
|
+
* the very first page). Returns a Connection<T> with
|
|
40
|
+
* `hasPreviousPage` and `startCursor` in pageInfo.
|
|
41
|
+
* @param initialCursor Start from this cursor instead of null. Pass the
|
|
42
|
+
* `startCursor` of an already-fetched page to avoid
|
|
43
|
+
* re-fetching it (fetch only the pages *before* it).
|
|
44
|
+
*/
|
|
45
|
+
export declare function paginateBackward<T>(fetchFn: (cursor: string | null) => Promise<Connection<T>>, initialCursor?: string | null): Promise<T[]>;
|
|
46
|
+
export {};
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* that returns pages of fake data.
|
|
7
7
|
*
|
|
8
8
|
* GitHub's GraphQL connections support two cursor directions:
|
|
9
|
-
* - Forward (`after` + `first`) — used by check contexts.
|
|
10
|
-
* - Backward (`before` + `last`) — used by reviewThreads
|
|
9
|
+
* - Forward (`after` + `first`) — used by check contexts and nested thread comments.
|
|
10
|
+
* - Backward (`before` + `last`) — used by reviewThreads/comments/reviews extra pages
|
|
11
|
+
* (combined in `batch-page.mts`; `paginateBackward` remains the generic primitive).
|
|
11
12
|
*/
|
|
12
13
|
/**
|
|
13
14
|
* Paginate forward through a GraphQL connection (`first` / `after` cursors).
|