@sentry/junior-github 0.199.0 → 0.200.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/index.js
CHANGED
|
@@ -1001,7 +1001,9 @@ var createPullRequestToolInputSchema = z4.object({
|
|
|
1001
1001
|
title: z4.string().describe("Pull request title."),
|
|
1002
1002
|
head: z4.string().describe("Head branch or owner:branch ref."),
|
|
1003
1003
|
base: z4.string().describe("Base branch."),
|
|
1004
|
-
body: z4.string().describe(
|
|
1004
|
+
body: z4.string().describe(
|
|
1005
|
+
"Pull request body. The runtime appends the conversation footer."
|
|
1006
|
+
).optional(),
|
|
1005
1007
|
draft: z4.boolean().describe("Whether to open the pull request as a draft.").optional()
|
|
1006
1008
|
}).strict();
|
|
1007
1009
|
var createPullRequestStateSchema = Type2.Union([
|
|
@@ -1252,6 +1254,7 @@ function createGitHubPullRequestTool(ctx, subscriptionConfig) {
|
|
|
1252
1254
|
readOnlyHint: false
|
|
1253
1255
|
},
|
|
1254
1256
|
description: "Create a GitHub pull request with a runtime-owned conversation footer. Use this instead of shelling out to gh pr create when creating pull requests.",
|
|
1257
|
+
exposure: "direct",
|
|
1255
1258
|
inputSchema: createPullRequestToolInputSchema,
|
|
1256
1259
|
outputSchema: gitHubPullRequestOutputSchema,
|
|
1257
1260
|
async execute(input, options) {
|
|
@@ -2191,6 +2194,129 @@ function createGitHubResolvePullRequestReviewThreadTool(ctx, botEmail) {
|
|
|
2191
2194
|
});
|
|
2192
2195
|
}
|
|
2193
2196
|
|
|
2197
|
+
// src/tools/submit-pull-request-review.ts
|
|
2198
|
+
import {
|
|
2199
|
+
definePluginTool as definePluginTool11,
|
|
2200
|
+
PluginToolInputError as PluginToolInputError12,
|
|
2201
|
+
pluginToolOutputSchema as pluginToolOutputSchema11
|
|
2202
|
+
} from "@sentry/junior-plugin-api";
|
|
2203
|
+
import { z as z11 } from "zod";
|
|
2204
|
+
var reviewCommentSchema = z11.object({
|
|
2205
|
+
path: z11.string().trim().min(1).describe("File path in the pull request."),
|
|
2206
|
+
body: z11.string().trim().min(1).describe("Inline review comment."),
|
|
2207
|
+
line: z11.number().int().positive().describe("Line in the pull request diff."),
|
|
2208
|
+
side: z11.enum(["LEFT", "RIGHT"]).describe("Side of the pull request diff."),
|
|
2209
|
+
startLine: z11.number().int().positive().optional().describe("First line of a multi-line comment."),
|
|
2210
|
+
startSide: z11.enum(["LEFT", "RIGHT"]).optional().describe("First side of a multi-line comment.")
|
|
2211
|
+
}).strict().refine(
|
|
2212
|
+
({ startLine, startSide }) => startLine === void 0 === (startSide === void 0),
|
|
2213
|
+
{ message: "startLine and startSide must be provided together." }
|
|
2214
|
+
);
|
|
2215
|
+
var inputSchema9 = z11.object({
|
|
2216
|
+
repo: z11.string().describe('Repository in "owner/name" format.'),
|
|
2217
|
+
number: z11.number().int().positive().describe("Pull request number."),
|
|
2218
|
+
event: z11.enum(["COMMENT", "REQUEST_CHANGES"]).describe("Review result. Junior cannot approve pull requests."),
|
|
2219
|
+
body: z11.string().trim().min(1).describe("Review summary."),
|
|
2220
|
+
comments: z11.array(reviewCommentSchema).optional().describe("Optional inline review comments.")
|
|
2221
|
+
}).strict();
|
|
2222
|
+
var outputSchema9 = pluginToolOutputSchema11.extend({
|
|
2223
|
+
target: z11.literal("submitPullRequestReview"),
|
|
2224
|
+
repo: z11.string(),
|
|
2225
|
+
number: z11.number(),
|
|
2226
|
+
reviewId: z11.number(),
|
|
2227
|
+
state: z11.string(),
|
|
2228
|
+
url: z11.string()
|
|
2229
|
+
});
|
|
2230
|
+
function parseRepo11(value) {
|
|
2231
|
+
const parts = value.split("/").map((part) => part.trim());
|
|
2232
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
2233
|
+
throw new PluginToolInputError12('repo must use "owner/name" format');
|
|
2234
|
+
}
|
|
2235
|
+
return { owner: parts[0], name: parts[1], ref: `${parts[0]}/${parts[1]}` };
|
|
2236
|
+
}
|
|
2237
|
+
async function readJson8(response) {
|
|
2238
|
+
const text2 = await response.text();
|
|
2239
|
+
if (!text2) return void 0;
|
|
2240
|
+
try {
|
|
2241
|
+
return JSON.parse(text2);
|
|
2242
|
+
} catch {
|
|
2243
|
+
return text2;
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
function githubError2(body) {
|
|
2247
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
2248
|
+
const message = body.message;
|
|
2249
|
+
if (typeof message === "string" && message.trim()) return message.trim();
|
|
2250
|
+
}
|
|
2251
|
+
if (typeof body === "string" && body.trim()) return body.trim();
|
|
2252
|
+
return "GitHub request failed";
|
|
2253
|
+
}
|
|
2254
|
+
function throwReviewError(status, body) {
|
|
2255
|
+
const message = `GitHub pull request review failed with HTTP ${status}: ${githubError2(body)}`;
|
|
2256
|
+
if (status === 404 || status === 422) {
|
|
2257
|
+
throw new PluginToolInputError12(message);
|
|
2258
|
+
}
|
|
2259
|
+
throw new Error(message);
|
|
2260
|
+
}
|
|
2261
|
+
function createGitHubSubmitPullRequestReviewTool(egress) {
|
|
2262
|
+
return definePluginTool11({
|
|
2263
|
+
annotations: {
|
|
2264
|
+
destructiveHint: true,
|
|
2265
|
+
idempotentHint: false,
|
|
2266
|
+
openWorldHint: true,
|
|
2267
|
+
readOnlyHint: false
|
|
2268
|
+
},
|
|
2269
|
+
description: "Submit a GitHub pull request review as a comment or change request. Use this instead of `gh pr review`, GraphQL, or direct REST calls. Junior cannot approve pull requests.",
|
|
2270
|
+
exposure: "direct",
|
|
2271
|
+
inputSchema: inputSchema9,
|
|
2272
|
+
outputSchema: outputSchema9,
|
|
2273
|
+
async execute(review) {
|
|
2274
|
+
const repo = parseRepo11(review.repo);
|
|
2275
|
+
const comments = review.comments?.map((comment) => ({
|
|
2276
|
+
path: comment.path,
|
|
2277
|
+
body: comment.body,
|
|
2278
|
+
line: comment.line,
|
|
2279
|
+
side: comment.side,
|
|
2280
|
+
...comment.startLine !== void 0 ? { start_line: comment.startLine } : void 0,
|
|
2281
|
+
...comment.startSide !== void 0 ? { start_side: comment.startSide } : void 0
|
|
2282
|
+
}));
|
|
2283
|
+
const response = await egress.fetch({
|
|
2284
|
+
provider: "github",
|
|
2285
|
+
operation: "github.pull.review.create",
|
|
2286
|
+
request: new Request(
|
|
2287
|
+
`https://api.github.com/repos/${encodeURIComponent(repo.owner)}/${encodeURIComponent(repo.name)}/pulls/${review.number}/reviews`,
|
|
2288
|
+
{
|
|
2289
|
+
method: "POST",
|
|
2290
|
+
headers: {
|
|
2291
|
+
Accept: "application/vnd.github+json",
|
|
2292
|
+
"Content-Type": "application/json",
|
|
2293
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
2294
|
+
},
|
|
2295
|
+
body: JSON.stringify({
|
|
2296
|
+
body: review.body,
|
|
2297
|
+
event: review.event,
|
|
2298
|
+
...comments ? { comments } : void 0
|
|
2299
|
+
})
|
|
2300
|
+
}
|
|
2301
|
+
)
|
|
2302
|
+
});
|
|
2303
|
+
const parsed = await readJson8(response);
|
|
2304
|
+
if (!response.ok) {
|
|
2305
|
+
throwReviewError(response.status, parsed);
|
|
2306
|
+
}
|
|
2307
|
+
const providerResult = z11.object({ id: z11.number(), html_url: z11.string(), state: z11.string() }).parse(parsed);
|
|
2308
|
+
return {
|
|
2309
|
+
target: "submitPullRequestReview",
|
|
2310
|
+
repo: repo.ref,
|
|
2311
|
+
number: review.number,
|
|
2312
|
+
reviewId: providerResult.id,
|
|
2313
|
+
state: providerResult.state,
|
|
2314
|
+
url: providerResult.html_url
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2194
2320
|
// src/tools.ts
|
|
2195
2321
|
function createGitHubTools(ctx, botEmail, pullRequestSubscription) {
|
|
2196
2322
|
return {
|
|
@@ -2205,6 +2331,9 @@ function createGitHubTools(ctx, botEmail, pullRequestSubscription) {
|
|
|
2205
2331
|
getRelease: createGitHubGetReleaseTool(ctx),
|
|
2206
2332
|
getRepository: createGitHubGetRepositoryTool(ctx),
|
|
2207
2333
|
resolvePullRequestReviewThread: createGitHubResolvePullRequestReviewThreadTool(ctx, botEmail),
|
|
2334
|
+
submitPullRequestReview: createGitHubSubmitPullRequestReviewTool(
|
|
2335
|
+
ctx.egress
|
|
2336
|
+
),
|
|
2208
2337
|
updateIssue: createGitHubUpdateIssueTool(ctx),
|
|
2209
2338
|
updatePullRequest: createGitHubUpdatePullRequestTool(ctx)
|
|
2210
2339
|
};
|
|
@@ -2215,7 +2344,7 @@ import { createHmac, timingSafeEqual } from "crypto";
|
|
|
2215
2344
|
|
|
2216
2345
|
// src/issue-outcomes/store.ts
|
|
2217
2346
|
import { and, eq, lte, sql as sql2 } from "drizzle-orm";
|
|
2218
|
-
import { z as
|
|
2347
|
+
import { z as z13 } from "zod";
|
|
2219
2348
|
|
|
2220
2349
|
// src/db/schema.ts
|
|
2221
2350
|
import { sql } from "drizzle-orm";
|
|
@@ -2227,18 +2356,18 @@ import {
|
|
|
2227
2356
|
text,
|
|
2228
2357
|
timestamp
|
|
2229
2358
|
} from "drizzle-orm/pg-core";
|
|
2230
|
-
import { z as
|
|
2231
|
-
var githubPullRequestStateSchema =
|
|
2359
|
+
import { z as z12 } from "zod";
|
|
2360
|
+
var githubPullRequestStateSchema = z12.enum([
|
|
2232
2361
|
"closed_unmerged",
|
|
2233
2362
|
"merged",
|
|
2234
2363
|
"open"
|
|
2235
2364
|
]);
|
|
2236
|
-
var githubPullRequestCommitCompositionSchema =
|
|
2365
|
+
var githubPullRequestCommitCompositionSchema = z12.enum([
|
|
2237
2366
|
"junior_only",
|
|
2238
2367
|
"mixed"
|
|
2239
2368
|
]);
|
|
2240
|
-
var githubIssueStateSchema =
|
|
2241
|
-
var githubIssueStateReasonSchema =
|
|
2369
|
+
var githubIssueStateSchema = z12.enum(["closed", "open"]);
|
|
2370
|
+
var githubIssueStateReasonSchema = z12.enum([
|
|
2242
2371
|
"completed",
|
|
2243
2372
|
"duplicate",
|
|
2244
2373
|
"not_planned",
|
|
@@ -2308,21 +2437,21 @@ var juniorGitHubPullRequestIssues = pgTable(
|
|
|
2308
2437
|
);
|
|
2309
2438
|
|
|
2310
2439
|
// src/issue-outcomes/store.ts
|
|
2311
|
-
var githubIssueOutcomeInputSchema =
|
|
2312
|
-
candidateOwned:
|
|
2313
|
-
closedAt:
|
|
2314
|
-
issueId:
|
|
2315
|
-
number:
|
|
2316
|
-
openedAt:
|
|
2317
|
-
repositoryFullName:
|
|
2318
|
-
repositoryId:
|
|
2440
|
+
var githubIssueOutcomeInputSchema = z13.object({
|
|
2441
|
+
candidateOwned: z13.boolean(),
|
|
2442
|
+
closedAt: z13.date().optional(),
|
|
2443
|
+
issueId: z13.string().min(1),
|
|
2444
|
+
number: z13.number().int().positive(),
|
|
2445
|
+
openedAt: z13.date(),
|
|
2446
|
+
repositoryFullName: z13.string().min(1),
|
|
2447
|
+
repositoryId: z13.string().min(1),
|
|
2319
2448
|
state: githubIssueStateSchema,
|
|
2320
2449
|
stateReason: githubIssueStateReasonSchema.optional(),
|
|
2321
|
-
updatedAt:
|
|
2450
|
+
updatedAt: z13.date()
|
|
2322
2451
|
}).strict();
|
|
2323
|
-
var githubIssueConversationsInputSchema =
|
|
2324
|
-
conversationIds:
|
|
2325
|
-
issueId:
|
|
2452
|
+
var githubIssueConversationsInputSchema = z13.object({
|
|
2453
|
+
conversationIds: z13.array(z13.string().min(1)).min(1),
|
|
2454
|
+
issueId: z13.string().min(1)
|
|
2326
2455
|
}).strict();
|
|
2327
2456
|
function projectionValues(input) {
|
|
2328
2457
|
return {
|
|
@@ -2386,33 +2515,33 @@ async function recordGitHubIssueConversations(db, input) {
|
|
|
2386
2515
|
|
|
2387
2516
|
// src/pull-request-outcomes/store.ts
|
|
2388
2517
|
import { and as and2, eq as eq2, lte as lte2, ne, sql as sql3 } from "drizzle-orm";
|
|
2389
|
-
import { z as
|
|
2390
|
-
var githubPullRequestOutcomeInputSchema =
|
|
2391
|
-
candidateOwned:
|
|
2392
|
-
closedAt:
|
|
2518
|
+
import { z as z14 } from "zod";
|
|
2519
|
+
var githubPullRequestOutcomeInputSchema = z14.object({
|
|
2520
|
+
candidateOwned: z14.boolean(),
|
|
2521
|
+
closedAt: z14.date().optional(),
|
|
2393
2522
|
commitComposition: githubPullRequestCommitCompositionSchema.optional(),
|
|
2394
|
-
mergedAt:
|
|
2395
|
-
number:
|
|
2396
|
-
openedAt:
|
|
2397
|
-
pullRequestId:
|
|
2398
|
-
repositoryFullName:
|
|
2399
|
-
repositoryId:
|
|
2523
|
+
mergedAt: z14.date().optional(),
|
|
2524
|
+
number: z14.number().int().positive(),
|
|
2525
|
+
openedAt: z14.date(),
|
|
2526
|
+
pullRequestId: z14.string().min(1),
|
|
2527
|
+
repositoryFullName: z14.string().min(1),
|
|
2528
|
+
repositoryId: z14.string().min(1),
|
|
2400
2529
|
state: githubPullRequestStateSchema,
|
|
2401
|
-
title:
|
|
2402
|
-
updatedAt:
|
|
2530
|
+
title: z14.string().min(1).optional(),
|
|
2531
|
+
updatedAt: z14.date()
|
|
2403
2532
|
}).strict();
|
|
2404
|
-
var githubPullRequestConversationsInputSchema =
|
|
2405
|
-
conversationIds:
|
|
2406
|
-
pullRequestId:
|
|
2533
|
+
var githubPullRequestConversationsInputSchema = z14.object({
|
|
2534
|
+
conversationIds: z14.array(z14.string().min(1)).min(1),
|
|
2535
|
+
pullRequestId: z14.string().min(1)
|
|
2407
2536
|
}).strict();
|
|
2408
|
-
var githubPullRequestLinkedIssuesInputSchema =
|
|
2409
|
-
linkedIssues:
|
|
2410
|
-
|
|
2411
|
-
number:
|
|
2412
|
-
repositoryFullName:
|
|
2537
|
+
var githubPullRequestLinkedIssuesInputSchema = z14.object({
|
|
2538
|
+
linkedIssues: z14.array(
|
|
2539
|
+
z14.object({
|
|
2540
|
+
number: z14.number().int().positive(),
|
|
2541
|
+
repositoryFullName: z14.string().min(1)
|
|
2413
2542
|
}).strict()
|
|
2414
2543
|
).min(1),
|
|
2415
|
-
pullRequestId:
|
|
2544
|
+
pullRequestId: z14.string().min(1)
|
|
2416
2545
|
}).strict();
|
|
2417
2546
|
function projectionValues2(input) {
|
|
2418
2547
|
return {
|
|
@@ -2577,39 +2706,39 @@ async function recordGitHubPullRequestLinkedIssues(db, input) {
|
|
|
2577
2706
|
}
|
|
2578
2707
|
|
|
2579
2708
|
// src/webhooks/issue-outcome.ts
|
|
2580
|
-
import { z as
|
|
2581
|
-
var canonicalIssueOutcomeSchema =
|
|
2582
|
-
action:
|
|
2583
|
-
issue:
|
|
2584
|
-
body:
|
|
2585
|
-
closed_at:
|
|
2586
|
-
created_at:
|
|
2587
|
-
id:
|
|
2588
|
-
number:
|
|
2709
|
+
import { z as z15 } from "zod";
|
|
2710
|
+
var canonicalIssueOutcomeSchema = z15.object({
|
|
2711
|
+
action: z15.enum(["opened", "closed", "reopened"]),
|
|
2712
|
+
issue: z15.object({
|
|
2713
|
+
body: z15.string().nullable().optional(),
|
|
2714
|
+
closed_at: z15.string().nullable().optional(),
|
|
2715
|
+
created_at: z15.string(),
|
|
2716
|
+
id: z15.number().int().positive(),
|
|
2717
|
+
number: z15.number().int().positive(),
|
|
2589
2718
|
state_reason: githubIssueStateReasonSchema.nullable().optional(),
|
|
2590
|
-
updated_at:
|
|
2591
|
-
user:
|
|
2719
|
+
updated_at: z15.string(),
|
|
2720
|
+
user: z15.object({ login: z15.string().min(1) }).strict()
|
|
2592
2721
|
}).strict(),
|
|
2593
|
-
repository:
|
|
2594
|
-
full_name:
|
|
2595
|
-
id:
|
|
2722
|
+
repository: z15.object({
|
|
2723
|
+
full_name: z15.string().min(1),
|
|
2724
|
+
id: z15.number().int().positive()
|
|
2596
2725
|
}).strict()
|
|
2597
2726
|
}).strict();
|
|
2598
|
-
var issueOutcomeSchema =
|
|
2599
|
-
action:
|
|
2600
|
-
issue:
|
|
2601
|
-
body:
|
|
2602
|
-
closed_at:
|
|
2603
|
-
created_at:
|
|
2604
|
-
id:
|
|
2605
|
-
number:
|
|
2727
|
+
var issueOutcomeSchema = z15.object({
|
|
2728
|
+
action: z15.enum(["opened", "closed", "reopened"]),
|
|
2729
|
+
issue: z15.object({
|
|
2730
|
+
body: z15.string().nullable().optional(),
|
|
2731
|
+
closed_at: z15.string().nullable().optional(),
|
|
2732
|
+
created_at: z15.string(),
|
|
2733
|
+
id: z15.number().int().positive(),
|
|
2734
|
+
number: z15.number().int().positive(),
|
|
2606
2735
|
state_reason: githubIssueStateReasonSchema.nullable().optional(),
|
|
2607
|
-
updated_at:
|
|
2608
|
-
user:
|
|
2736
|
+
updated_at: z15.string(),
|
|
2737
|
+
user: z15.object({ login: z15.string().min(1) }).passthrough()
|
|
2609
2738
|
}).passthrough(),
|
|
2610
|
-
repository:
|
|
2611
|
-
full_name:
|
|
2612
|
-
id:
|
|
2739
|
+
repository: z15.object({
|
|
2740
|
+
full_name: z15.string().min(1),
|
|
2741
|
+
id: z15.number().int().positive()
|
|
2613
2742
|
}).passthrough()
|
|
2614
2743
|
}).passthrough().transform(
|
|
2615
2744
|
(provider) => canonicalIssueOutcomeSchema.parse({
|
|
@@ -2630,7 +2759,7 @@ var issueOutcomeSchema = z14.object({
|
|
|
2630
2759
|
}
|
|
2631
2760
|
})
|
|
2632
2761
|
);
|
|
2633
|
-
var issueLifecycleActionSchema =
|
|
2762
|
+
var issueLifecycleActionSchema = z15.object({ action: z15.string() }).passthrough();
|
|
2634
2763
|
function timestamp2(value) {
|
|
2635
2764
|
if (!value) return void 0;
|
|
2636
2765
|
const parsed = new Date(value);
|
|
@@ -2676,21 +2805,21 @@ function normalizeGitHubIssueOutcome(args) {
|
|
|
2676
2805
|
updatedAt
|
|
2677
2806
|
};
|
|
2678
2807
|
}
|
|
2679
|
-
var canonicalIssueConversationSchema =
|
|
2680
|
-
issue:
|
|
2681
|
-
body:
|
|
2682
|
-
id:
|
|
2683
|
-
user:
|
|
2808
|
+
var canonicalIssueConversationSchema = z15.object({
|
|
2809
|
+
issue: z15.object({
|
|
2810
|
+
body: z15.string().nullable().optional(),
|
|
2811
|
+
id: z15.number().int().positive(),
|
|
2812
|
+
user: z15.object({ login: z15.string().min(1) }).strict()
|
|
2684
2813
|
}).strict(),
|
|
2685
|
-
sender:
|
|
2814
|
+
sender: z15.object({ login: z15.string().min(1) }).strict().optional()
|
|
2686
2815
|
}).strict();
|
|
2687
|
-
var issueConversationSchema =
|
|
2688
|
-
issue:
|
|
2689
|
-
body:
|
|
2690
|
-
id:
|
|
2691
|
-
user:
|
|
2816
|
+
var issueConversationSchema = z15.object({
|
|
2817
|
+
issue: z15.object({
|
|
2818
|
+
body: z15.string().nullable().optional(),
|
|
2819
|
+
id: z15.number().int().positive(),
|
|
2820
|
+
user: z15.object({ login: z15.string().min(1) }).passthrough()
|
|
2692
2821
|
}).passthrough(),
|
|
2693
|
-
sender:
|
|
2822
|
+
sender: z15.object({ login: z15.string().min(1) }).passthrough().optional()
|
|
2694
2823
|
}).passthrough().transform(
|
|
2695
2824
|
(provider) => canonicalIssueConversationSchema.parse({
|
|
2696
2825
|
issue: {
|
|
@@ -2717,43 +2846,43 @@ function normalizeGitHubIssueConversations(args) {
|
|
|
2717
2846
|
}
|
|
2718
2847
|
|
|
2719
2848
|
// src/webhooks/pull-request-outcome.ts
|
|
2720
|
-
import { z as
|
|
2721
|
-
var canonicalPullRequestOutcomeSchema =
|
|
2722
|
-
action:
|
|
2723
|
-
pull_request:
|
|
2724
|
-
body:
|
|
2725
|
-
closed_at:
|
|
2726
|
-
created_at:
|
|
2727
|
-
id:
|
|
2728
|
-
merged:
|
|
2729
|
-
merged_at:
|
|
2730
|
-
number:
|
|
2731
|
-
title:
|
|
2732
|
-
updated_at:
|
|
2733
|
-
user:
|
|
2849
|
+
import { z as z16 } from "zod";
|
|
2850
|
+
var canonicalPullRequestOutcomeSchema = z16.object({
|
|
2851
|
+
action: z16.enum(["opened", "closed", "reopened"]),
|
|
2852
|
+
pull_request: z16.object({
|
|
2853
|
+
body: z16.string().nullable().optional(),
|
|
2854
|
+
closed_at: z16.string().nullable().optional(),
|
|
2855
|
+
created_at: z16.string(),
|
|
2856
|
+
id: z16.number().int().positive(),
|
|
2857
|
+
merged: z16.boolean(),
|
|
2858
|
+
merged_at: z16.string().nullable().optional(),
|
|
2859
|
+
number: z16.number().int().positive(),
|
|
2860
|
+
title: z16.string().min(1).optional(),
|
|
2861
|
+
updated_at: z16.string(),
|
|
2862
|
+
user: z16.object({ login: z16.string().min(1) }).strict()
|
|
2734
2863
|
}).strict(),
|
|
2735
|
-
repository:
|
|
2736
|
-
full_name:
|
|
2737
|
-
id:
|
|
2864
|
+
repository: z16.object({
|
|
2865
|
+
full_name: z16.string().min(1),
|
|
2866
|
+
id: z16.number().int().positive()
|
|
2738
2867
|
}).strict()
|
|
2739
2868
|
}).strict();
|
|
2740
|
-
var pullRequestOutcomeSchema =
|
|
2741
|
-
action:
|
|
2742
|
-
pull_request:
|
|
2743
|
-
body:
|
|
2744
|
-
closed_at:
|
|
2745
|
-
created_at:
|
|
2746
|
-
id:
|
|
2747
|
-
merged:
|
|
2748
|
-
merged_at:
|
|
2749
|
-
number:
|
|
2750
|
-
title:
|
|
2751
|
-
updated_at:
|
|
2752
|
-
user:
|
|
2869
|
+
var pullRequestOutcomeSchema = z16.object({
|
|
2870
|
+
action: z16.enum(["opened", "closed", "reopened"]),
|
|
2871
|
+
pull_request: z16.object({
|
|
2872
|
+
body: z16.string().nullable().optional(),
|
|
2873
|
+
closed_at: z16.string().nullable().optional(),
|
|
2874
|
+
created_at: z16.string(),
|
|
2875
|
+
id: z16.number().int().positive(),
|
|
2876
|
+
merged: z16.boolean(),
|
|
2877
|
+
merged_at: z16.string().nullable().optional(),
|
|
2878
|
+
number: z16.number().int().positive(),
|
|
2879
|
+
title: z16.string().min(1).optional(),
|
|
2880
|
+
updated_at: z16.string(),
|
|
2881
|
+
user: z16.object({ login: z16.string().min(1) }).passthrough()
|
|
2753
2882
|
}).passthrough(),
|
|
2754
|
-
repository:
|
|
2755
|
-
full_name:
|
|
2756
|
-
id:
|
|
2883
|
+
repository: z16.object({
|
|
2884
|
+
full_name: z16.string().min(1),
|
|
2885
|
+
id: z16.number().int().positive()
|
|
2757
2886
|
}).passthrough()
|
|
2758
2887
|
}).passthrough().transform(
|
|
2759
2888
|
(provider) => canonicalPullRequestOutcomeSchema.parse({
|
|
@@ -2776,24 +2905,24 @@ var pullRequestOutcomeSchema = z15.object({
|
|
|
2776
2905
|
}
|
|
2777
2906
|
})
|
|
2778
2907
|
);
|
|
2779
|
-
var pullRequestLifecycleActionSchema =
|
|
2780
|
-
var canonicalPullRequestConversationSchema =
|
|
2781
|
-
pull_request:
|
|
2782
|
-
body:
|
|
2783
|
-
id:
|
|
2784
|
-
user:
|
|
2908
|
+
var pullRequestLifecycleActionSchema = z16.object({ action: z16.string() }).passthrough();
|
|
2909
|
+
var canonicalPullRequestConversationSchema = z16.object({
|
|
2910
|
+
pull_request: z16.object({
|
|
2911
|
+
body: z16.string().nullable().optional(),
|
|
2912
|
+
id: z16.number().int().positive(),
|
|
2913
|
+
user: z16.object({ login: z16.string().min(1) }).strict()
|
|
2785
2914
|
}).strict(),
|
|
2786
|
-
repository:
|
|
2787
|
-
sender:
|
|
2915
|
+
repository: z16.object({ full_name: z16.string().min(1) }).strict(),
|
|
2916
|
+
sender: z16.object({ login: z16.string().min(1) }).strict()
|
|
2788
2917
|
}).strict();
|
|
2789
|
-
var pullRequestConversationSchema =
|
|
2790
|
-
pull_request:
|
|
2791
|
-
body:
|
|
2792
|
-
id:
|
|
2793
|
-
user:
|
|
2918
|
+
var pullRequestConversationSchema = z16.object({
|
|
2919
|
+
pull_request: z16.object({
|
|
2920
|
+
body: z16.string().nullable().optional(),
|
|
2921
|
+
id: z16.number().int().positive(),
|
|
2922
|
+
user: z16.object({ login: z16.string().min(1) }).passthrough()
|
|
2794
2923
|
}).passthrough(),
|
|
2795
|
-
repository:
|
|
2796
|
-
sender:
|
|
2924
|
+
repository: z16.object({ full_name: z16.string().min(1) }).passthrough(),
|
|
2925
|
+
sender: z16.object({ login: z16.string().min(1) }).passthrough()
|
|
2797
2926
|
}).passthrough().transform(
|
|
2798
2927
|
(provider) => canonicalPullRequestConversationSchema.parse({
|
|
2799
2928
|
pull_request: {
|
|
@@ -3075,18 +3204,18 @@ function createGitHubWebhookRoute(args) {
|
|
|
3075
3204
|
}
|
|
3076
3205
|
|
|
3077
3206
|
// src/pull-request-outcomes/commit-composition.ts
|
|
3078
|
-
import { z as
|
|
3079
|
-
var canonicalCommitSchema =
|
|
3080
|
-
authorEmail:
|
|
3081
|
-
authorLogin:
|
|
3207
|
+
import { z as z17 } from "zod";
|
|
3208
|
+
var canonicalCommitSchema = z17.object({
|
|
3209
|
+
authorEmail: z17.string().nullable(),
|
|
3210
|
+
authorLogin: z17.string().nullable()
|
|
3082
3211
|
}).strict();
|
|
3083
|
-
var providerCommitSchema =
|
|
3084
|
-
author:
|
|
3085
|
-
commit:
|
|
3086
|
-
author:
|
|
3212
|
+
var providerCommitSchema = z17.object({
|
|
3213
|
+
author: z17.object({ login: z17.string() }).passthrough().nullable(),
|
|
3214
|
+
commit: z17.object({
|
|
3215
|
+
author: z17.object({ email: z17.string() }).passthrough().nullable()
|
|
3087
3216
|
}).passthrough()
|
|
3088
3217
|
}).passthrough();
|
|
3089
|
-
var commitPageSchema =
|
|
3218
|
+
var commitPageSchema = z17.array(providerCommitSchema).transform(
|
|
3090
3219
|
(commits) => commits.map(
|
|
3091
3220
|
(commit) => canonicalCommitSchema.parse({
|
|
3092
3221
|
authorEmail: commit.commit.author?.email ?? null,
|
|
@@ -3965,6 +4094,13 @@ var GITHUB_BODY_WRITES = [
|
|
|
3965
4094
|
operation: "github.pull.create",
|
|
3966
4095
|
restPath: /^\/repos\/[^/]+\/[^/]+\/pulls$/
|
|
3967
4096
|
},
|
|
4097
|
+
{
|
|
4098
|
+
denialMessage: `GitHub pull request reviews must use the github_submitPullRequestReview tool. The tool posts to /repos/{owner}/{repo}/pulls/{number}/reviews. ${CREATE_TOOL_ROUTING_GUIDANCE}`,
|
|
4099
|
+
graphqlField: "addPullRequestReview",
|
|
4100
|
+
method: "POST",
|
|
4101
|
+
operation: "github.pull.review.create",
|
|
4102
|
+
restPath: /^\/repos\/[^/]+\/[^/]+\/pulls\/[^/]+\/reviews$/
|
|
4103
|
+
},
|
|
3968
4104
|
{
|
|
3969
4105
|
denialMessage: `GitHub issue updates must use the github_updateIssue tool so Junior can own requester attribution and the conversation footer. ${CREATE_TOOL_ROUTING_GUIDANCE}`,
|
|
3970
4106
|
graphqlField: "updateIssue",
|
|
@@ -4087,7 +4223,7 @@ function requireRepositoryTarget(upstreamUrl) {
|
|
|
4087
4223
|
return;
|
|
4088
4224
|
}
|
|
4089
4225
|
throw new EgressPolicyDenied2(
|
|
4090
|
-
"GitHub write request
|
|
4226
|
+
"GitHub write request has no repository in its URL. Use a /repos/{owner}/{repo}/... URL or a GitHub tool for the operation."
|
|
4091
4227
|
);
|
|
4092
4228
|
}
|
|
4093
4229
|
async function githubGrantForEgress(ctx) {
|
|
@@ -4154,7 +4290,7 @@ async function githubGrantForEgress(ctx) {
|
|
|
4154
4290
|
if (graphqlAccess) {
|
|
4155
4291
|
if (graphqlAccess === "write") {
|
|
4156
4292
|
throw new EgressPolicyDenied2(
|
|
4157
|
-
"GitHub GraphQL mutations are not enabled for runtime credentials."
|
|
4293
|
+
"GitHub GraphQL mutations are not enabled for runtime credentials. Use the matching GitHub tool or a supported REST endpoint. For pull request reviews, use github_submitPullRequestReview. It posts to /repos/{owner}/{repo}/pulls/{number}/reviews."
|
|
4158
4294
|
);
|
|
4159
4295
|
}
|
|
4160
4296
|
return grantForAccess(
|
|
@@ -4166,7 +4302,7 @@ async function githubGrantForEgress(ctx) {
|
|
|
4166
4302
|
const access = HTTP_READ_METHODS.has(method) ? "read" : "write";
|
|
4167
4303
|
if (access === "write") {
|
|
4168
4304
|
throw new EgressPolicyDenied2(
|
|
4169
|
-
"GitHub write request
|
|
4305
|
+
"Junior does not support this GitHub write request. Use the matching GitHub tool or a supported REST endpoint."
|
|
4170
4306
|
);
|
|
4171
4307
|
}
|
|
4172
4308
|
return grantForAccess(access, "github.api-read", "installation-read");
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type PluginEgress } from "@sentry/junior-plugin-api";
|
|
2
|
+
/** Submit a comment or change-request review through GitHub's REST API. */
|
|
3
|
+
export declare function createGitHubSubmitPullRequestReviewTool(egress: PluginEgress): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
4
|
+
repo: string;
|
|
5
|
+
number: number;
|
|
6
|
+
event: "COMMENT" | "REQUEST_CHANGES";
|
|
7
|
+
body: string;
|
|
8
|
+
comments?: {
|
|
9
|
+
path: string;
|
|
10
|
+
body: string;
|
|
11
|
+
line: number;
|
|
12
|
+
side: "LEFT" | "RIGHT";
|
|
13
|
+
startLine?: number | undefined;
|
|
14
|
+
startSide?: "LEFT" | "RIGHT" | undefined;
|
|
15
|
+
}[] | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
[x: string]: unknown;
|
|
18
|
+
target: "submitPullRequestReview";
|
|
19
|
+
repo: string;
|
|
20
|
+
number: number;
|
|
21
|
+
reviewId: number;
|
|
22
|
+
state: string;
|
|
23
|
+
url: string;
|
|
24
|
+
truncated?: boolean | undefined;
|
|
25
|
+
continuation?: {
|
|
26
|
+
arguments: Record<string, unknown>;
|
|
27
|
+
reason?: string | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
[x: string]: unknown;
|
|
31
|
+
target: "submitPullRequestReview";
|
|
32
|
+
repo: string;
|
|
33
|
+
number: number;
|
|
34
|
+
reviewId: number;
|
|
35
|
+
state: string;
|
|
36
|
+
url: string;
|
|
37
|
+
truncated?: boolean | undefined;
|
|
38
|
+
continuation?: {
|
|
39
|
+
arguments: Record<string, unknown>;
|
|
40
|
+
reason?: string | undefined;
|
|
41
|
+
} | undefined;
|
|
42
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.200.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@sinclair/typebox": "^0.34.49",
|
|
32
32
|
"drizzle-orm": "^0.45.2",
|
|
33
33
|
"zod": "^4.5.4",
|
|
34
|
-
"@sentry/junior-plugin-api": "0.
|
|
34
|
+
"@sentry/junior-plugin-api": "0.200.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@oxlint/plugins": "1.79.0",
|
|
@@ -3,36 +3,37 @@ name: github-code
|
|
|
3
3
|
description: Work with GitHub repositories, source code, branches, commits, pull requests, reviews, diffs, CI, and repository credentials. Use for implementation, source investigation, clone/fetch/branch workflows, PR creation or updates, review feedback, GitHub Actions checks, and repository permission failures. Prefer this skill for repository tasks even when they concern a Sentry product.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# GitHub
|
|
6
|
+
# GitHub code
|
|
7
7
|
|
|
8
8
|
Use `git` and `gh` for repository work.
|
|
9
9
|
|
|
10
|
-
| Action
|
|
11
|
-
|
|
|
12
|
-
| Create PR
|
|
13
|
-
| Update PR title/body/base/state | `github_updatePullRequest`
|
|
14
|
-
|
|
|
15
|
-
|
|
|
10
|
+
| Action | Tool / command |
|
|
11
|
+
| ------------------------------- | ------------------------------------------------------------------------ |
|
|
12
|
+
| Create PR | `github_createPullRequest` (not `gh pr create`) |
|
|
13
|
+
| Update PR title/body/base/state | `github_updatePullRequest` |
|
|
14
|
+
| Submit PR review | `github_submitPullRequestReview` |
|
|
15
|
+
| Resolve review thread | `github_resolvePullRequestReviewThread` |
|
|
16
|
+
| Clone missing repo | `github_cloneRepository`; on Workspace match error use `switchWorkspace` |
|
|
16
17
|
|
|
17
18
|
## Open when needed
|
|
18
19
|
|
|
19
|
-
| Need
|
|
20
|
-
|
|
|
21
|
-
| Commands
|
|
22
|
-
| Edit
|
|
23
|
-
|
|
|
20
|
+
| Need | Read |
|
|
21
|
+
| ----------------------------- | -------------------------------------------------------------------------------------- |
|
|
22
|
+
| Commands and permissions | [references/api-surface.md](references/api-surface.md) |
|
|
23
|
+
| Edit, verify, and open a PR | [references/workflow.md](references/workflow.md) |
|
|
24
|
+
| Command or permission failure | [references/troubleshooting-workarounds.md](references/troubleshooting-workarounds.md) |
|
|
24
25
|
|
|
25
26
|
## Always
|
|
26
27
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- Read applicable `AGENTS.md` before
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
- Push
|
|
33
|
-
-
|
|
34
|
-
- Stop for
|
|
35
|
-
- Unless the user opts out,
|
|
36
|
-
- Report
|
|
37
|
-
|
|
38
|
-
Do not install or repair the GitHub plugin
|
|
28
|
+
- Use the requested repo. Otherwise read `github.repo` with standalone `jr-rpc config get github.repo`.
|
|
29
|
+
- Pass `--repo owner/repo` to `gh`. Use `git -C PATH` for local repos.
|
|
30
|
+
- Read each applicable `AGENTS.md` before edits.
|
|
31
|
+
- Keep unrelated work. Never force-push, delete refs, or make destructive merges.
|
|
32
|
+
- Use repository evidence. Report only checks you ran.
|
|
33
|
+
- Push before `github_createPullRequest`. Never ask for a token for bot pushes.
|
|
34
|
+
- When an error names a tool, use it. Change permissions only when GitHub rejected the request.
|
|
35
|
+
- Stop for an unclear target, missing access, destructive work, or a GitHub permission failure.
|
|
36
|
+
- Unless the user opts out, push completed work and open a draft PR.
|
|
37
|
+
- Report repo, branch, PR, checks, and skipped checks.
|
|
38
|
+
|
|
39
|
+
Do not install or repair the GitHub plugin from this skill.
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
# GitHub
|
|
1
|
+
# GitHub commands and permissions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use the tools in `SKILL.md` to create or update a PR, submit a review, or resolve a review thread. Use supported REST endpoints for other writes. Do not use GraphQL mutations.
|
|
4
4
|
|
|
5
5
|
## Repo targeting
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
If the user omits `owner/repo`, run `jr-rpc config get github.repo`. Then pass `--repo owner/repo` to `gh`.
|
|
8
8
|
|
|
9
9
|
## Permissions
|
|
10
10
|
|
|
11
|
-
| Capability
|
|
12
|
-
|
|
|
13
|
-
| `github.actions.read`
|
|
14
|
-
| `github.actions.write`
|
|
15
|
-
| `github.contents.read`
|
|
16
|
-
| `github.contents.write`
|
|
17
|
-
| `github.workflows.write`
|
|
18
|
-
| `github.pull-requests.read`
|
|
19
|
-
| `github.pull-requests.write` |
|
|
11
|
+
| Capability | Commands |
|
|
12
|
+
| ---------------------------- | ------------------------------------------------------------------------------------ |
|
|
13
|
+
| `github.actions.read` | `gh run list`, `gh run view`, `gh run watch`, `gh workflow list`, `gh workflow view` |
|
|
14
|
+
| `github.actions.write` | `gh workflow run`, `gh run rerun`, `gh run cancel` |
|
|
15
|
+
| `github.contents.read` | `gh repo clone`, `git fetch` |
|
|
16
|
+
| `github.contents.write` | Git smart-HTTP `git push` only |
|
|
17
|
+
| `github.workflows.write` | Workflow-file changes on push |
|
|
18
|
+
| `github.pull-requests.read` | `gh pr view`, `gh pr list`, `gh pr diff`, `gh pr checks` |
|
|
19
|
+
| `github.pull-requests.write` | GitHub tools and supported REST writes |
|
|
20
20
|
|
|
21
21
|
## Commands
|
|
22
22
|
|
|
23
|
-
| Operation
|
|
24
|
-
|
|
|
25
|
-
| Clone (default shallow) | `gh repo clone owner/repo [DIR] -- --depth=1`
|
|
26
|
-
| Fetch bounded base
|
|
27
|
-
| Deepen base
|
|
28
|
-
| Unshallow
|
|
29
|
-
| Shallow check
|
|
30
|
-
| Branch / status
|
|
31
|
-
| Log / diff vs base
|
|
32
|
-
| Default branch
|
|
33
|
-
| Create branch
|
|
34
|
-
| Commit
|
|
35
|
-
| Push
|
|
36
|
-
| Workflow dispatch
|
|
37
|
-
| Rerun / cancel
|
|
38
|
-
| Ready for review
|
|
39
|
-
| Request reviewers
|
|
40
|
-
| Submit review
|
|
41
|
-
| Inline review comment
|
|
42
|
-
| View PR / checks
|
|
43
|
-
| Diff PR
|
|
44
|
-
| List runs
|
|
45
|
-
| View / watch run
|
|
23
|
+
| Operation | Command |
|
|
24
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------- |
|
|
25
|
+
| Clone (default shallow) | `gh repo clone owner/repo [DIR] -- --depth=1` |
|
|
26
|
+
| Fetch bounded base | `git -C DIR fetch --depth=N origin BASE:refs/remotes/origin/BASE` |
|
|
27
|
+
| Deepen base | `git -C DIR fetch --deepen=N origin BASE:refs/remotes/origin/BASE` |
|
|
28
|
+
| Unshallow | `git -C DIR fetch --unshallow origin` |
|
|
29
|
+
| Shallow check | `git -C DIR rev-parse --is-shallow-repository` |
|
|
30
|
+
| Branch / status | `git -C DIR branch --show-current` / `git -C DIR status --short --branch` |
|
|
31
|
+
| Log / diff vs base | `git -C DIR log origin/BASE..HEAD --oneline` / `git -C DIR diff origin/BASE...HEAD` |
|
|
32
|
+
| Default branch | `gh repo view owner/repo --json defaultBranchRef --jq .defaultBranchRef.name` |
|
|
33
|
+
| Create branch | `git -C DIR checkout -b BRANCH` |
|
|
34
|
+
| Commit | `git -C DIR add -A && git -C DIR commit -m "message"` |
|
|
35
|
+
| Push | `git -C DIR push -u origin BRANCH` |
|
|
36
|
+
| Workflow dispatch | `gh workflow run WORKFLOW --repo owner/repo --ref REF [-f key=value]` |
|
|
37
|
+
| Rerun / cancel | `gh run rerun RUN_ID -R owner/repo [--failed]` / `gh run cancel RUN_ID -R owner/repo` |
|
|
38
|
+
| Ready for review | `gh api repos/owner/repo/pulls/NUMBER/ready_for_review --method POST` |
|
|
39
|
+
| Request reviewers | `gh api repos/owner/repo/pulls/NUMBER/requested_reviewers --method POST --input reviewers.json` |
|
|
40
|
+
| Submit review | `github_submitPullRequestReview` |
|
|
41
|
+
| Inline review comment | `gh api repos/owner/repo/pulls/NUMBER/comments --method POST --input comment.json` |
|
|
42
|
+
| View PR / checks | `gh pr view NUMBER --repo owner/repo` / `gh pr checks NUMBER --repo owner/repo` |
|
|
43
|
+
| Diff PR | `gh pr diff NUMBER --repo owner/repo` |
|
|
44
|
+
| List runs | `gh run list -R owner/repo --workflow WORKFLOW` |
|
|
45
|
+
| View / watch run | `gh run view RUN_ID -R owner/repo` / `gh run watch RUN_ID -R owner/repo --exit-status` |
|
|
46
46
|
|
|
47
47
|
## Notes
|
|
48
48
|
|
|
49
49
|
- Prefer `--json` where available. Pass clone flags after `--`.
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
- Push head and
|
|
53
|
-
-
|
|
54
|
-
- Reviews and inline comments
|
|
50
|
+
- A local commit does not call GitHub. A push uses installation credentials. Workflow changes also need `workflows.write`.
|
|
51
|
+
- Deepen a shallow clone before work that needs old history. Do not force-push to work around missing history.
|
|
52
|
+
- Push `head` and read the default `base` before `github_createPullRequest`.
|
|
53
|
+
- Junior does not support merges, forks, repository administration, REST content or Git database writes, direct PR update or review writes, or GraphQL mutations.
|
|
54
|
+
- Reviews and inline comments use the App bot.
|
|
55
55
|
- PR comments/labels/assignees use issue endpoints; load `github-issues` for those.
|
|
56
56
|
- Embed local images with `publishImage` first (public URL). Do not use private Slack file links.
|
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
# GitHub
|
|
1
|
+
# GitHub troubleshooting
|
|
2
2
|
|
|
3
|
-
|
|
|
4
|
-
|
|
|
5
|
-
| `
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
| 401
|
|
11
|
-
| `
|
|
12
|
-
|
|
|
13
|
-
| `
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
| `dnf install gh failed` | Plugin bootstrap | Report runtime bootstrap failure; do not repair from skill |
|
|
3
|
+
| Problem | Action |
|
|
4
|
+
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
5
|
+
| `gh` reports an unknown command | Report that the GitHub plugin is unavailable. Do not install it. |
|
|
6
|
+
| Clone rejects `--depth` | Put clone flags after `--`: `gh repo clone owner/repo -- --depth=1`. |
|
|
7
|
+
| Repository is missing or wrong | Read `github.repo`, then pass `--repo owner/repo`. |
|
|
8
|
+
| GraphQL cannot find the repository | Check `owner/repo` and the GitHub App installation. |
|
|
9
|
+
| `junior-auth-required` with `user-write` | Follow the private OAuth prompt. Never ask for a pasted token. |
|
|
10
|
+
| `git push` returns 401 or 403 | Check the remote and repository. Retry once, then report the installation access failure. |
|
|
11
|
+
| `permission_denied` has `source: "upstream"` | GitHub rejected the request. Report the grant, account, or SSO details. |
|
|
12
|
+
| Other 403 response | Read the error and use the tool it names. |
|
|
13
|
+
| `gh auth status` shows no token scopes | This is normal for GitHub App user tokens. Check App permissions instead. |
|
|
14
|
+
| `github_createPullRequest` returns 401 or 403 | Report the installation access failure. Do not use user OAuth. |
|
|
15
|
+
| PR creation returns 422 for `head` | Push the branch, then retry with explicit `head` and `base`. |
|
|
16
|
+
| PR create or update returns 422 for `base` | Read the default branch, then retry. |
|
|
17
|
+
| 403 names `github_updatePullRequest` | Use `github_updatePullRequest`. |
|
|
18
|
+
| PR review reports blocked GraphQL mutations | Use `github_submitPullRequestReview`. |
|
|
19
|
+
| Review-thread resolution reports blocked GraphQL mutations | Use `github_resolvePullRequestReviewThread`. It works only on bot-authored PRs. |
|
|
20
|
+
| Blame or old history is missing | Deepen the needed refs. Unshallow only when required. |
|
|
21
|
+
| Rebase has missing ancestry | Fetch `BASE:refs/remotes/origin/BASE`, deepen it, and use `origin/BASE`. |
|
|
22
|
+
| Dependencies are missing | Run the frozen install. Do not change the lockfile. |
|
|
23
|
+
| Frozen install fails | Report the exact failure. |
|
|
24
|
+
| Plugin setup fails | Report the setup failure. Do not repair it from the skill. |
|
|
26
25
|
|
|
27
26
|
## Retry rules
|
|
28
27
|
|
|
29
|
-
- Retry
|
|
30
|
-
- Do not
|
|
31
|
-
- `user-read
|
|
32
|
-
-
|
|
33
|
-
-
|
|
28
|
+
- Retry a transport failure once after you check the repository.
|
|
29
|
+
- Do not repeat 401, 403, 404, or validation failures.
|
|
30
|
+
- A `user-read` or `user-write` failure needs private App OAuth.
|
|
31
|
+
- An `installation-*` failure needs an App permission or installation fix.
|
|
32
|
+
- Use structured `permission_denied` details when present.
|