@sentry/junior-github 0.206.0 → 0.208.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/README.md CHANGED
@@ -26,7 +26,7 @@ export const plugins = defineJuniorPlugins([
26
26
  Full setup guide: https://junior.sentry.dev/extend/github-plugin/
27
27
 
28
28
  The plugin owns its signed webhook route, deployment, pull request, and release
29
- resource events, and normalized pull request and issue outcome projections.
29
+ events, and normalized pull request and issue outcome projections.
30
30
  Those projections also feed native code-change records used by the dashboard
31
31
  Code page and person profiles. Core only owns delivery from plugin-published
32
- resource events into matching conversation subscriptions.
32
+ events into matching conversation subscriptions.
package/SETUP.md CHANGED
@@ -155,7 +155,7 @@ Use `additionalUserScopes` only when a human-identity integration flow requires
155
155
  - When either GitHub skill is active, authenticated `gh` and `git` commands cause the runtime to inject GitHub credentials automatically for the current turn.
156
156
  - The plugin classifies GitHub traffic from the forwarded HTTP request. Reads use `installation-read`, while `GET /user` uses `user-read`. Allowlisted App-owned mutations and Git smart-HTTP pushes use `installation-write`. User-attachment uploads to `uploads.github.com/user-attachments/assets` use `user-write`. Unknown REST writes and GraphQL mutations are denied.
157
157
  - `user-read` and explicitly human `user-write` operations require the actor, or an explicitly delegated user subject, to authorize the GitHub App through the private OAuth flow. Junior-owned issue, pull request, review, inline review comment, and branch operations do not fall back to user OAuth.
158
- - Headless resource-event turns use the `resource-event` system actor and may receive the same installation grants. This lets Junior respond to subscribed pull request events by committing and pushing fixes without inheriting a subscriber's OAuth credential.
158
+ - Headless event turns use the `event` system actor and may receive the same installation grants. This lets Junior respond to subscribed pull request events by committing and pushing fixes without inheriting a subscriber's OAuth credential.
159
159
  - Git commits use Junior as author and committer. Resolvable human run actors are credited once with `Co-Authored-By` trailers. When the current actor has a linked GitHub identity, Junior prefers a GitHub noreply address so external automation can resolve a login for assignment.
160
160
  - Installation credential leases are cached on the host by grant name and reused across sandboxes until near expiry. User grants stay actor-scoped. Upstream 403 after injection clears the cached lease, issues a new token, and retries the hop once before recording permission denied.
161
161
  - Sandbox does not receive raw tokens via env; host applies Authorization header transforms for GitHub API and upload calls.
@@ -1,7 +1,7 @@
1
- // src/webhooks/resource-events.ts
1
+ // src/webhooks/events.ts
2
2
  import { z as z2 } from "zod";
3
3
 
4
- // src/resource-events/deployment.ts
4
+ // src/events/deployment.ts
5
5
  var GITHUB_DEPLOYMENT_EVENTS = [
6
6
  "deployment.created",
7
7
  "deployment.queued",
@@ -36,7 +36,7 @@ function gitHubDeploymentSourceSubscribable(input) {
36
36
  };
37
37
  }
38
38
 
39
- // src/resource-events/issue.ts
39
+ // src/events/issue.ts
40
40
  var GITHUB_ISSUE_EVENTS = [
41
41
  "issue.comment.created",
42
42
  "issue.opened",
@@ -65,9 +65,9 @@ function gitHubIssueSubscribable(input) {
65
65
  };
66
66
  }
67
67
 
68
- // src/resource-events/pull-request.ts
68
+ // src/events/pull-request.ts
69
69
  import {
70
- resourceEventMatchFieldsSchema
70
+ eventMatchFieldsSchema
71
71
  } from "@sentry/junior-plugin-api";
72
72
  var GITHUB_PULL_REQUEST_EVENTS = [
73
73
  "pull_request.checks.failed",
@@ -106,7 +106,7 @@ var GITHUB_PULL_REQUEST_SUGGESTED_EVENTS = [
106
106
  "pull_request.merged",
107
107
  "pull_request.closed_unmerged"
108
108
  ];
109
- var GITHUB_PULL_REQUEST_MATCH_FIELDS = resourceEventMatchFieldsSchema.parse({
109
+ var GITHUB_PULL_REQUEST_MATCH_FIELDS = eventMatchFieldsSchema.parse({
110
110
  authorEmail: {
111
111
  kind: "string",
112
112
  description: "pull request author email when GitHub sends it"
@@ -145,7 +145,7 @@ function gitHubPullRequestSubscribable(input) {
145
145
  };
146
146
  }
147
147
 
148
- // src/resource-events/release.ts
148
+ // src/events/release.ts
149
149
  var GITHUB_RELEASE_EVENTS = ["release.published"];
150
150
  var GITHUB_RELEASE_SUGGESTED_EVENTS = ["release.published"];
151
151
  function gitHubReleaseSourceResource(input) {
@@ -167,7 +167,7 @@ function gitHubReleaseSourceSubscribable(input) {
167
167
  };
168
168
  }
169
169
 
170
- // src/resource-events/repository.ts
170
+ // src/events/repository.ts
171
171
  function gitHubRepositoryResource(input) {
172
172
  return {
173
173
  label: `GitHub repository ${input.repo}`,
@@ -921,7 +921,7 @@ function checkSuiteHeadBranch(value) {
921
921
  const branch = value?.trim();
922
922
  return branch ? branch : void 0;
923
923
  }
924
- function buildCheckSuiteResourceEvent(args) {
924
+ function buildCheckSuiteEvent(args) {
925
925
  const pullRequestNumber = args.pullRequestNumber;
926
926
  const resource = pullRequestNumber === void 0 ? gitHubRepositoryResource({ repo: args.repo }) : gitHubPullRequestResource({
927
927
  number: pullRequestNumber,
@@ -1037,7 +1037,7 @@ function normalizeCheckSuiteEvents(deliveryId, body, options) {
1037
1037
  );
1038
1038
  if (sameRepoPullRequests.length === 0) {
1039
1039
  return [
1040
- buildCheckSuiteResourceEvent({
1040
+ buildCheckSuiteEvent({
1041
1041
  ...shared,
1042
1042
  ...headBranch ? { headBranch } : void 0
1043
1043
  })
@@ -1047,7 +1047,7 @@ function normalizeCheckSuiteEvents(deliveryId, body, options) {
1047
1047
  const facts = options?.pullRequestFactsByNumber?.[pullRequest.number];
1048
1048
  const pullRequestHeadBranch = checkSuiteHeadBranch(pullRequest.head?.ref) ?? headBranch;
1049
1049
  return pullRequestTargets(
1050
- buildCheckSuiteResourceEvent({
1050
+ buildCheckSuiteEvent({
1051
1051
  ...shared,
1052
1052
  ...facts?.authorEmail ? { authorEmail: facts.authorEmail } : void 0,
1053
1053
  ...facts?.authorUsername ? { authorUsername: facts.authorUsername } : void 0,
@@ -1070,7 +1070,8 @@ function parseCheckSuitePublishTargets(body) {
1070
1070
  gitHubRepositoryResource({ repo }).identifier
1071
1071
  ]);
1072
1072
  for (const pullRequest of parsed.data.check_suite.pull_requests) {
1073
- if (!isCheckSuiteRepositoryPullRequest(pullRequest, repository.id)) continue;
1073
+ if (!isCheckSuiteRepositoryPullRequest(pullRequest, repository.id))
1074
+ continue;
1074
1075
  identifiers.add(
1075
1076
  gitHubPullRequestResource({ number: pullRequest.number, repo }).identifier
1076
1077
  );
@@ -1223,7 +1224,7 @@ async function loadCheckSuiteFacts(args) {
1223
1224
  return facts.failingChecks || facts.pullRequestFactsByNumber ? facts : void 0;
1224
1225
  }
1225
1226
 
1226
- // src/webhooks/resource-events.ts
1227
+ // src/webhooks/events.ts
1227
1228
  function gitHubEventKey2(deliveryId, eventType) {
1228
1229
  return `github:${deliveryId}:${eventType}`;
1229
1230
  }
@@ -1799,7 +1800,7 @@ function normalizeReleaseEvent(deliveryId, body) {
1799
1800
  })
1800
1801
  );
1801
1802
  }
1802
- function normalizeGitHubResourceEvents(args) {
1803
+ function normalizeGitHubEvents(args) {
1803
1804
  switch (args.eventName) {
1804
1805
  case "deployment":
1805
1806
  return normalizeDeploymentEvent(args.deliveryId, args.body);
@@ -1872,5 +1873,5 @@ export {
1872
1873
  parseCheckSuitePublishTargets,
1873
1874
  needsCheckSuitePullRequestFacts,
1874
1875
  loadCheckSuiteFacts,
1875
- normalizeGitHubResourceEvents
1876
+ normalizeGitHubEvents
1876
1877
  };
@@ -3,9 +3,9 @@ export declare const GITHUB_PULL_REQUEST_EVENTS: readonly ["pull_request.checks.
3
3
  export type GitHubPullRequestEvent = (typeof GITHUB_PULL_REQUEST_EVENTS)[number];
4
4
  /** Combine provider defaults with app guidance for pull request events. */
5
5
  export declare function gitHubPullRequestEventGuidance(guidance?: Partial<Record<GitHubPullRequestEvent, string>>): Partial<Record<GitHubPullRequestEvent, string>>;
6
- /** App-configured pull request resource event behavior. */
6
+ /** App-configured pull request event behavior. */
7
7
  export interface GitHubPullRequestEventOptions {
8
- /** App guidance applied within the matching subscription or event task instruction. */
8
+ /** App guidance applied within the matching subscription or event automation instruction. */
9
9
  guidance?: Partial<Record<GitHubPullRequestEvent, string>>;
10
10
  /** Temporary subscription created after Junior creates a pull request. */
11
11
  subscribeAfterCreate?: GitHubPullRequestSubscriptionConfig;
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  issueUserCredential,
36
36
  loadCheckSuiteFacts,
37
37
  needsCheckSuitePullRequestFacts,
38
- normalizeGitHubResourceEvents,
38
+ normalizeGitHubEvents,
39
39
  normalizePermissions,
40
40
  normalizeScopeList,
41
41
  parseCheckSuitePublishTargets,
@@ -43,7 +43,7 @@ import {
43
43
  readGrantPermissions,
44
44
  requireEnv,
45
45
  resolveUserAccount
46
- } from "./chunk-F2PJG6AF.js";
46
+ } from "./chunk-XP2336UO.js";
47
47
 
48
48
  // src/plugin.ts
49
49
  import {
@@ -703,7 +703,7 @@ function createGitHubIssueTool(ctx) {
703
703
  return gitHubIssueToolResult(
704
704
  completedInput,
705
705
  completedResult,
706
- ctx.resourceEvents.canSubscribe
706
+ ctx.events.canSubscribe
707
707
  );
708
708
  }
709
709
  if (state?.status === "pending") {
@@ -746,7 +746,7 @@ function createGitHubIssueTool(ctx) {
746
746
  return gitHubIssueToolResult(
747
747
  parsedInput,
748
748
  result,
749
- ctx.resourceEvents.canSubscribe
749
+ ctx.events.canSubscribe
750
750
  );
751
751
  } catch (error) {
752
752
  if (isEgressAuthRequired(error) || isDefinitiveGitHubIssueCreateRejection(error)) {
@@ -942,7 +942,7 @@ function createGitHubGetDeploymentTool(ctx) {
942
942
  url: `https://github.com/${repo.ref}/deployments`
943
943
  };
944
944
  }
945
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubDeploymentSourceSubscribable({
945
+ const subscribable = ctx.events.canSubscribe ? gitHubDeploymentSourceSubscribable({
946
946
  commitSha,
947
947
  environment: input.environment,
948
948
  repo: repo.ref
@@ -968,7 +968,7 @@ import {
968
968
  EgressAuthRequired as EgressAuthRequired2,
969
969
  PluginToolInputError as PluginToolInputError5,
970
970
  pluginToolOutputSchema as pluginToolOutputSchema4,
971
- resourceEventSubscriptionResultSchema,
971
+ watchResultSchema,
972
972
  subscribableResourceSchema as subscribableResourceSchema3
973
973
  } from "@sentry/junior-plugin-api";
974
974
  import { Type as Type2 } from "@sinclair/typebox";
@@ -1045,7 +1045,7 @@ var gitHubPullRequestDataSchema = z4.object({
1045
1045
  number: z4.number(),
1046
1046
  url: z4.string(),
1047
1047
  subscribable: subscribableResourceSchema3.optional(),
1048
- subscription: resourceEventSubscriptionResultSchema.optional()
1048
+ subscription: watchResultSchema.optional()
1049
1049
  });
1050
1050
  var gitHubPullRequestOutputSchema = pluginToolOutputSchema4.merge(
1051
1051
  gitHubPullRequestDataSchema.extend({
@@ -1223,7 +1223,7 @@ async function gitHubPullRequestStructuredResult(ctx, input, result, subscriptio
1223
1223
  const base = gitHubPullRequestToolResult(
1224
1224
  input,
1225
1225
  result,
1226
- ctx.resourceEvents.canSubscribe
1226
+ ctx.events.canSubscribe
1227
1227
  );
1228
1228
  if (!subscriptionConfig || !base.subscribable) {
1229
1229
  return {
@@ -1232,7 +1232,7 @@ async function gitHubPullRequestStructuredResult(ctx, input, result, subscriptio
1232
1232
  };
1233
1233
  }
1234
1234
  try {
1235
- const subscription = await ctx.resourceEvents.subscribe({
1235
+ const subscription = await ctx.events.subscribe({
1236
1236
  events: subscriptionConfig.events,
1237
1237
  intent: subscriptionConfig.intent,
1238
1238
  resource: base.subscribable
@@ -1240,7 +1240,7 @@ async function gitHubPullRequestStructuredResult(ctx, input, result, subscriptio
1240
1240
  const data = gitHubPullRequestToolResult(
1241
1241
  input,
1242
1242
  result,
1243
- ctx.resourceEvents.canSubscribe,
1243
+ ctx.events.canSubscribe,
1244
1244
  subscriptionConfig.events
1245
1245
  );
1246
1246
  return {
@@ -1408,7 +1408,7 @@ function createGitHubGetPullRequestTool(ctx) {
1408
1408
  openWorldHint: true,
1409
1409
  readOnlyHint: true
1410
1410
  },
1411
- description: "Get a GitHub pull request. Use this when an existing PR may need resource-event monitoring; the result includes a subscribable hint when GitHub webhooks are configured.",
1411
+ description: "Get a GitHub pull request. Use this when an existing PR may need event monitoring; the result includes a subscribable hint when GitHub webhooks are configured.",
1412
1412
  inputSchema: inputSchema3,
1413
1413
  outputSchema: outputSchema3,
1414
1414
  async execute(input) {
@@ -1444,7 +1444,7 @@ function createGitHubGetPullRequestTool(ctx) {
1444
1444
  state: z5.string(),
1445
1445
  title: z5.string()
1446
1446
  }).parse(parsed);
1447
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubPullRequestSubscribable({
1447
+ const subscribable = ctx.events.canSubscribe ? gitHubPullRequestSubscribable({
1448
1448
  number: providerResult.number,
1449
1449
  repo: repo.ref
1450
1450
  }) : void 0;
@@ -1606,7 +1606,7 @@ function createGitHubGetReleaseTool(ctx) {
1606
1606
  );
1607
1607
  }
1608
1608
  }
1609
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubReleaseSourceSubscribable({
1609
+ const subscribable = ctx.events.canSubscribe ? gitHubReleaseSourceSubscribable({
1610
1610
  repo: repo.ref,
1611
1611
  tag
1612
1612
  }) : void 0;
@@ -1672,7 +1672,7 @@ function createGitHubGetRepositoryTool(ctx) {
1672
1672
  openWorldHint: true,
1673
1673
  readOnlyHint: true
1674
1674
  },
1675
- description: "Get a GitHub repository. Use this when repository-wide issue activity may need resource-event monitoring; the result includes a subscribable hint when GitHub webhooks are configured.",
1675
+ description: "Get a GitHub repository. Use this when repository-wide issue activity may need event monitoring; the result includes a subscribable hint when GitHub webhooks are configured.",
1676
1676
  inputSchema: inputSchema5,
1677
1677
  outputSchema: outputSchema5,
1678
1678
  async execute(input) {
@@ -1703,7 +1703,7 @@ function createGitHubGetRepositoryTool(ctx) {
1703
1703
  html_url: z7.string(),
1704
1704
  private: z7.boolean()
1705
1705
  }).parse(parsed);
1706
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubRepositorySubscribable({
1706
+ const subscribable = ctx.events.canSubscribe ? gitHubRepositorySubscribable({
1707
1707
  repo: providerResult.full_name
1708
1708
  }) : void 0;
1709
1709
  const data = {
@@ -1843,7 +1843,7 @@ function createGitHubUpdateIssueTool(ctx) {
1843
1843
  state: z8.string(),
1844
1844
  title: z8.string()
1845
1845
  }).parse(parsed);
1846
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubIssueSubscribable({
1846
+ const subscribable = ctx.events.canSubscribe ? gitHubIssueSubscribable({
1847
1847
  number: providerResult.number,
1848
1848
  repo: repo.ref
1849
1849
  }) : void 0;
@@ -1990,7 +1990,7 @@ function createGitHubUpdatePullRequestTool(ctx) {
1990
1990
  state: z9.string(),
1991
1991
  title: z9.string()
1992
1992
  }).parse(parsed);
1993
- const subscribable = ctx.resourceEvents.canSubscribe ? gitHubPullRequestSubscribable({
1993
+ const subscribable = ctx.events.canSubscribe ? gitHubPullRequestSubscribable({
1994
1994
  number: providerResult.number,
1995
1995
  repo: repo.ref
1996
1996
  }) : void 0;
@@ -2108,7 +2108,7 @@ function createGitHubUpdatePullRequestFeedbackTool(ctx, botEmail) {
2108
2108
  openWorldHint: true,
2109
2109
  readOnlyHint: false
2110
2110
  },
2111
- description: "Set Junior's status reaction on GitHub pull request feedback: reviewing (eyes), addressed (+1), or declined (-1). Use the commentId and commentKind from the resource event. Replaces only Junior's prior status reaction on that comment.",
2111
+ description: "Set Junior's status reaction on GitHub pull request feedback: reviewing (eyes), addressed (+1), or declined (-1). Use the commentId and commentKind from the event. Replaces only Junior's prior status reaction on that comment.",
2112
2112
  exposure: "direct",
2113
2113
  inputSchema: inputSchema8,
2114
2114
  outputSchema: outputSchema8,
@@ -3400,7 +3400,7 @@ function createGitHubWebhookRoute(args) {
3400
3400
  pullRequestLinkedIssues
3401
3401
  ) : false;
3402
3402
  const checkSuitePublishTargets = eventName === "check_suite" ? parseCheckSuitePublishTargets(body) : void 0;
3403
- const checkSuiteMatchKeys = checkSuitePublishTargets && args.resourceEvents.neededMatchKeys ? await args.resourceEvents.neededMatchKeys(checkSuitePublishTargets) : [];
3403
+ const checkSuiteMatchKeys = checkSuitePublishTargets && args.events.neededMatchKeys ? await args.events.neededMatchKeys(checkSuitePublishTargets) : [];
3404
3404
  const checkSuiteFacts = eventName === "check_suite" ? await loadCheckSuiteFacts({
3405
3405
  appIdEnv: args.appIdEnv,
3406
3406
  body,
@@ -3409,15 +3409,17 @@ function createGitHubWebhookRoute(args) {
3409
3409
  log: args.log,
3410
3410
  privateKeyEnv: args.privateKeyEnv
3411
3411
  }) : void 0;
3412
- const resourceEvents = normalizeGitHubResourceEvents({
3412
+ const events = normalizeGitHubEvents({
3413
3413
  body,
3414
3414
  ...checkSuiteFacts ? { checkSuiteFacts } : void 0,
3415
3415
  deliveryId,
3416
3416
  eventName
3417
3417
  });
3418
- const feedbackTarget = pullRequestFeedbackTarget(resourceEvents);
3419
- const hasMatch = args.resourceEvents.hasMatch;
3420
- const feedbackHasMatch = feedbackTarget && hasMatch ? (await Promise.all(resourceEvents.map((event) => hasMatch(event)))).some(Boolean) : false;
3418
+ const feedbackTarget = pullRequestFeedbackTarget(events);
3419
+ const hasMatch = args.events.hasMatch;
3420
+ const feedbackHasMatch = feedbackTarget && hasMatch ? (await Promise.all(events.map((event) => hasMatch(event)))).some(
3421
+ Boolean
3422
+ ) : false;
3421
3423
  if (feedbackTarget && feedbackHasMatch) {
3422
3424
  try {
3423
3425
  await args.markFeedbackReviewing(feedbackTarget);
@@ -3430,10 +3432,10 @@ function createGitHubWebhookRoute(args) {
3430
3432
  });
3431
3433
  }
3432
3434
  }
3433
- for (const event of resourceEvents) {
3434
- await args.resourceEvents.publish(event);
3435
+ for (const event of events) {
3436
+ await args.events.publish(event);
3435
3437
  }
3436
- if (!pullRequestOutcome && !issueOutcome && !recordedIssueConversations && !recordedPullRequestConversations && !recordedPullRequestLinkedIssues && resourceEvents.length === 0) {
3438
+ if (!pullRequestOutcome && !issueOutcome && !recordedIssueConversations && !recordedPullRequestConversations && !recordedPullRequestLinkedIssues && events.length === 0) {
3437
3439
  return new Response("Ignored", { status: 202 });
3438
3440
  }
3439
3441
  return new Response("Accepted", { status: 202 });
@@ -3908,6 +3910,7 @@ async function prepareWorkspace(ctx) {
3908
3910
  GIT_CONFIG_GLOBAL: "/dev/null",
3909
3911
  GIT_CONFIG_NOSYSTEM: "1"
3910
3912
  };
3913
+ const finalize = [];
3911
3914
  for (const { owner, name, path, repo } of repos) {
3912
3915
  const parent = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) : void 0;
3913
3916
  if (parent) {
@@ -3943,7 +3946,9 @@ async function prepareWorkspace(ctx) {
3943
3946
  env: gitEnv
3944
3947
  }) : void 0;
3945
3948
  const detachedSha = detachedHead?.stdout.trim();
3946
- const validDetachedSha = detachedHead?.exitCode === 0 && detachedSha && /^[0-9a-f]{40,64}$/.test(detachedSha) ? detachedSha : void 0;
3949
+ const validDetachedHead = Boolean(
3950
+ detachedHead?.exitCode === 0 && detachedSha && /^[0-9a-f]{40,64}$/.test(detachedSha)
3951
+ );
3947
3952
  const upstream = branch?.exitCode === 0 && branchName ? await ctx.sandbox.run({
3948
3953
  cmd: "git",
3949
3954
  args: [
@@ -3959,91 +3964,23 @@ async function prepareWorkspace(ctx) {
3959
3964
  const upstreamRef = upstream?.stdout.trim();
3960
3965
  const upstreamPrefix = "refs/remotes/origin/";
3961
3966
  const upstreamBranch = upstreamRef?.startsWith(upstreamPrefix) ? upstreamRef.slice(upstreamPrefix.length) : void 0;
3962
- if (worktree.exitCode === 0 && (branchName || validDetachedSha)) {
3963
- const localBranch = branchName || "workspace-detached";
3964
- const remoteBranch = upstreamBranch || branchName;
3965
- const remoteRef = remoteBranch ? `${upstreamPrefix}${remoteBranch}` : validDetachedSha;
3966
- const tempDir = await ctx.sandbox.run({
3967
- cmd: "mktemp",
3968
- args: ["-d", `${ctx.sandbox.juniorRoot}/workspace-refresh.XXXXXX`],
3969
- cwd: ctx.sandbox.root
3970
- });
3971
- const refreshGitDir = tempDir.stdout.trim();
3972
- if (tempDir.exitCode !== 0 || !refreshGitDir) {
3973
- throw new Error(
3974
- `GitHub workspace refresh temp directory failed for ${repo}: ${tempDir.stderr.trim() || `exit ${tempDir.exitCode}`}`
3975
- );
3976
- }
3977
- for (const args of [
3978
- [
3979
- "--git-dir",
3980
- refreshGitDir,
3981
- "--work-tree",
3982
- path,
3983
- "init",
3984
- "--quiet",
3985
- "--initial-branch",
3986
- localBranch
3987
- ],
3988
- [
3989
- "--git-dir",
3990
- refreshGitDir,
3991
- "--work-tree",
3992
- path,
3993
- "remote",
3994
- "add",
3995
- "origin",
3996
- cloneUrl
3997
- ],
3998
- [
3999
- "--git-dir",
4000
- refreshGitDir,
4001
- "--work-tree",
4002
- path,
4003
- "fetch",
4004
- "--quiet",
4005
- "--prune",
4006
- "--tags",
4007
- "origin",
4008
- "+refs/heads/*:refs/remotes/origin/*",
4009
- ...validDetachedSha ? [validDetachedSha] : []
4010
- ],
4011
- ...validDetachedSha ? [
4012
- [
4013
- "--git-dir",
4014
- refreshGitDir,
4015
- "--work-tree",
4016
- path,
4017
- "update-ref",
4018
- "--no-deref",
4019
- "HEAD",
4020
- validDetachedSha
4021
- ]
4022
- ] : [],
4023
- [
4024
- "--git-dir",
4025
- refreshGitDir,
4026
- "--work-tree",
4027
- path,
4028
- "reset",
4029
- "--hard",
4030
- remoteRef
4031
- ],
4032
- ...remoteBranch && branchName ? [
4033
- [
4034
- "--git-dir",
4035
- refreshGitDir,
4036
- "--work-tree",
4037
- path,
4038
- "branch",
4039
- `--set-upstream-to=origin/${remoteBranch}`,
4040
- branchName
4041
- ]
4042
- ] : []
4043
- ]) {
3967
+ if (worktree.exitCode === 0 && (branchName || validDetachedHead)) {
3968
+ const target = upstreamBranch ? `${upstreamPrefix}${upstreamBranch}` : "HEAD";
3969
+ if (upstreamBranch) {
4044
3970
  const result2 = await ctx.sandbox.run({
4045
3971
  cmd: "git",
4046
- args,
3972
+ args: [
3973
+ "-c",
3974
+ "credential.helper=",
3975
+ "-C",
3976
+ path,
3977
+ "fetch",
3978
+ "--quiet",
3979
+ "--no-tags",
3980
+ "--no-recurse-submodules",
3981
+ cloneUrl,
3982
+ `+refs/heads/${upstreamBranch}:${target}`
3983
+ ],
4047
3984
  cwd: ctx.sandbox.root,
4048
3985
  env: gitEnv
4049
3986
  });
@@ -4053,32 +3990,7 @@ async function prepareWorkspace(ctx) {
4053
3990
  );
4054
3991
  }
4055
3992
  }
4056
- for (const [cmd, args] of [
4057
- ["rm", ["-rf", "--", `${path}/.git`]],
4058
- ["mv", ["--", refreshGitDir, `${path}/.git`]]
4059
- ]) {
4060
- const result2 = await ctx.sandbox.run({
4061
- cmd,
4062
- args: [...args],
4063
- cwd: ctx.sandbox.root
4064
- });
4065
- if (result2.exitCode !== 0) {
4066
- throw new Error(
4067
- `GitHub workspace metadata replacement failed for ${repo}: ${result2.stderr.trim() || `exit ${result2.exitCode}`}`
4068
- );
4069
- }
4070
- }
4071
- const clean = await ctx.sandbox.run({
4072
- cmd: "git",
4073
- args: ["-C", path, "clean", "-fd"],
4074
- cwd: ctx.sandbox.root,
4075
- env: gitEnv
4076
- });
4077
- if (clean.exitCode !== 0) {
4078
- throw new Error(
4079
- `GitHub workspace refresh failed for ${repo}: ${clean.stderr.trim() || `exit ${clean.exitCode}`}`
4080
- );
4081
- }
3993
+ finalize.push({ path, repo, target });
4082
3994
  continue;
4083
3995
  }
4084
3996
  const cleanup = await ctx.sandbox.run({
@@ -4102,7 +4014,28 @@ async function prepareWorkspace(ctx) {
4102
4014
  `GitHub workspace clone failed for ${repo}: ${result.stderr.trim() || `exit ${result.exitCode}`}`
4103
4015
  );
4104
4016
  }
4017
+ finalize.push({ path, repo, target: "HEAD" });
4105
4018
  }
4019
+ return async () => {
4020
+ for (const { path, repo, target } of finalize) {
4021
+ for (const args of [
4022
+ ["-C", path, "reset", "--hard", target],
4023
+ ["-C", path, "clean", "-fd"]
4024
+ ]) {
4025
+ const result = await ctx.sandbox.run({
4026
+ cmd: "git",
4027
+ args,
4028
+ cwd: ctx.sandbox.root,
4029
+ env: gitEnv
4030
+ });
4031
+ if (result.exitCode !== 0) {
4032
+ throw new Error(
4033
+ `GitHub workspace refresh failed for ${repo}: ${result.stderr.trim() || `exit ${result.exitCode}`}`
4034
+ );
4035
+ }
4036
+ }
4037
+ }
4038
+ };
4106
4039
  }
4107
4040
 
4108
4041
  // src/egress-policy.ts
@@ -4576,7 +4509,7 @@ function githubPlugin(options = {}) {
4576
4509
  const userScope = userScopes.length ? userScopes.join(" ") : void 0;
4577
4510
  return defineJuniorPlugin({
4578
4511
  packageName: "@sentry/junior-github",
4579
- resourceEvents: {
4512
+ events: {
4580
4513
  resourceTypes: [
4581
4514
  {
4582
4515
  type: "deployment_source",
@@ -4770,7 +4703,7 @@ function githubPlugin(options = {}) {
4770
4703
  );
4771
4704
  },
4772
4705
  privateKeyEnv,
4773
- resourceEvents: ctx.resourceEvents,
4706
+ events: ctx.events,
4774
4707
  webhookSecret: () => readEnv("GITHUB_WEBHOOK_SECRET")
4775
4708
  })
4776
4709
  ];
package/dist/plugin.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * GitHub plugin runtime boundary.
3
3
  *
4
- * This module composes GitHub hooks, resource events, and credentials.
4
+ * This module composes GitHub hooks, events, and credentials.
5
5
  */
6
6
  import { type PluginRegistration } from "@sentry/junior-plugin-api";
7
7
  import { type GitHubAppPermissions } from "./permissions.js";
8
- import { type GitHubPullRequestEventOptions } from "./resource-events/pull-request.js";
8
+ import { type GitHubPullRequestEventOptions } from "./events/pull-request.js";
9
9
  /** Configure the built-in GitHub plugin manifest and hooks. */
10
10
  export interface GitHubPluginOptions {
11
11
  /**
@@ -40,7 +40,7 @@ export interface GitHubPluginOptions {
40
40
  installationIdEnv?: string;
41
41
  /** Environment variable containing the GitHub App private key. */
42
42
  privateKeyEnv?: string;
43
- /** App-configured pull request resource event behavior. */
43
+ /** App-configured pull request event behavior. */
44
44
  pullRequestEvents?: GitHubPullRequestEventOptions;
45
45
  }
46
46
  /** Register GitHub runtime hooks for repository workflows. */
package/dist/testing.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Test-only access to GitHub webhook normalization for runtime eval fixtures. */
2
- export { normalizeGitHubResourceEvents } from "./webhooks/resource-events.js";
2
+ export { normalizeGitHubEvents } from "./webhooks/events.js";
package/dist/testing.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
- normalizeGitHubResourceEvents
3
- } from "./chunk-F2PJG6AF.js";
2
+ normalizeGitHubEvents
3
+ } from "./chunk-XP2336UO.js";
4
4
  export {
5
- normalizeGitHubResourceEvents
5
+ normalizeGitHubEvents
6
6
  };
@@ -1,5 +1,5 @@
1
1
  import { type ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
2
- import { type GitHubPullRequestSubscriptionConfig } from "../resource-events/pull-request.js";
2
+ import { type GitHubPullRequestSubscriptionConfig } from "../events/pull-request.js";
3
3
  /** Own PR creation so provider writes use host egress and the footer stays deterministic. */
4
4
  export declare function createGitHubPullRequestTool(ctx: ToolRegistrationHookContext, subscriptionConfig?: GitHubPullRequestSubscriptionConfig): import("@sentry/junior-plugin-api").PluginToolDefinition<{
5
5
  repo: string;
@@ -2,7 +2,7 @@ import { type PluginEgress } from "@sentry/junior-plugin-api";
2
2
  /** Read deployment metadata and expose its stable subscription identity. */
3
3
  export declare function createGitHubGetDeploymentTool(ctx: {
4
4
  egress: PluginEgress;
5
- resourceEvents: {
5
+ events: {
6
6
  canSubscribe: boolean;
7
7
  };
8
8
  }): import("@sentry/junior-plugin-api").PluginToolDefinition<{
@@ -2,7 +2,7 @@ import { type PluginEgress } from "@sentry/junior-plugin-api";
2
2
  /** Read one PR and expose its stable subscription identity when webhooks are enabled. */
3
3
  export declare function createGitHubGetPullRequestTool(ctx: {
4
4
  egress: PluginEgress;
5
- resourceEvents: {
5
+ events: {
6
6
  canSubscribe: boolean;
7
7
  };
8
8
  }): import("@sentry/junior-plugin-api").PluginToolDefinition<{
@@ -2,7 +2,7 @@ import { type PluginEgress } from "@sentry/junior-plugin-api";
2
2
  /** Read release metadata and expose its stable subscription identity. */
3
3
  export declare function createGitHubGetReleaseTool(ctx: {
4
4
  egress: PluginEgress;
5
- resourceEvents: {
5
+ events: {
6
6
  canSubscribe: boolean;
7
7
  };
8
8
  }): import("@sentry/junior-plugin-api").PluginToolDefinition<{
@@ -2,7 +2,7 @@ import { type PluginEgress } from "@sentry/junior-plugin-api";
2
2
  /** Read one repository and expose its stable subscription identity. */
3
3
  export declare function createGitHubGetRepositoryTool(ctx: {
4
4
  egress: PluginEgress;
5
- resourceEvents: {
5
+ events: {
6
6
  canSubscribe: boolean;
7
7
  };
8
8
  }): import("@sentry/junior-plugin-api").PluginToolDefinition<{
@@ -5,7 +5,7 @@ export declare function createGitHubUpdateIssueTool(ctx: {
5
5
  conversationId?: string;
6
6
  egress: PluginEgress;
7
7
  log: PluginLogger;
8
- resourceEvents: {
8
+ events: {
9
9
  canSubscribe: boolean;
10
10
  };
11
11
  slack?: {
@@ -5,7 +5,7 @@ export declare function createGitHubUpdatePullRequestTool(ctx: {
5
5
  conversationId?: string;
6
6
  egress: PluginEgress;
7
7
  log: PluginLogger;
8
- resourceEvents: {
8
+ events: {
9
9
  canSubscribe: boolean;
10
10
  };
11
11
  slack?: {
package/dist/tools.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { PluginToolDefinition, ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
2
- import type { GitHubPullRequestSubscriptionConfig } from "./resource-events/pull-request.js";
2
+ import type { GitHubPullRequestSubscriptionConfig } from "./events/pull-request.js";
3
3
  /** Build the GitHub plugin's runtime tools from their per-tool modules. */
4
4
  export declare function createGitHubTools(ctx: ToolRegistrationHookContext, botEmail?: string, pullRequestSubscription?: GitHubPullRequestSubscriptionConfig): Record<string, PluginToolDefinition>;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * GitHub check suite resource events.
2
+ * GitHub check suite events.
3
3
  */
4
- import type { ResourceEventInput } from "@sentry/junior-plugin-api";
4
+ import type { EventInput } from "@sentry/junior-plugin-api";
5
5
  export type GitHubFailingCheck = {
6
6
  checkRunId: number;
7
7
  conclusion: string;
@@ -27,7 +27,7 @@ export declare function buildCheckSuiteUrl(args: {
27
27
  repo: string;
28
28
  }): string;
29
29
  /** Build the trusted data and summary for one check-suite event. */
30
- export declare function buildCheckSuiteResourceEvent(args: {
30
+ export declare function buildCheckSuiteEvent(args: {
31
31
  appName?: string;
32
32
  authorEmail?: string;
33
33
  authorUsername?: string;
@@ -43,13 +43,13 @@ export declare function buildCheckSuiteResourceEvent(args: {
43
43
  pullRequestNumber?: number;
44
44
  repo: string;
45
45
  suiteConclusion: string;
46
- }): ResourceEventInput;
46
+ }): EventInput;
47
47
  /** Keep only failed check runs from one suite. */
48
48
  export declare function selectFailingChecks(checkRuns: unknown, options?: {
49
49
  checkSuiteId?: number;
50
50
  }): GitHubFailingCheck[];
51
51
  /** Normalize a completed check suite for attached PRs, or the repository alone. */
52
- export declare function normalizeCheckSuiteEvents(deliveryId: string, body: unknown, options?: GitHubCheckSuiteFacts): ResourceEventInput[];
52
+ export declare function normalizeCheckSuiteEvents(deliveryId: string, body: unknown, options?: GitHubCheckSuiteFacts): EventInput[];
53
53
  /** Identifiers and event types one completed check suite may publish. */
54
54
  export declare function parseCheckSuitePublishTargets(body: unknown): {
55
55
  eventTypes: string[];
@@ -0,0 +1,12 @@
1
+ import type { EventInput } from "@sentry/junior-plugin-api";
2
+ import { type GitHubCheckSuiteFacts } from "./check-suite.js";
3
+ export type { GitHubCheckSuiteFacts, GitHubCheckSuitePullRequestFacts, GitHubFailingCheck, } from "./check-suite.js";
4
+ export { buildCheckSuiteEvent, buildCheckSuiteUrl, loadCheckSuiteFacts, needsCheckSuitePullRequestFacts, parseCheckSuiteFactsTarget, parseCheckSuitePublishTargets, selectFailingChecks, } from "./check-suite.js";
5
+ /** Read the check suite target used to load missing suite facts. */
6
+ /** Normalize one verified GitHub delivery into conversation events. */
7
+ export declare function normalizeGitHubEvents(args: {
8
+ body: unknown;
9
+ checkSuiteFacts?: GitHubCheckSuiteFacts;
10
+ deliveryId: string;
11
+ eventName: string;
12
+ }): EventInput[];
@@ -1,4 +1,4 @@
1
- import type { CodeChangePublisher, PluginConversationAnnotations, PluginLogger, PluginRoute, ResourceEventPublisher } from "@sentry/junior-plugin-api";
1
+ import type { CodeChangePublisher, PluginConversationAnnotations, PluginLogger, PluginRoute, 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
4
  interface FeedbackTarget {
@@ -22,7 +22,7 @@ export declare function createGitHubWebhookRoute(args: {
22
22
  log?: Pick<PluginLogger, "error">;
23
23
  markFeedbackReviewing(input: FeedbackTarget): Promise<void>;
24
24
  privateKeyEnv: string;
25
- resourceEvents: ResourceEventPublisher;
25
+ events: EventPublisher;
26
26
  webhookSecret(): string | undefined;
27
27
  }): PluginRoute;
28
28
  export {};
@@ -1,3 +1,3 @@
1
- import type { WorkspacePrepareHookContext } from "@sentry/junior-plugin-api";
1
+ import type { WorkspaceFinalize, WorkspacePrepareHookContext } from "@sentry/junior-plugin-api";
2
2
  /** Clone missing GitHub repositories or refresh existing Workspace checkouts. */
3
- export declare function prepareWorkspace(ctx: WorkspacePrepareHookContext): Promise<void>;
3
+ export declare function prepareWorkspace(ctx: WorkspacePrepareHookContext): Promise<WorkspaceFinalize>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-github",
3
- "version": "0.206.0",
3
+ "version": "0.208.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.206.0"
34
+ "@sentry/junior-plugin-api": "0.208.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@oxlint/plugins": "1.79.0",
@@ -28,11 +28,11 @@ Use only for GitHub issues. For pull requests, branches, pushes, or PR creation
28
28
  - Resolve the issue number for non-create operations.
29
29
  - Keep `--repo owner/repo` explicit on `gh` commands so the command itself targets the intended repository, not a stale default.
30
30
  - When the user explicitly asks for durable work in response to GitHub issue
31
- activity, use an event task instead of polling:
31
+ activity, use an event automation instead of polling:
32
32
  - Use namespace `github`. One issue uses identifier `owner/repo#number` and
33
33
  resource type `issue`; repo-wide issue activity uses identifier
34
34
  `owner/repo` and resource type `repository`.
35
- - Use the event names currently exposed by the resource-event catalog; search
35
+ - Use the event names currently exposed by the event catalog; search
36
36
  it when the requested event is unclear.
37
37
  - Put every requested issue state in the same task's `events` array. Create
38
38
  separate tasks only when the work to perform is different.
@@ -1,12 +0,0 @@
1
- import type { ResourceEventInput } from "@sentry/junior-plugin-api";
2
- import { type GitHubCheckSuiteFacts } from "./check-suite.js";
3
- export type { GitHubCheckSuiteFacts, GitHubCheckSuitePullRequestFacts, GitHubFailingCheck, } from "./check-suite.js";
4
- export { buildCheckSuiteResourceEvent, buildCheckSuiteUrl, loadCheckSuiteFacts, needsCheckSuitePullRequestFacts, parseCheckSuiteFactsTarget, parseCheckSuitePublishTargets, selectFailingChecks, } from "./check-suite.js";
5
- /** Read the check suite target used to load missing suite facts. */
6
- /** Normalize one verified GitHub delivery into conversation resource events. */
7
- export declare function normalizeGitHubResourceEvents(args: {
8
- body: unknown;
9
- checkSuiteFacts?: GitHubCheckSuiteFacts;
10
- deliveryId: string;
11
- eventName: string;
12
- }): ResourceEventInput[];
File without changes
File without changes