@sentry/junior-github 0.249.0 → 0.250.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/SETUP.md CHANGED
@@ -164,11 +164,9 @@ Use `additionalUserScopes` only when a human-identity integration flow requires
164
164
 
165
165
  Run as a regular sandbox `bash` command while the relevant skill is active:
166
166
 
167
- Clone a repository with a shallow checkout by default:
168
-
169
- ```bash
170
- gh repo clone owner/repo -- --depth=1
171
- ```
167
+ Clone a repository with the `github_cloneRepository` tool. It makes a shallow
168
+ checkout. It first checks for a matching Workspace. Do not use `git clone` or
169
+ `gh repo clone`, because they skip that check.
172
170
 
173
171
  Deepen later only if the task needs more history:
174
172
 
@@ -104,6 +104,20 @@ function gitHubPullRequestEventGuidance(guidance) {
104
104
  }
105
105
  return merged;
106
106
  }
107
+ var GITHUB_PULL_REQUEST_OUTCOME_GUIDANCE = {
108
+ "pull_request.review.approved": "Mention each person in People involved, or the person who asked for the pull request if that line is missing. Say who approved it and link it. Do not merge it unless asked.",
109
+ "pull_request.merged": "Mention each person in People involved, or the person who asked for the pull request if that line is missing. Say that it merged and link it."
110
+ };
111
+ function gitHubPullRequestCreateWatch(config) {
112
+ const outcomeEvents = Object.keys(
113
+ GITHUB_PULL_REQUEST_OUTCOME_GUIDANCE
114
+ );
115
+ return {
116
+ events: [.../* @__PURE__ */ new Set([...config.events, ...outcomeEvents])],
117
+ guidance: GITHUB_PULL_REQUEST_OUTCOME_GUIDANCE,
118
+ intent: config.intent
119
+ };
120
+ }
107
121
  var GITHUB_PULL_REQUEST_SUGGESTED_EVENTS = [
108
122
  "pull_request.checks.failed",
109
123
  "pull_request.comment.created",
@@ -1910,6 +1924,7 @@ export {
1910
1924
  gitHubDeploymentSourceSubscribable,
1911
1925
  GITHUB_PULL_REQUEST_EVENTS,
1912
1926
  gitHubPullRequestEventGuidance,
1927
+ gitHubPullRequestCreateWatch,
1913
1928
  GITHUB_PULL_REQUEST_SUGGESTED_EVENTS,
1914
1929
  GITHUB_PULL_REQUEST_MATCH_FIELDS,
1915
1930
  GITHUB_PULL_REQUEST_IDENTIFIER,
@@ -15,6 +15,12 @@ export interface GitHubPullRequestSubscriptionConfig {
15
15
  events: GitHubPullRequestEvent[];
16
16
  intent: string;
17
17
  }
18
+ /** Build the Watch created after Junior creates a pull request. */
19
+ export declare function gitHubPullRequestCreateWatch(config: GitHubPullRequestSubscriptionConfig): {
20
+ events: GitHubPullRequestEvent[];
21
+ guidance: Partial<Record<GitHubPullRequestEvent, string>>;
22
+ intent: string;
23
+ };
18
24
  export declare const GITHUB_PULL_REQUEST_SUGGESTED_EVENTS: readonly ["pull_request.checks.failed", "pull_request.comment.created", "pull_request.ready_for_review", "pull_request.review.changes_requested", "pull_request.review.commented", "pull_request.review_comment.created", "pull_request.merged", "pull_request.closed_unmerged"];
19
25
  /** Exact values GitHub may set on pull request event data. Missing keys do not match. */
20
26
  export declare const GITHUB_PULL_REQUEST_MATCH_FIELDS: Record<string, {
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  credentialUnavailable,
31
31
  gitHubDeploymentSourceSubscribable,
32
32
  gitHubIssueSubscribable,
33
+ gitHubPullRequestCreateWatch,
33
34
  gitHubPullRequestEventGuidance,
34
35
  gitHubPullRequestSubscribable,
35
36
  gitHubReleaseSourceSubscribable,
@@ -51,7 +52,7 @@ import {
51
52
  readGrantPermissions,
52
53
  requireEnv,
53
54
  resolveUserAccount
54
- } from "./chunk-EYBKPQTJ.js";
55
+ } from "./chunk-D75O3CY3.js";
55
56
 
56
57
  // src/plugin.ts
57
58
  import {
@@ -1447,17 +1448,17 @@ async function gitHubPullRequestStructuredResult(ctx, input, result, subscriptio
1447
1448
  ...base
1448
1449
  };
1449
1450
  }
1451
+ const watch = gitHubPullRequestCreateWatch(subscriptionConfig);
1450
1452
  try {
1451
1453
  const subscription = await ctx.events.subscribe({
1452
- events: subscriptionConfig.events,
1453
- intent: subscriptionConfig.intent,
1454
+ ...watch,
1454
1455
  resource: base.subscribable
1455
1456
  });
1456
1457
  const data = gitHubPullRequestToolResult(
1457
1458
  input,
1458
1459
  result,
1459
1460
  ctx.events.canSubscribe,
1460
- subscriptionConfig.events
1461
+ watch.events
1461
1462
  );
1462
1463
  return {
1463
1464
  objectAnnotations,
@@ -3518,6 +3519,102 @@ function normalizeGitHubPullRequestLinkedIssues(args) {
3518
3519
  } : void 0;
3519
3520
  }
3520
3521
 
3522
+ // src/webhooks/pull-request-people.ts
3523
+ import { z as z19 } from "zod";
3524
+ var PEOPLE_EVENTS = /* @__PURE__ */ new Set([
3525
+ "pull_request.review.approved",
3526
+ "pull_request.merged"
3527
+ ]);
3528
+ var MAX_PEOPLE = 20;
3529
+ var PAGE_SIZE = 100;
3530
+ var MAX_PAGES = 3;
3531
+ var CO_AUTHOR_TRAILER = /^co-authored-by:[^<\n]*<([^>\s]+@[^>\s]+)>\s*$/gim;
3532
+ var GITHUB_NOREPLY_EMAIL = /^(?:\d+\+)?(?<login>[^@+]+)@users\.noreply\.github\.com$/i;
3533
+ var webhookSchema = z19.object({
3534
+ pull_request: z19.object({
3535
+ assignees: z19.array(z19.object({ login: z19.string().min(1) })).nullish(),
3536
+ number: z19.number(),
3537
+ user: z19.object({ login: z19.string().min(1) }).nullish()
3538
+ }),
3539
+ repository: z19.object({ full_name: z19.string().min(1) })
3540
+ });
3541
+ var commitPageSchema = z19.array(
3542
+ z19.object({
3543
+ author: z19.object({ login: z19.string().min(1) }).nullish(),
3544
+ commit: z19.object({ message: z19.string() })
3545
+ })
3546
+ );
3547
+ async function loadGitHubPullRequestPeople(args) {
3548
+ const people = /* @__PURE__ */ new Map();
3549
+ const addLogin = (login) => {
3550
+ if (/\[bot\]$/i.test(login)) return;
3551
+ const key = `github:${login.toLowerCase()}`;
3552
+ if (!people.has(key))
3553
+ people.set(key, { provider: "github", handle: login });
3554
+ };
3555
+ const addEmail = (value) => {
3556
+ const email = value.toLowerCase();
3557
+ const login = GITHUB_NOREPLY_EMAIL.exec(email)?.groups?.login;
3558
+ if (login) addLogin(login);
3559
+ else if (!people.has(`email:${email}`)) {
3560
+ people.set(`email:${email}`, { email });
3561
+ }
3562
+ };
3563
+ args.logins.forEach(addLogin);
3564
+ for (let page = 1; page <= MAX_PAGES; page += 1) {
3565
+ const commits = commitPageSchema.parse(
3566
+ await args.loadPage(page, PAGE_SIZE)
3567
+ );
3568
+ for (const commit of commits) {
3569
+ if (commit.author) addLogin(commit.author.login);
3570
+ for (const match of commit.commit.message.matchAll(CO_AUTHOR_TRAILER)) {
3571
+ addEmail(match[1]);
3572
+ }
3573
+ }
3574
+ if (commits.length < PAGE_SIZE) break;
3575
+ }
3576
+ return [...people.values()].slice(0, MAX_PEOPLE);
3577
+ }
3578
+ async function withGitHubPullRequestPeople(args) {
3579
+ const { hasMatch } = args;
3580
+ const peopleEvents = args.events.filter(
3581
+ (event) => PEOPLE_EVENTS.has(event.eventType)
3582
+ );
3583
+ const parsed = webhookSchema.safeParse(args.body);
3584
+ if (peopleEvents.length === 0 || !hasMatch || !args.load || !parsed.success) {
3585
+ return args.events;
3586
+ }
3587
+ const matches = await Promise.all(
3588
+ peopleEvents.map((event) => hasMatch(event))
3589
+ );
3590
+ if (!matches.some(Boolean)) return args.events;
3591
+ const { pull_request: pullRequest, repository } = parsed.data;
3592
+ const target = {
3593
+ logins: [
3594
+ ...pullRequest.user ? [pullRequest.user.login] : [],
3595
+ ...(pullRequest.assignees ?? []).map((assignee) => assignee.login)
3596
+ ],
3597
+ number: pullRequest.number,
3598
+ repositoryFullName: repository.full_name
3599
+ };
3600
+ let people;
3601
+ try {
3602
+ people = await args.load(target);
3603
+ } catch (error) {
3604
+ args.log?.error("GitHub pull request people lookup failed", {
3605
+ deliveryId: args.deliveryId,
3606
+ errorType: error instanceof Error ? error.name : "UnknownError",
3607
+ number: target.number,
3608
+ repository: target.repositoryFullName
3609
+ });
3610
+ return args.events;
3611
+ }
3612
+ if (people.length === 0) return args.events;
3613
+ return args.events.map(
3614
+ (event) => PEOPLE_EVENTS.has(event.eventType) ? { ...event, people } : event
3615
+ );
3616
+ }
3617
+
3521
3618
  // src/webhooks/handler.ts
3522
3619
  function verifyGitHubSignature(body, signature, secret) {
3523
3620
  if (!secret || !signature.startsWith("sha256=")) return false;
@@ -3710,15 +3807,22 @@ function createGitHubWebhookRoute(args) {
3710
3807
  log: args.log,
3711
3808
  privateKeyEnv: args.privateKeyEnv
3712
3809
  }) : void 0;
3713
- const events = normalizeGitHubEvents({
3810
+ const hasMatch = args.events.hasMatch;
3811
+ const events = await withGitHubPullRequestPeople({
3714
3812
  body,
3715
- botEmail,
3716
- ...checkSuiteFacts ? { checkSuiteFacts } : void 0,
3717
3813
  deliveryId,
3718
- eventName
3814
+ events: normalizeGitHubEvents({
3815
+ body,
3816
+ botEmail,
3817
+ ...checkSuiteFacts ? { checkSuiteFacts } : void 0,
3818
+ deliveryId,
3819
+ eventName
3820
+ }),
3821
+ hasMatch,
3822
+ load: args.loadPullRequestPeople,
3823
+ log: args.log
3719
3824
  });
3720
3825
  const feedbackTarget = pullRequestFeedbackTarget(events);
3721
- const hasMatch = args.events.hasMatch;
3722
3826
  const feedbackHasMatch = feedbackTarget && hasMatch ? (await Promise.all(events.map((event) => hasMatch(event)))).some(
3723
3827
  Boolean
3724
3828
  ) : false;
@@ -3749,18 +3853,18 @@ function createGitHubWebhookRoute(args) {
3749
3853
  }
3750
3854
 
3751
3855
  // src/pull-request-outcomes/commit-composition.ts
3752
- import { z as z19 } from "zod";
3753
- var canonicalCommitSchema = z19.object({
3754
- authorEmail: z19.string().nullable(),
3755
- authorLogin: z19.string().nullable()
3856
+ import { z as z20 } from "zod";
3857
+ var canonicalCommitSchema = z20.object({
3858
+ authorEmail: z20.string().nullable(),
3859
+ authorLogin: z20.string().nullable()
3756
3860
  }).strict();
3757
- var providerCommitSchema = z19.object({
3758
- author: z19.object({ login: z19.string() }).passthrough().nullable(),
3759
- commit: z19.object({
3760
- author: z19.object({ email: z19.string() }).passthrough().nullable()
3861
+ var providerCommitSchema = z20.object({
3862
+ author: z20.object({ login: z20.string() }).passthrough().nullable(),
3863
+ commit: z20.object({
3864
+ author: z20.object({ email: z20.string() }).passthrough().nullable()
3761
3865
  }).passthrough()
3762
3866
  }).passthrough();
3763
- var commitPageSchema = z19.array(providerCommitSchema).transform(
3867
+ var commitPageSchema2 = z20.array(providerCommitSchema).transform(
3764
3868
  (commits) => commits.map(
3765
3869
  (commit) => canonicalCommitSchema.parse({
3766
3870
  authorEmail: commit.commit.author?.email ?? null,
@@ -3768,8 +3872,8 @@ var commitPageSchema = z19.array(providerCommitSchema).transform(
3768
3872
  })
3769
3873
  )
3770
3874
  );
3771
- var PAGE_SIZE = 100;
3772
- var MAX_PAGES = 3;
3875
+ var PAGE_SIZE2 = 100;
3876
+ var MAX_PAGES2 = 3;
3773
3877
  var MAX_LISTED_COMMITS = 250;
3774
3878
  async function classifyGitHubPullRequestCommitComposition(args) {
3775
3879
  const botEmail = args.botEmail.trim().toLowerCase();
@@ -3780,9 +3884,9 @@ async function classifyGitHubPullRequestCommitComposition(args) {
3780
3884
  }
3781
3885
  let foundCommit = false;
3782
3886
  let inspectedCommits = 0;
3783
- for (let page = 1; page <= MAX_PAGES; page += 1) {
3784
- const commits = commitPageSchema.parse(
3785
- await args.loadPage(page, PAGE_SIZE)
3887
+ for (let page = 1; page <= MAX_PAGES2; page += 1) {
3888
+ const commits = commitPageSchema2.parse(
3889
+ await args.loadPage(page, PAGE_SIZE2)
3786
3890
  );
3787
3891
  inspectedCommits += commits.length;
3788
3892
  for (const commit of commits) {
@@ -3793,8 +3897,8 @@ async function classifyGitHubPullRequestCommitComposition(args) {
3793
3897
  }
3794
3898
  }
3795
3899
  if (inspectedCommits >= MAX_LISTED_COMMITS) return void 0;
3796
- if (commits.length < PAGE_SIZE) break;
3797
- if (page === MAX_PAGES) return void 0;
3900
+ if (commits.length < PAGE_SIZE2) break;
3901
+ if (page === MAX_PAGES2) return void 0;
3798
3902
  }
3799
3903
  return foundCommit ? "junior_only" : void 0;
3800
3904
  }
@@ -4918,41 +5022,43 @@ function githubPlugin(options = {}) {
4918
5022
  };
4919
5023
  },
4920
5024
  routes(ctx) {
5025
+ const loadPullRequestCommitPage = async (pullRequest) => {
5026
+ const [owner, name, ...extra] = pullRequest.repositoryFullName.split("/");
5027
+ if (!owner || !name || extra.length > 0) {
5028
+ throw new Error(
5029
+ "GitHub pull request commits received an invalid repository name"
5030
+ );
5031
+ }
5032
+ const token = await issueInstallationToken({
5033
+ appIdEnv,
5034
+ privateKeyEnv,
5035
+ installationIdEnv,
5036
+ permissions: { pull_requests: "read" },
5037
+ repositories: [name]
5038
+ });
5039
+ return async (page, perPage) => await githubRequest(
5040
+ "https://api.github.com",
5041
+ `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/pulls/${pullRequest.number}/commits?per_page=${perPage}&page=${page}`,
5042
+ { token: token.token }
5043
+ );
5044
+ };
4921
5045
  return [
4922
5046
  createGitHubWebhookRoute({
4923
5047
  annotations: ctx.annotations,
4924
5048
  appIdEnv,
4925
5049
  botEmail: () => readEnv(botEmailEnv),
4926
- classifyPullRequestCommits: async ({
4927
- number,
4928
- repositoryFullName
4929
- }) => {
4930
- const [owner, name, ...extra] = repositoryFullName.split("/");
4931
- if (!owner || !name || extra.length > 0) {
4932
- throw new Error(
4933
- "GitHub pull request commit classification received an invalid repository name"
4934
- );
4935
- }
4936
- const token = await issueInstallationToken({
4937
- appIdEnv,
4938
- privateKeyEnv,
4939
- installationIdEnv,
4940
- permissions: { pull_requests: "read" },
4941
- repositories: [name]
4942
- });
4943
- return await classifyGitHubPullRequestCommitComposition({
4944
- botEmail: requireEnv(botEmailEnv),
4945
- loadPage: async (page, perPage) => await githubRequest(
4946
- "https://api.github.com",
4947
- `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/pulls/${number}/commits?per_page=${perPage}&page=${page}`,
4948
- { token: token.token }
4949
- )
4950
- });
4951
- },
5050
+ classifyPullRequestCommits: async (pullRequest) => await classifyGitHubPullRequestCommitComposition({
5051
+ botEmail: requireEnv(botEmailEnv),
5052
+ loadPage: await loadPullRequestCommitPage(pullRequest)
5053
+ }),
4952
5054
  codeChanges: ctx.codeChanges,
4953
5055
  db: ctx.db,
4954
5056
  installationId: () => readEnv(installationIdEnv),
4955
5057
  installationIdEnv,
5058
+ loadPullRequestPeople: async (pullRequest) => await loadGitHubPullRequestPeople({
5059
+ logins: pullRequest.logins,
5060
+ loadPage: await loadPullRequestCommitPage(pullRequest)
5061
+ }),
4956
5062
  log: ctx.log,
4957
5063
  markFeedbackReviewing: async ({ commentId, commentKind, repo }) => {
4958
5064
  const [owner, name, ...extra] = repo.split("/");
package/dist/testing.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  normalizeGitHubEvents
3
- } from "./chunk-EYBKPQTJ.js";
3
+ } from "./chunk-D75O3CY3.js";
4
4
  export {
5
5
  normalizeGitHubEvents
6
6
  };
@@ -1,6 +1,7 @@
1
- import type { CodeChangePublisher, PluginConversationAnnotations, PluginLogger, PluginRoute, EventPublisher } from "@sentry/junior-plugin-api";
1
+ import type { CodeChangePublisher, PluginConversationAnnotations, PluginLogger, PluginRoute, EventPerson, EventPublisher } from "@sentry/junior-plugin-api";
2
2
  import type { GitHubDb } from "../db/database.js";
3
3
  import type { GitHubPullRequestCommitComposition } from "../db/schema.js";
4
+ import { type GitHubPullRequestPeopleTarget } from "./pull-request-people.js";
4
5
  interface FeedbackTarget {
5
6
  commentId: number;
6
7
  commentKind: "conversation" | "review";
@@ -19,6 +20,8 @@ export declare function createGitHubWebhookRoute(args: {
19
20
  db: GitHubDb;
20
21
  installationId(): string | undefined;
21
22
  installationIdEnv: string;
23
+ /** Load the people involved in a pull request for approvals and merges. */
24
+ loadPullRequestPeople?(target: GitHubPullRequestPeopleTarget): Promise<EventPerson[]>;
22
25
  log?: Pick<PluginLogger, "error">;
23
26
  markFeedbackReviewing(input: FeedbackTarget): Promise<void>;
24
27
  privateKeyEnv: string;
@@ -0,0 +1,31 @@
1
+ import type { EventInput, EventPerson, EventPublisher, PluginLogger } from "@sentry/junior-plugin-api";
2
+ /** The pull request that a people lookup reads. */
3
+ export interface GitHubPullRequestPeopleTarget {
4
+ /** Pull request author and assignees from the webhook. */
5
+ logins: string[];
6
+ number: number;
7
+ repositoryFullName: string;
8
+ }
9
+ /**
10
+ * Collect the people involved in a pull request: the webhook logins, commit
11
+ * authors, and `Co-authored-by` trailers. Junior adds a trailer for each
12
+ * person whose instructions a run accepted, so people who steer later are
13
+ * included. Noreply emails become logins. `[bot]` accounts are skipped.
14
+ */
15
+ export declare function loadGitHubPullRequestPeople(args: {
16
+ logins: readonly string[];
17
+ loadPage(page: number, perPage: number): Promise<unknown>;
18
+ }): Promise<EventPerson[]>;
19
+ /**
20
+ * Add the people involved to approval and merge events. It loads them only
21
+ * when a Watch or event automation matches, so other deliveries make no extra
22
+ * GitHub calls. People only add context, so a failed load keeps the events.
23
+ */
24
+ export declare function withGitHubPullRequestPeople(args: {
25
+ body: unknown;
26
+ deliveryId: string;
27
+ events: EventInput[];
28
+ hasMatch: EventPublisher["hasMatch"];
29
+ load?(target: GitHubPullRequestPeopleTarget): Promise<EventPerson[]>;
30
+ log?: Pick<PluginLogger, "error">;
31
+ }): Promise<EventInput[]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-github",
3
- "version": "0.249.0",
3
+ "version": "0.250.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.249.0"
34
+ "@sentry/junior-plugin-api": "0.250.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@oxlint/plugins": "1.79.0",
@@ -7,14 +7,14 @@ description: Work with GitHub repositories, source code, branches, commits, pull
7
7
 
8
8
  Use `git` and `gh` for repository work.
9
9
 
10
- | Action | Tool / command |
11
- | ------------------------------- | ------------------------------------------------------------------------ |
12
- | Create PR | `github_createPullRequest` (not `gh pr create`) |
13
- | Update PR title/body/base/state | `github_updatePullRequest` |
14
- | Mark PR ready / draft | `github_updatePullRequest` with `draft: false` / `draft: true` |
15
- | Submit PR review | `github_submitPullRequestReview` |
16
- | Resolve review thread | `github_resolvePullRequestReviewThread` |
17
- | Clone missing repo | `github_cloneRepository`; on Workspace match error use `switchWorkspace` |
10
+ | Action | Tool / command |
11
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------- |
12
+ | Create PR | `github_createPullRequest` (not `gh pr create`) |
13
+ | Update PR title/body/base/state | `github_updatePullRequest` |
14
+ | Mark PR ready / draft | `github_updatePullRequest` with `draft: false` / `draft: true` |
15
+ | Submit PR review | `github_submitPullRequestReview` |
16
+ | Resolve review thread | `github_resolvePullRequestReviewThread` |
17
+ | Clone missing repo | `github_cloneRepository` (not `git clone` or `gh repo clone`); on Workspace match error use `switchWorkspace` |
18
18
 
19
19
  ## Open when needed
20
20
 
@@ -12,7 +12,7 @@ If the user omits `owner/repo`, run `jr-rpc config get github.repo`. Then pass `
12
12
  | ---------------------------- | ------------------------------------------------------------------------------------ |
13
13
  | `github.actions.read` | `gh run list`, `gh run view`, `gh run watch`, `gh workflow list`, `gh workflow view` |
14
14
  | `github.actions.write` | `gh workflow run`, `gh run rerun`, `gh run cancel` |
15
- | `github.contents.read` | `gh repo clone`, `git fetch` |
15
+ | `github.contents.read` | `github_cloneRepository`, `git fetch` |
16
16
  | `github.contents.write` | Git smart-HTTP `git push` only |
17
17
  | `github.workflows.write` | Workflow-file changes on push |
18
18
  | `github.pull-requests.read` | `gh pr view`, `gh pr list`, `gh pr diff`, `gh pr checks` |
@@ -22,7 +22,7 @@ If the user omits `owner/repo`, run `jr-rpc config get github.repo`. Then pass `
22
22
 
23
23
  | Operation | Command |
24
24
  | ----------------------- | ----------------------------------------------------------------------------------------------- |
25
- | Clone (default shallow) | `gh repo clone owner/repo [DIR] -- --depth=1` |
25
+ | Clone (default shallow) | `github_cloneRepository`. Do not use `git clone` or `gh repo clone`. |
26
26
  | Fetch bounded base | `git -C DIR fetch --depth=N origin BASE:refs/remotes/origin/BASE` |
27
27
  | Deepen base | `git -C DIR fetch --deepen=N origin BASE:refs/remotes/origin/BASE` |
28
28
  | Unshallow | `git -C DIR fetch --unshallow origin` |
@@ -51,7 +51,7 @@ If the user omits `owner/repo`, run `jr-rpc config get github.repo`. Then pass `
51
51
 
52
52
  ## Notes
53
53
 
54
- - Prefer `--json` where available. Pass clone flags after `--`.
54
+ - Prefer `--json` where available.
55
55
  - A local commit does not call GitHub. A push uses installation credentials. Workflow changes also need `workflows.write`.
56
56
  - Deepen a shallow clone before work that needs old history. Do not force-push to work around missing history.
57
57
  - Push `head` and read the default `base` before `github_createPullRequest`.
@@ -3,7 +3,6 @@
3
3
  | Problem | Action |
4
4
  | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
5
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
6
  | Repository is missing or wrong | Read `github.repo`, then pass `--repo owner/repo`. |
8
7
  | GraphQL cannot find the repository | Check `owner/repo` and the GitHub App installation. |
9
8
  | `junior-auth-required` with `user-write` | Follow the private OAuth prompt. Never ask for a pasted token. |
@@ -5,7 +5,7 @@ Open this when making repository edits, not for read-only inspection.
5
5
  ## Resolve and inspect
6
6
 
7
7
  1. Identify repo, checkout, branches, worktree, package manager, and relevant checks.
8
- 2. Prefer an existing checkout or matching Workspace; otherwise clone shallowly.
8
+ 2. Prefer an existing checkout or matching Workspace; otherwise clone with `github_cloneRepository`.
9
9
  3. If clone returns a Workspace match error, switch Workspace or pass `allowAdHoc=true`.
10
10
  4. Shallow clones are for fast inspection. Before rebase, merge-base, blame, or base comparison, fetch/deepen the needed refs. Never force-push around missing history.
11
11
  5. For edits, pick the smallest credible validation path. Capture a baseline when a failure may be pre-existing.