@sentry/junior-github 0.133.0 → 0.134.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
@@ -77,26 +77,139 @@ function readGrantPermissions(permissions) {
77
77
  return readOnly;
78
78
  }
79
79
 
80
- // src/tools/create-issue.ts
80
+ // src/tools/clone-repository.ts
81
81
  import {
82
82
  definePluginTool,
83
+ PluginToolInputError,
84
+ pluginToolOutputSchema
85
+ } from "@sentry/junior-plugin-api";
86
+ import { z } from "zod";
87
+ var RESERVED_SANDBOX_DIRECTORIES = /* @__PURE__ */ new Set([".junior", "data", "skills"]);
88
+ var inputSchema = z.object({
89
+ repo: z.string().describe('Repository in "owner/name" format.'),
90
+ directory: z.string().regex(/^[A-Za-z0-9._-]+$/).refine((value) => value !== "." && value !== "..", {
91
+ message: "Directory must be a single directory name."
92
+ }).describe("Optional destination directory under the sandbox root.").optional()
93
+ }).strict();
94
+ var cloneSchema = z.object({
95
+ path: z.string(),
96
+ repo: z.string()
97
+ });
98
+ var outputSchema = pluginToolOutputSchema.extend({
99
+ target: z.literal("cloneRepository"),
100
+ ...cloneSchema.shape
101
+ });
102
+ function parseRepo(value) {
103
+ const parts = value.split("/").map((part) => part.trim());
104
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
105
+ throw new PluginToolInputError('repo must use "owner/name" format');
106
+ }
107
+ return { owner: parts[0], name: parts[1] };
108
+ }
109
+ function defaultDirectory(repoName) {
110
+ return RESERVED_SANDBOX_DIRECTORIES.has(repoName) ? `${repoName}-repo` : repoName;
111
+ }
112
+ function commandSignal(signal, timeoutMs) {
113
+ const timeout = AbortSignal.timeout(timeoutMs);
114
+ return signal ? AbortSignal.any([signal, timeout]) : timeout;
115
+ }
116
+ async function removePartialClone(ctx, path) {
117
+ try {
118
+ const result = await ctx.sandbox.run({
119
+ cmd: "rm",
120
+ args: ["-rf", "--", path],
121
+ cwd: ctx.sandbox.root,
122
+ signal: AbortSignal.timeout(3e4)
123
+ });
124
+ if (result.exitCode !== 0) {
125
+ ctx.log.warn("github.clone.cleanup.failed", {
126
+ path,
127
+ stderr: result.stderr
128
+ });
129
+ }
130
+ } catch (error) {
131
+ ctx.log.warn("github.clone.cleanup.failed", {
132
+ path,
133
+ error: error instanceof Error ? error.message : String(error)
134
+ });
135
+ }
136
+ }
137
+ function createGitHubCloneRepositoryTool(ctx) {
138
+ return definePluginTool({
139
+ annotations: {
140
+ destructiveHint: false,
141
+ idempotentHint: false,
142
+ openWorldHint: true,
143
+ readOnlyHint: false
144
+ },
145
+ description: "Clone a GitHub repository into the sandbox workspace. The destination must not already exist.",
146
+ executionMode: "sequential",
147
+ inputSchema,
148
+ outputSchema,
149
+ async execute(input, options) {
150
+ const repo = parseRepo(input.repo);
151
+ const directory = input.directory ?? defaultDirectory(repo.name);
152
+ const path = `${ctx.sandbox.root}/${directory}`;
153
+ const exists = await ctx.sandbox.run({
154
+ cmd: "bash",
155
+ args: ["-c", `test -e "$1"`, "bash", path],
156
+ cwd: ctx.sandbox.root,
157
+ signal: commandSignal(options.signal, 3e4)
158
+ });
159
+ if (exists.exitCode === 0) {
160
+ throw new PluginToolInputError(`destination already exists: ${path}`);
161
+ }
162
+ let clone;
163
+ try {
164
+ clone = await ctx.sandbox.run({
165
+ cmd: "git",
166
+ args: [
167
+ "clone",
168
+ "--quiet",
169
+ "--depth=1",
170
+ "--",
171
+ `https://github.com/${repo.owner}/${repo.name}.git`,
172
+ directory
173
+ ],
174
+ cwd: ctx.sandbox.root,
175
+ signal: commandSignal(options.signal, 2 * 6e4)
176
+ });
177
+ } catch (error) {
178
+ await removePartialClone(ctx, path);
179
+ throw error;
180
+ }
181
+ if (clone.exitCode !== 0) {
182
+ await removePartialClone(ctx, path);
183
+ throw new PluginToolInputError(
184
+ `GitHub repository clone failed: ${clone.stderr.trim() || `exit ${clone.exitCode}`}`
185
+ );
186
+ }
187
+ const data = { repo: `${repo.owner}/${repo.name}`, path };
188
+ return { target: "cloneRepository", ...data };
189
+ }
190
+ });
191
+ }
192
+
193
+ // src/tools/create-issue.ts
194
+ import {
195
+ definePluginTool as definePluginTool2,
83
196
  EgressAuthRequired,
84
- PluginToolInputError as PluginToolInputError2,
197
+ PluginToolInputError as PluginToolInputError3,
85
198
  subscribableResourceSchema,
86
- pluginToolOutputSchema
199
+ pluginToolOutputSchema as pluginToolOutputSchema2
87
200
  } from "@sentry/junior-plugin-api";
88
201
  import { Type } from "@sinclair/typebox";
89
202
  import { Value } from "@sinclair/typebox/value";
90
- import { z } from "zod";
203
+ import { z as z2 } from "zod";
91
204
 
92
205
  // src/tools/footer.ts
93
- import { PluginToolInputError } from "@sentry/junior-plugin-api";
206
+ import { PluginToolInputError as PluginToolInputError2 } from "@sentry/junior-plugin-api";
94
207
  var GITHUB_SESSION_FOOTER_START = "<!-- junior-session-footer:start -->";
95
208
  var GITHUB_SESSION_FOOTER_END = "<!-- junior-session-footer:end -->";
96
209
  var GITHUB_CONVERSATION_ID_MARKER = "junior-conversation-id:";
97
210
  function nonEmptyString(value, name) {
98
211
  if (!value?.trim()) {
99
- throw new PluginToolInputError(`${name} is required`);
212
+ throw new PluginToolInputError2(`${name} is required`);
100
213
  }
101
214
  return value.trim();
102
215
  }
@@ -277,11 +390,11 @@ var createIssueInputSchema = Type.Object(
277
390
  },
278
391
  { additionalProperties: false }
279
392
  );
280
- var createIssueToolInputSchema = z.object({
281
- repo: z.string().describe('Repository in "owner/name" format.'),
282
- title: z.string().describe("Issue title."),
283
- body: z.string().describe("Issue body. Junior appends the conversation footer.").optional(),
284
- labels: z.array(z.string()).describe("Labels to apply to the issue.").optional()
393
+ var createIssueToolInputSchema = z2.object({
394
+ repo: z2.string().describe('Repository in "owner/name" format.'),
395
+ title: z2.string().describe("Issue title."),
396
+ body: z2.string().describe("Issue body. Junior appends the conversation footer.").optional(),
397
+ labels: z2.array(z2.string()).describe("Labels to apply to the issue.").optional()
285
398
  }).strict();
286
399
  var createIssueStateSchema = Type.Union([
287
400
  Type.Object(
@@ -303,17 +416,17 @@ var createIssueStateSchema = Type.Union([
303
416
  { additionalProperties: false }
304
417
  )
305
418
  ]);
306
- var gitHubIssueDataSchema = z.object({
307
- number: z.number(),
419
+ var gitHubIssueDataSchema = z2.object({
420
+ number: z2.number(),
308
421
  subscribable: subscribableResourceSchema.optional(),
309
- url: z.string()
422
+ url: z2.string()
310
423
  });
311
- var gitHubIssueOutputSchema = pluginToolOutputSchema.extend({
312
- target: z.literal("createIssue"),
424
+ var gitHubIssueOutputSchema = pluginToolOutputSchema2.extend({
425
+ target: z2.literal("createIssue"),
313
426
  ...gitHubIssueDataSchema.shape
314
427
  });
315
428
  function gitHubIssueToolResult(input, result, canSubscribe) {
316
- const repo = parseRepo(input.repo);
429
+ const repo = parseRepo2(input.repo);
317
430
  const subscribable = canSubscribe ? gitHubIssueSubscribable({
318
431
  number: result.number,
319
432
  repo: `${repo.owner}/${repo.name}`
@@ -328,22 +441,22 @@ function parseCreateIssueInput(input) {
328
441
  try {
329
442
  return Value.Parse(createIssueInputSchema, input);
330
443
  } catch (error) {
331
- throw new PluginToolInputError2("Invalid GitHub createIssue input.", {
444
+ throw new PluginToolInputError3("Invalid GitHub createIssue input.", {
332
445
  cause: error
333
446
  });
334
447
  }
335
448
  }
336
449
  function nonEmptyString2(value, name) {
337
450
  if (!value?.trim()) {
338
- throw new PluginToolInputError2(`${name} is required`);
451
+ throw new PluginToolInputError3(`${name} is required`);
339
452
  }
340
453
  return value.trim();
341
454
  }
342
- function parseRepo(value) {
455
+ function parseRepo2(value) {
343
456
  const repo = nonEmptyString2(value, "repo");
344
457
  const parts = repo.split("/");
345
458
  if (parts.length !== 2 || !parts[0]?.trim() || !parts[1]?.trim()) {
346
- throw new PluginToolInputError2('repo must use "owner/name" format');
459
+ throw new PluginToolInputError3('repo must use "owner/name" format');
347
460
  }
348
461
  return {
349
462
  owner: parts[0].trim(),
@@ -395,7 +508,7 @@ function isDefinitiveGitHubIssueCreateRejection(error) {
395
508
  return [400, 401, 404, 410, 422].includes(error.status);
396
509
  }
397
510
  function createGitHubIssueRequest(conversationId, input, actor, dashboardUrl) {
398
- const repo = parseRepo(input.repo);
511
+ const repo = parseRepo2(input.repo);
399
512
  const labels = input.labels?.map(
400
513
  (label) => nonEmptyString2(label, "labels entry")
401
514
  );
@@ -451,7 +564,7 @@ async function createGitHubIssue(ctx, request) {
451
564
  };
452
565
  }
453
566
  async function annotateIssue(ctx, input, result) {
454
- const repo = parseRepo(input.repo);
567
+ const repo = parseRepo2(input.repo);
455
568
  await ctx.annotations?.upsert({
456
569
  kind: "resource_link",
457
570
  key: `${repo.owner.toLowerCase()}/${repo.name.toLowerCase()}#${result.number}`,
@@ -461,7 +574,7 @@ async function annotateIssue(ctx, input, result) {
461
574
  });
462
575
  }
463
576
  function createGitHubIssueTool(ctx) {
464
- return definePluginTool({
577
+ return definePluginTool2({
465
578
  annotations: {
466
579
  destructiveHint: false,
467
580
  idempotentHint: true,
@@ -553,78 +666,78 @@ function createGitHubIssueTool(ctx) {
553
666
 
554
667
  // src/tools/get-deployment.ts
555
668
  import {
556
- definePluginTool as definePluginTool2,
557
- PluginToolInputError as PluginToolInputError3,
558
- pluginToolOutputSchema as pluginToolOutputSchema2,
669
+ definePluginTool as definePluginTool3,
670
+ PluginToolInputError as PluginToolInputError4,
671
+ pluginToolOutputSchema as pluginToolOutputSchema3,
559
672
  subscribableResourceSchema as subscribableResourceSchema2
560
673
  } from "@sentry/junior-plugin-api";
561
- import { z as z2 } from "zod";
562
- var commitShaSchema = z2.string().regex(/^[0-9a-f]{40}$/i);
563
- var inputSchema = z2.object({
564
- repo: z2.string().describe('Repository in "owner/name" format.'),
674
+ import { z as z3 } from "zod";
675
+ var commitShaSchema = z3.string().regex(/^[0-9a-f]{40}$/i);
676
+ var inputSchema2 = z3.object({
677
+ repo: z3.string().describe('Repository in "owner/name" format.'),
565
678
  commitSha: commitShaSchema.describe(
566
679
  "Full 40-character Git commit SHA recorded by the deployment."
567
680
  ),
568
- environment: z2.string().trim().min(1).describe(
681
+ environment: z3.string().trim().min(1).describe(
569
682
  'Optional GitHub deployment environment, such as "Production". Omit to inspect and watch deployments for the commit across environments.'
570
683
  ).optional()
571
684
  }).strict();
572
- var statusSchema = z2.object({
573
- createdAt: z2.string(),
574
- creator: z2.string().nullable(),
575
- description: z2.string().nullable(),
576
- environmentUrl: z2.string().nullable(),
577
- id: z2.number(),
578
- logUrl: z2.string().nullable(),
579
- state: z2.string()
685
+ var statusSchema = z3.object({
686
+ createdAt: z3.string(),
687
+ creator: z3.string().nullable(),
688
+ description: z3.string().nullable(),
689
+ environmentUrl: z3.string().nullable(),
690
+ id: z3.number(),
691
+ logUrl: z3.string().nullable(),
692
+ state: z3.string()
580
693
  }).strict();
581
- var deploymentSchema = z2.object({
582
- createdAt: z2.string(),
583
- creator: z2.string().nullable(),
584
- description: z2.string().nullable(),
585
- environment: z2.string(),
586
- id: z2.number(),
694
+ var deploymentSchema = z3.object({
695
+ createdAt: z3.string(),
696
+ creator: z3.string().nullable(),
697
+ description: z3.string().nullable(),
698
+ environment: z3.string(),
699
+ id: z3.number(),
587
700
  latestStatus: statusSchema.nullable(),
588
- ref: z2.string(),
701
+ ref: z3.string(),
589
702
  sha: commitShaSchema,
590
- updatedAt: z2.string(),
591
- url: z2.string()
703
+ updatedAt: z3.string(),
704
+ url: z3.string()
592
705
  }).strict();
593
- var deploymentSourceSchema = z2.object({
706
+ var deploymentSourceSchema = z3.object({
594
707
  commitSha: commitShaSchema,
595
708
  deployment: deploymentSchema.nullable(),
596
- environment: z2.string().nullable(),
597
- repo: z2.string(),
709
+ environment: z3.string().nullable(),
710
+ repo: z3.string(),
598
711
  subscribable: subscribableResourceSchema2.optional()
599
712
  }).strict();
600
- var outputSchema = pluginToolOutputSchema2.extend({
601
- target: z2.literal("getDeployment"),
713
+ var outputSchema2 = pluginToolOutputSchema3.extend({
714
+ target: z3.literal("getDeployment"),
602
715
  ...deploymentSourceSchema.shape
603
716
  }).strict();
604
- var providerCreatorSchema = z2.object({ login: z2.string() }).passthrough().nullable();
605
- var providerDeploymentSchema = z2.object({
606
- created_at: z2.string(),
717
+ var providerCreatorSchema = z3.object({ login: z3.string() }).passthrough().nullable();
718
+ var providerDeploymentSchema = z3.object({
719
+ created_at: z3.string(),
607
720
  creator: providerCreatorSchema,
608
- description: z2.string().nullable(),
609
- environment: z2.string(),
610
- id: z2.number(),
611
- ref: z2.string(),
721
+ description: z3.string().nullable(),
722
+ environment: z3.string(),
723
+ id: z3.number(),
724
+ ref: z3.string(),
612
725
  sha: commitShaSchema,
613
- updated_at: z2.string()
726
+ updated_at: z3.string()
614
727
  }).passthrough();
615
- var providerStatusSchema = z2.object({
616
- created_at: z2.string(),
728
+ var providerStatusSchema = z3.object({
729
+ created_at: z3.string(),
617
730
  creator: providerCreatorSchema,
618
- description: z2.string().nullable().optional(),
619
- environment_url: z2.string().nullable().optional(),
620
- id: z2.number(),
621
- log_url: z2.string().nullable().optional(),
622
- state: z2.string()
731
+ description: z3.string().nullable().optional(),
732
+ environment_url: z3.string().nullable().optional(),
733
+ id: z3.number(),
734
+ log_url: z3.string().nullable().optional(),
735
+ state: z3.string()
623
736
  }).passthrough();
624
- function parseRepo2(value) {
737
+ function parseRepo3(value) {
625
738
  const parts = value.split("/").map((part) => part.trim());
626
739
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
627
- throw new PluginToolInputError3('repo must use "owner/name" format');
740
+ throw new PluginToolInputError4('repo must use "owner/name" format');
628
741
  }
629
742
  return { owner: parts[0], name: parts[1], ref: `${parts[0]}/${parts[1]}` };
630
743
  }
@@ -641,7 +754,7 @@ function throwLookupError(target, status, body) {
641
754
  const message = `GitHub ${target} lookup failed with HTTP ${status}`;
642
755
  const hasValidationErrors = body !== null && typeof body === "object" && !Array.isArray(body) && Array.isArray(body.errors) && body.errors.length > 0;
643
756
  if (target === "deployment" && (status === 404 || status === 422 && hasValidationErrors)) {
644
- throw new PluginToolInputError3(message);
757
+ throw new PluginToolInputError4(message);
645
758
  }
646
759
  throw new Error(message);
647
760
  }
@@ -649,7 +762,7 @@ function repositoryUrl(repo, path) {
649
762
  return `https://api.github.com/repos/${encodeURIComponent(repo.owner)}/${encodeURIComponent(repo.name)}/${path}`;
650
763
  }
651
764
  function createGitHubGetDeploymentTool(ctx) {
652
- return definePluginTool2({
765
+ return definePluginTool3({
653
766
  annotations: {
654
767
  destructiveHint: false,
655
768
  idempotentHint: true,
@@ -657,10 +770,10 @@ function createGitHubGetDeploymentTool(ctx) {
657
770
  readOnlyHint: true
658
771
  },
659
772
  description: "Get the latest GitHub deployment and status for an exact repository and full commit SHA, optionally limited to one environment. The result remains subscribable when no deployment exists yet, so use it before waiting for a deployment outcome.",
660
- inputSchema,
661
- outputSchema,
773
+ inputSchema: inputSchema2,
774
+ outputSchema: outputSchema2,
662
775
  async execute(input) {
663
- const repo = parseRepo2(input.repo);
776
+ const repo = parseRepo3(input.repo);
664
777
  const commitSha = input.commitSha.toLowerCase();
665
778
  const deploymentsUrl = new URL(repositoryUrl(repo, "deployments"));
666
779
  deploymentsUrl.searchParams.set("sha", commitSha);
@@ -686,7 +799,7 @@ function createGitHubGetDeploymentTool(ctx) {
686
799
  deploymentsBody
687
800
  );
688
801
  }
689
- const providerDeployment = z2.array(providerDeploymentSchema).parse(deploymentsBody)[0];
802
+ const providerDeployment = z3.array(providerDeploymentSchema).parse(deploymentsBody)[0];
690
803
  let deployment = null;
691
804
  if (providerDeployment) {
692
805
  const statusesResponse = await ctx.egress.fetch({
@@ -710,7 +823,7 @@ function createGitHubGetDeploymentTool(ctx) {
710
823
  statusesBody
711
824
  );
712
825
  }
713
- const providerStatus = z2.array(providerStatusSchema).parse(statusesBody)[0];
826
+ const providerStatus = z3.array(providerStatusSchema).parse(statusesBody)[0];
714
827
  deployment = {
715
828
  createdAt: providerDeployment.created_at,
716
829
  creator: providerDeployment.creator?.login ?? null,
@@ -754,14 +867,14 @@ function createGitHubGetDeploymentTool(ctx) {
754
867
 
755
868
  // src/tools/create-pull-request.ts
756
869
  import {
757
- definePluginTool as definePluginTool3,
870
+ definePluginTool as definePluginTool4,
758
871
  EgressAuthRequired as EgressAuthRequired2,
759
- PluginToolInputError as PluginToolInputError4,
760
- pluginToolOutputSchema as pluginToolOutputSchema3
872
+ PluginToolInputError as PluginToolInputError5,
873
+ pluginToolOutputSchema as pluginToolOutputSchema4
761
874
  } from "@sentry/junior-plugin-api";
762
875
  import { Type as Type2 } from "@sinclair/typebox";
763
876
  import { Value as Value2 } from "@sinclair/typebox/value";
764
- import { z as z3 } from "zod";
877
+ import { z as z4 } from "zod";
765
878
  import { subscribableResourceSchema as subscribableResourceSchema3 } from "@sentry/junior-plugin-api";
766
879
  var GITHUB_PULL_REQUEST_CREATE_IDEMPOTENCY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
767
880
  var GITHUB_PULL_REQUEST_CREATE_LOCK_TTL_MS = 6e4;
@@ -800,13 +913,13 @@ var createPullRequestInputSchema = Type2.Object(
800
913
  },
801
914
  { additionalProperties: false }
802
915
  );
803
- var createPullRequestToolInputSchema = z3.object({
804
- repo: z3.string().describe('Repository in "owner/name" format.'),
805
- title: z3.string().describe("Pull request title."),
806
- head: z3.string().describe("Head branch or owner:branch ref."),
807
- base: z3.string().describe("Base branch."),
808
- body: z3.string().describe("Pull request body. Junior appends the conversation footer.").optional(),
809
- draft: z3.boolean().describe("Whether to open the pull request as a draft.").optional()
916
+ var createPullRequestToolInputSchema = z4.object({
917
+ repo: z4.string().describe('Repository in "owner/name" format.'),
918
+ title: z4.string().describe("Pull request title."),
919
+ head: z4.string().describe("Head branch or owner:branch ref."),
920
+ base: z4.string().describe("Base branch."),
921
+ body: z4.string().describe("Pull request body. Junior appends the conversation footer.").optional(),
922
+ draft: z4.boolean().describe("Whether to open the pull request as a draft.").optional()
810
923
  }).strict();
811
924
  var createPullRequestStateSchema = Type2.Union([
812
925
  Type2.Object(
@@ -828,35 +941,35 @@ var createPullRequestStateSchema = Type2.Union([
828
941
  { additionalProperties: false }
829
942
  )
830
943
  ]);
831
- var gitHubPullRequestDataSchema = z3.object({
832
- number: z3.number(),
833
- url: z3.string(),
944
+ var gitHubPullRequestDataSchema = z4.object({
945
+ number: z4.number(),
946
+ url: z4.string(),
834
947
  subscribable: subscribableResourceSchema3.optional()
835
948
  });
836
- var gitHubPullRequestOutputSchema = pluginToolOutputSchema3.extend({
837
- target: z3.literal("createPullRequest"),
949
+ var gitHubPullRequestOutputSchema = pluginToolOutputSchema4.extend({
950
+ target: z4.literal("createPullRequest"),
838
951
  ...gitHubPullRequestDataSchema.shape
839
952
  });
840
953
  function parseCreatePullRequestInput(input) {
841
954
  try {
842
955
  return Value2.Parse(createPullRequestInputSchema, input);
843
956
  } catch (error) {
844
- throw new PluginToolInputError4("Invalid GitHub createPullRequest input.", {
957
+ throw new PluginToolInputError5("Invalid GitHub createPullRequest input.", {
845
958
  cause: error
846
959
  });
847
960
  }
848
961
  }
849
962
  function nonEmptyString3(value, name) {
850
963
  if (!value?.trim()) {
851
- throw new PluginToolInputError4(`${name} is required`);
964
+ throw new PluginToolInputError5(`${name} is required`);
852
965
  }
853
966
  return value.trim();
854
967
  }
855
- function parseRepo3(value) {
968
+ function parseRepo4(value) {
856
969
  const repo = nonEmptyString3(value, "repo");
857
970
  const parts = repo.split("/");
858
971
  if (parts.length !== 2 || !parts[0]?.trim() || !parts[1]?.trim()) {
859
- throw new PluginToolInputError4('repo must use "owner/name" format');
972
+ throw new PluginToolInputError5('repo must use "owner/name" format');
860
973
  }
861
974
  return {
862
975
  owner: parts[0].trim(),
@@ -926,7 +1039,7 @@ function isDefinitiveGitHubPullRequestCreateRejection(error) {
926
1039
  return [400, 401, 404, 410, 422].includes(error.status);
927
1040
  }
928
1041
  function createGitHubPullRequestRequest(conversationId, input, actor, dashboardUrl) {
929
- const repo = parseRepo3(input.repo);
1042
+ const repo = parseRepo4(input.repo);
930
1043
  const payload = {
931
1044
  title: nonEmptyString3(input.title, "title"),
932
1045
  head: nonEmptyString3(input.head, "head"),
@@ -985,7 +1098,7 @@ async function createGitHubPullRequest(ctx, request) {
985
1098
  };
986
1099
  }
987
1100
  function gitHubPullRequestToolResult(input, result, canSubscribe) {
988
- const repo = parseRepo3(input.repo);
1101
+ const repo = parseRepo4(input.repo);
989
1102
  const subscribable = canSubscribe ? gitHubPullRequestSubscribable({
990
1103
  number: result.number,
991
1104
  repo: `${repo.owner}/${repo.name}`
@@ -993,7 +1106,7 @@ function gitHubPullRequestToolResult(input, result, canSubscribe) {
993
1106
  return { ...result, ...subscribable ? { subscribable } : {} };
994
1107
  }
995
1108
  async function annotatePullRequest(ctx, input, result) {
996
- const repo = parseRepo3(input.repo);
1109
+ const repo = parseRepo4(input.repo);
997
1110
  await ctx.annotations?.upsert({
998
1111
  kind: "resource_link",
999
1112
  key: `${repo.owner.toLowerCase()}/${repo.name.toLowerCase()}#${result.number}`,
@@ -1010,7 +1123,7 @@ function gitHubPullRequestStructuredResult(input, result, canSubscribe) {
1010
1123
  };
1011
1124
  }
1012
1125
  function createGitHubPullRequestTool(ctx) {
1013
- return definePluginTool3({
1126
+ return definePluginTool4({
1014
1127
  annotations: {
1015
1128
  destructiveHint: false,
1016
1129
  idempotentHint: true,
@@ -1102,37 +1215,37 @@ function createGitHubPullRequestTool(ctx) {
1102
1215
 
1103
1216
  // src/tools/get-pull-request.ts
1104
1217
  import {
1105
- definePluginTool as definePluginTool4,
1106
- PluginToolInputError as PluginToolInputError5,
1107
- pluginToolOutputSchema as pluginToolOutputSchema4
1218
+ definePluginTool as definePluginTool5,
1219
+ PluginToolInputError as PluginToolInputError6,
1220
+ pluginToolOutputSchema as pluginToolOutputSchema5
1108
1221
  } from "@sentry/junior-plugin-api";
1109
- import { z as z4 } from "zod";
1222
+ import { z as z5 } from "zod";
1110
1223
  import { subscribableResourceSchema as subscribableResourceSchema4 } from "@sentry/junior-plugin-api";
1111
- var commitShaSchema2 = z4.string().regex(/^[0-9a-f]{40}$/i);
1112
- var inputSchema2 = z4.object({
1113
- repo: z4.string().describe('Repository in "owner/name" format.'),
1114
- number: z4.number().int().positive().describe("Pull request number.")
1224
+ var commitShaSchema2 = z5.string().regex(/^[0-9a-f]{40}$/i);
1225
+ var inputSchema3 = z5.object({
1226
+ repo: z5.string().describe('Repository in "owner/name" format.'),
1227
+ number: z5.number().int().positive().describe("Pull request number.")
1115
1228
  }).strict();
1116
- var pullRequestSchema = z4.object({
1117
- base: z4.string(),
1118
- draft: z4.boolean(),
1119
- head: z4.string(),
1229
+ var pullRequestSchema = z5.object({
1230
+ base: z5.string(),
1231
+ draft: z5.boolean(),
1232
+ head: z5.string(),
1120
1233
  headSha: commitShaSchema2,
1121
- merged: z4.boolean(),
1122
- number: z4.number(),
1123
- state: z4.string(),
1234
+ merged: z5.boolean(),
1235
+ number: z5.number(),
1236
+ state: z5.string(),
1124
1237
  subscribable: subscribableResourceSchema4.optional(),
1125
- title: z4.string(),
1126
- url: z4.string()
1238
+ title: z5.string(),
1239
+ url: z5.string()
1127
1240
  });
1128
- var outputSchema2 = pluginToolOutputSchema4.extend({
1129
- target: z4.literal("getPullRequest"),
1241
+ var outputSchema3 = pluginToolOutputSchema5.extend({
1242
+ target: z5.literal("getPullRequest"),
1130
1243
  ...pullRequestSchema.shape
1131
1244
  });
1132
- function parseRepo4(value) {
1245
+ function parseRepo5(value) {
1133
1246
  const parts = value.split("/").map((part) => part.trim());
1134
1247
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
1135
- throw new PluginToolInputError5('repo must use "owner/name" format');
1248
+ throw new PluginToolInputError6('repo must use "owner/name" format');
1136
1249
  }
1137
1250
  return { owner: parts[0], name: parts[1], ref: `${parts[0]}/${parts[1]}` };
1138
1251
  }
@@ -1146,7 +1259,7 @@ async function readJson2(response) {
1146
1259
  }
1147
1260
  }
1148
1261
  function createGitHubGetPullRequestTool(ctx) {
1149
- return definePluginTool4({
1262
+ return definePluginTool5({
1150
1263
  annotations: {
1151
1264
  destructiveHint: false,
1152
1265
  idempotentHint: true,
@@ -1154,10 +1267,10 @@ function createGitHubGetPullRequestTool(ctx) {
1154
1267
  readOnlyHint: true
1155
1268
  },
1156
1269
  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.",
1157
- inputSchema: inputSchema2,
1158
- outputSchema: outputSchema2,
1270
+ inputSchema: inputSchema3,
1271
+ outputSchema: outputSchema3,
1159
1272
  async execute(input) {
1160
- const repo = parseRepo4(input.repo);
1273
+ const repo = parseRepo5(input.repo);
1161
1274
  const response = await ctx.egress.fetch({
1162
1275
  provider: "github",
1163
1276
  operation: "github.pull.get",
@@ -1176,15 +1289,15 @@ function createGitHubGetPullRequestTool(ctx) {
1176
1289
  throw new Error(
1177
1290
  `GitHub pull request lookup failed with HTTP ${response.status}`
1178
1291
  );
1179
- const providerResult = z4.object({
1180
- base: z4.object({ ref: z4.string() }),
1181
- draft: z4.boolean(),
1182
- head: z4.object({ ref: z4.string(), sha: commitShaSchema2 }),
1183
- html_url: z4.string(),
1184
- merged: z4.boolean().optional().default(false),
1185
- number: z4.number(),
1186
- state: z4.string(),
1187
- title: z4.string()
1292
+ const providerResult = z5.object({
1293
+ base: z5.object({ ref: z5.string() }),
1294
+ draft: z5.boolean(),
1295
+ head: z5.object({ ref: z5.string(), sha: commitShaSchema2 }),
1296
+ html_url: z5.string(),
1297
+ merged: z5.boolean().optional().default(false),
1298
+ number: z5.number(),
1299
+ state: z5.string(),
1300
+ title: z5.string()
1188
1301
  }).parse(parsed);
1189
1302
  const subscribable = ctx.resourceEvents.canSubscribe ? gitHubPullRequestSubscribable({
1190
1303
  number: providerResult.number,
@@ -1212,54 +1325,54 @@ function createGitHubGetPullRequestTool(ctx) {
1212
1325
 
1213
1326
  // src/tools/get-release.ts
1214
1327
  import {
1215
- definePluginTool as definePluginTool5,
1216
- PluginToolInputError as PluginToolInputError6,
1217
- pluginToolOutputSchema as pluginToolOutputSchema5,
1328
+ definePluginTool as definePluginTool6,
1329
+ PluginToolInputError as PluginToolInputError7,
1330
+ pluginToolOutputSchema as pluginToolOutputSchema6,
1218
1331
  subscribableResourceSchema as subscribableResourceSchema5
1219
1332
  } from "@sentry/junior-plugin-api";
1220
- import { z as z5 } from "zod";
1221
- var inputSchema3 = z5.object({
1222
- repo: z5.string().describe('Repository in "owner/name" format.'),
1223
- tag: z5.string().trim().min(1).describe(
1333
+ import { z as z6 } from "zod";
1334
+ var inputSchema4 = z6.object({
1335
+ repo: z6.string().describe('Repository in "owner/name" format.'),
1336
+ tag: z6.string().trim().min(1).describe(
1224
1337
  "Optional release tag name. Omit to inspect and watch every published release in the repository."
1225
1338
  ).optional()
1226
1339
  }).strict();
1227
- var releaseSchema = z5.object({
1228
- createdAt: z5.string(),
1229
- draft: z5.boolean(),
1230
- htmlUrl: z5.string(),
1231
- id: z5.number(),
1232
- name: z5.string().nullable(),
1233
- prerelease: z5.boolean(),
1234
- publishedAt: z5.string().nullable(),
1235
- tagName: z5.string(),
1236
- targetCommitish: z5.string()
1340
+ var releaseSchema = z6.object({
1341
+ createdAt: z6.string(),
1342
+ draft: z6.boolean(),
1343
+ htmlUrl: z6.string(),
1344
+ id: z6.number(),
1345
+ name: z6.string().nullable(),
1346
+ prerelease: z6.boolean(),
1347
+ publishedAt: z6.string().nullable(),
1348
+ tagName: z6.string(),
1349
+ targetCommitish: z6.string()
1237
1350
  }).strict();
1238
- var releaseSourceSchema = z5.object({
1351
+ var releaseSourceSchema = z6.object({
1239
1352
  release: releaseSchema.nullable(),
1240
- repo: z5.string(),
1353
+ repo: z6.string(),
1241
1354
  subscribable: subscribableResourceSchema5.optional(),
1242
- tag: z5.string().nullable()
1355
+ tag: z6.string().nullable()
1243
1356
  }).strict();
1244
- var outputSchema3 = pluginToolOutputSchema5.extend({
1245
- target: z5.literal("getRelease"),
1357
+ var outputSchema4 = pluginToolOutputSchema6.extend({
1358
+ target: z6.literal("getRelease"),
1246
1359
  ...releaseSourceSchema.shape
1247
1360
  }).strict();
1248
- var providerReleaseSchema = z5.object({
1249
- created_at: z5.string(),
1250
- draft: z5.boolean(),
1251
- html_url: z5.string(),
1252
- id: z5.number(),
1253
- name: z5.string().nullable(),
1254
- prerelease: z5.boolean(),
1255
- published_at: z5.string().nullable(),
1256
- tag_name: z5.string(),
1257
- target_commitish: z5.string()
1361
+ var providerReleaseSchema = z6.object({
1362
+ created_at: z6.string(),
1363
+ draft: z6.boolean(),
1364
+ html_url: z6.string(),
1365
+ id: z6.number(),
1366
+ name: z6.string().nullable(),
1367
+ prerelease: z6.boolean(),
1368
+ published_at: z6.string().nullable(),
1369
+ tag_name: z6.string(),
1370
+ target_commitish: z6.string()
1258
1371
  }).passthrough();
1259
- function parseRepo5(value) {
1372
+ function parseRepo6(value) {
1260
1373
  const parts = value.split("/").map((part) => part.trim());
1261
1374
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
1262
- throw new PluginToolInputError6('repo must use "owner/name" format');
1375
+ throw new PluginToolInputError7('repo must use "owner/name" format');
1263
1376
  }
1264
1377
  return { owner: parts[0], name: parts[1], ref: `${parts[0]}/${parts[1]}` };
1265
1378
  }
@@ -1289,7 +1402,7 @@ function mapRelease(providerRelease) {
1289
1402
  };
1290
1403
  }
1291
1404
  function createGitHubGetReleaseTool(ctx) {
1292
- return definePluginTool5({
1405
+ return definePluginTool6({
1293
1406
  annotations: {
1294
1407
  destructiveHint: false,
1295
1408
  idempotentHint: true,
@@ -1297,10 +1410,10 @@ function createGitHubGetReleaseTool(ctx) {
1297
1410
  readOnlyHint: true
1298
1411
  },
1299
1412
  description: "Get a GitHub release for an exact repository, optionally limited to one tag. The result remains subscribable when no release exists yet, so use it before waiting for a published release. Omit the tag to watch every published release in the repository.",
1300
- inputSchema: inputSchema3,
1301
- outputSchema: outputSchema3,
1413
+ inputSchema: inputSchema4,
1414
+ outputSchema: outputSchema4,
1302
1415
  async execute(input) {
1303
- const repo = parseRepo5(input.repo);
1416
+ const repo = parseRepo6(input.repo);
1304
1417
  const tag = input.tag?.trim() || void 0;
1305
1418
  let release = null;
1306
1419
  if (tag) {
@@ -1367,31 +1480,31 @@ function createGitHubGetReleaseTool(ctx) {
1367
1480
 
1368
1481
  // src/tools/get-repository.ts
1369
1482
  import {
1370
- definePluginTool as definePluginTool6,
1371
- PluginToolInputError as PluginToolInputError7,
1372
- pluginToolOutputSchema as pluginToolOutputSchema6,
1483
+ definePluginTool as definePluginTool7,
1484
+ PluginToolInputError as PluginToolInputError8,
1485
+ pluginToolOutputSchema as pluginToolOutputSchema7,
1373
1486
  subscribableResourceSchema as subscribableResourceSchema6
1374
1487
  } from "@sentry/junior-plugin-api";
1375
- import { z as z6 } from "zod";
1376
- var inputSchema4 = z6.object({
1377
- repo: z6.string().describe('Repository in "owner/name" format.')
1488
+ import { z as z7 } from "zod";
1489
+ var inputSchema5 = z7.object({
1490
+ repo: z7.string().describe('Repository in "owner/name" format.')
1378
1491
  }).strict();
1379
- var repositorySchema = z6.object({
1380
- defaultBranch: z6.string(),
1381
- description: z6.string().nullable(),
1382
- fullName: z6.string(),
1383
- private: z6.boolean(),
1492
+ var repositorySchema = z7.object({
1493
+ defaultBranch: z7.string(),
1494
+ description: z7.string().nullable(),
1495
+ fullName: z7.string(),
1496
+ private: z7.boolean(),
1384
1497
  subscribable: subscribableResourceSchema6.optional(),
1385
- url: z6.string()
1498
+ url: z7.string()
1386
1499
  });
1387
- var outputSchema4 = pluginToolOutputSchema6.extend({
1388
- target: z6.literal("getRepository"),
1500
+ var outputSchema5 = pluginToolOutputSchema7.extend({
1501
+ target: z7.literal("getRepository"),
1389
1502
  ...repositorySchema.shape
1390
1503
  });
1391
- function parseRepo6(value) {
1504
+ function parseRepo7(value) {
1392
1505
  const parts = value.split("/").map((part) => part.trim());
1393
1506
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
1394
- throw new PluginToolInputError7('repo must use "owner/name" format');
1507
+ throw new PluginToolInputError8('repo must use "owner/name" format');
1395
1508
  }
1396
1509
  return { owner: parts[0], name: parts[1] };
1397
1510
  }
@@ -1405,7 +1518,7 @@ async function readJson4(response) {
1405
1518
  }
1406
1519
  }
1407
1520
  function createGitHubGetRepositoryTool(ctx) {
1408
- return definePluginTool6({
1521
+ return definePluginTool7({
1409
1522
  annotations: {
1410
1523
  destructiveHint: false,
1411
1524
  idempotentHint: true,
@@ -1413,10 +1526,10 @@ function createGitHubGetRepositoryTool(ctx) {
1413
1526
  readOnlyHint: true
1414
1527
  },
1415
1528
  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.",
1416
- inputSchema: inputSchema4,
1417
- outputSchema: outputSchema4,
1529
+ inputSchema: inputSchema5,
1530
+ outputSchema: outputSchema5,
1418
1531
  async execute(input) {
1419
- const repo = parseRepo6(input.repo);
1532
+ const repo = parseRepo7(input.repo);
1420
1533
  const response = await ctx.egress.fetch({
1421
1534
  provider: "github",
1422
1535
  operation: "github.repository.get",
@@ -1432,16 +1545,16 @@ function createGitHubGetRepositoryTool(ctx) {
1432
1545
  });
1433
1546
  const parsed = await readJson4(response);
1434
1547
  if (!response.ok) {
1435
- throw new PluginToolInputError7(
1548
+ throw new PluginToolInputError8(
1436
1549
  `GitHub repository lookup failed with HTTP ${response.status}`
1437
1550
  );
1438
1551
  }
1439
- const providerResult = z6.object({
1440
- default_branch: z6.string(),
1441
- description: z6.string().nullable(),
1442
- full_name: z6.string(),
1443
- html_url: z6.string(),
1444
- private: z6.boolean()
1552
+ const providerResult = z7.object({
1553
+ default_branch: z7.string(),
1554
+ description: z7.string().nullable(),
1555
+ full_name: z7.string(),
1556
+ html_url: z7.string(),
1557
+ private: z7.boolean()
1445
1558
  }).parse(parsed);
1446
1559
  const subscribable = ctx.resourceEvents.canSubscribe ? gitHubRepositorySubscribable({
1447
1560
  repo: providerResult.full_name
@@ -1464,49 +1577,49 @@ function createGitHubGetRepositoryTool(ctx) {
1464
1577
 
1465
1578
  // src/tools/update-pull-request.ts
1466
1579
  import {
1467
- definePluginTool as definePluginTool7,
1468
- PluginToolInputError as PluginToolInputError8,
1469
- pluginToolOutputSchema as pluginToolOutputSchema7
1580
+ definePluginTool as definePluginTool8,
1581
+ PluginToolInputError as PluginToolInputError9,
1582
+ pluginToolOutputSchema as pluginToolOutputSchema8
1470
1583
  } from "@sentry/junior-plugin-api";
1471
- import { z as z7 } from "zod";
1584
+ import { z as z8 } from "zod";
1472
1585
  import { subscribableResourceSchema as subscribableResourceSchema7 } from "@sentry/junior-plugin-api";
1473
- var inputSchema5 = z7.object({
1474
- repo: z7.string().describe('Repository in "owner/name" format.'),
1475
- number: z7.number().int().positive().describe("Pull request number."),
1476
- title: z7.string().trim().min(1).optional().describe("Replacement pull request title."),
1477
- body: z7.string().optional().describe(
1586
+ var inputSchema6 = z8.object({
1587
+ repo: z8.string().describe('Repository in "owner/name" format.'),
1588
+ number: z8.number().int().positive().describe("Pull request number."),
1589
+ title: z8.string().trim().min(1).optional().describe("Replacement pull request title."),
1590
+ body: z8.string().optional().describe(
1478
1591
  "Replacement pull request body. Junior appends requester attribution and the conversation footer."
1479
1592
  ),
1480
- base: z7.string().trim().min(1).optional().describe("Replacement base branch."),
1481
- state: z7.enum(["open", "closed"]).optional().describe("Replacement pull request state.")
1593
+ base: z8.string().trim().min(1).optional().describe("Replacement base branch."),
1594
+ state: z8.enum(["open", "closed"]).optional().describe("Replacement pull request state.")
1482
1595
  }).strict().refine(
1483
1596
  ({ title, body, base, state }) => title !== void 0 || body !== void 0 || base !== void 0 || state !== void 0,
1484
1597
  { message: "At least one pull request field must be provided." }
1485
1598
  );
1486
- var pullRequestSchema2 = z7.object({
1487
- base: z7.string(),
1488
- body: z7.string().nullable(),
1489
- draft: z7.boolean(),
1490
- number: z7.number(),
1491
- state: z7.string(),
1599
+ var pullRequestSchema2 = z8.object({
1600
+ base: z8.string(),
1601
+ body: z8.string().nullable(),
1602
+ draft: z8.boolean(),
1603
+ number: z8.number(),
1604
+ state: z8.string(),
1492
1605
  subscribable: subscribableResourceSchema7.optional(),
1493
- title: z7.string(),
1494
- url: z7.string()
1606
+ title: z8.string(),
1607
+ url: z8.string()
1495
1608
  });
1496
- var outputSchema5 = pluginToolOutputSchema7.extend({
1497
- target: z7.literal("updatePullRequest"),
1609
+ var outputSchema6 = pluginToolOutputSchema8.extend({
1610
+ target: z8.literal("updatePullRequest"),
1498
1611
  ...pullRequestSchema2.shape
1499
1612
  });
1500
1613
  function nonEmptyString4(value, name) {
1501
1614
  if (!value?.trim()) {
1502
- throw new PluginToolInputError8(`${name} is required`);
1615
+ throw new PluginToolInputError9(`${name} is required`);
1503
1616
  }
1504
1617
  return value.trim();
1505
1618
  }
1506
- function parseRepo7(value) {
1619
+ function parseRepo8(value) {
1507
1620
  const parts = value.split("/").map((part) => part.trim());
1508
1621
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
1509
- throw new PluginToolInputError8('repo must use "owner/name" format');
1622
+ throw new PluginToolInputError9('repo must use "owner/name" format');
1510
1623
  }
1511
1624
  return { owner: parts[0], name: parts[1], ref: `${parts[0]}/${parts[1]}` };
1512
1625
  }
@@ -1528,7 +1641,7 @@ function githubApiErrorMessage3(payload) {
1528
1641
  return "GitHub request failed";
1529
1642
  }
1530
1643
  function createGitHubUpdatePullRequestTool(ctx) {
1531
- return definePluginTool7({
1644
+ return definePluginTool8({
1532
1645
  annotations: {
1533
1646
  destructiveHint: true,
1534
1647
  idempotentHint: true,
@@ -1536,18 +1649,18 @@ function createGitHubUpdatePullRequestTool(ctx) {
1536
1649
  readOnlyHint: false
1537
1650
  },
1538
1651
  description: "Update an existing GitHub pull request's title, body, base branch, or open/closed state. Use this instead of raw GitHub API calls when changing PR metadata.",
1539
- inputSchema: inputSchema5,
1540
- outputSchema: outputSchema5,
1652
+ inputSchema: inputSchema6,
1653
+ outputSchema: outputSchema6,
1541
1654
  async execute(input) {
1542
- const parsedInput = inputSchema5.safeParse(input);
1655
+ const parsedInput = inputSchema6.safeParse(input);
1543
1656
  if (!parsedInput.success) {
1544
- throw new PluginToolInputError8(
1657
+ throw new PluginToolInputError9(
1545
1658
  "Invalid GitHub updatePullRequest input.",
1546
1659
  { cause: parsedInput.error }
1547
1660
  );
1548
1661
  }
1549
1662
  const update = parsedInput.data;
1550
- const repo = parseRepo7(update.repo);
1663
+ const repo = parseRepo8(update.repo);
1551
1664
  const payload = {
1552
1665
  ...update.title !== void 0 ? { title: update.title } : {},
1553
1666
  ...update.body !== void 0 ? {
@@ -1582,14 +1695,14 @@ function createGitHubUpdatePullRequestTool(ctx) {
1582
1695
  `GitHub pull request update failed with HTTP ${response.status}: ${githubApiErrorMessage3(parsed)}`
1583
1696
  );
1584
1697
  }
1585
- const providerResult = z7.object({
1586
- base: z7.object({ ref: z7.string() }),
1587
- body: z7.string().nullable().optional().default(null),
1588
- draft: z7.boolean(),
1589
- html_url: z7.string(),
1590
- number: z7.number(),
1591
- state: z7.string(),
1592
- title: z7.string()
1698
+ const providerResult = z8.object({
1699
+ base: z8.object({ ref: z8.string() }),
1700
+ body: z8.string().nullable().optional().default(null),
1701
+ draft: z8.boolean(),
1702
+ html_url: z8.string(),
1703
+ number: z8.number(),
1704
+ state: z8.string(),
1705
+ title: z8.string()
1593
1706
  }).parse(parsed);
1594
1707
  const subscribable = ctx.resourceEvents.canSubscribe ? gitHubPullRequestSubscribable({
1595
1708
  number: providerResult.number,
@@ -1616,6 +1729,7 @@ function createGitHubUpdatePullRequestTool(ctx) {
1616
1729
  // src/tools.ts
1617
1730
  function createGitHubTools(ctx) {
1618
1731
  return {
1732
+ cloneRepository: createGitHubCloneRepositoryTool(ctx),
1619
1733
  createIssue: createGitHubIssueTool(ctx),
1620
1734
  createPullRequest: createGitHubPullRequestTool(ctx),
1621
1735
  getDeployment: createGitHubGetDeploymentTool(ctx),
@@ -1631,7 +1745,7 @@ import { createHmac, timingSafeEqual } from "crypto";
1631
1745
 
1632
1746
  // src/issue-outcomes/store.ts
1633
1747
  import { and, eq, lte, sql as sql2 } from "drizzle-orm";
1634
- import { z as z9 } from "zod";
1748
+ import { z as z10 } from "zod";
1635
1749
 
1636
1750
  // src/db/schema.ts
1637
1751
  import { sql } from "drizzle-orm";
@@ -1643,18 +1757,18 @@ import {
1643
1757
  text,
1644
1758
  timestamp
1645
1759
  } from "drizzle-orm/pg-core";
1646
- import { z as z8 } from "zod";
1647
- var githubPullRequestStateSchema = z8.enum([
1760
+ import { z as z9 } from "zod";
1761
+ var githubPullRequestStateSchema = z9.enum([
1648
1762
  "closed_unmerged",
1649
1763
  "merged",
1650
1764
  "open"
1651
1765
  ]);
1652
- var githubPullRequestCommitCompositionSchema = z8.enum([
1766
+ var githubPullRequestCommitCompositionSchema = z9.enum([
1653
1767
  "junior_only",
1654
1768
  "mixed"
1655
1769
  ]);
1656
- var githubIssueStateSchema = z8.enum(["closed", "open"]);
1657
- var githubIssueStateReasonSchema = z8.enum([
1770
+ var githubIssueStateSchema = z9.enum(["closed", "open"]);
1771
+ var githubIssueStateReasonSchema = z9.enum([
1658
1772
  "completed",
1659
1773
  "duplicate",
1660
1774
  "not_planned",
@@ -1723,21 +1837,21 @@ var juniorGitHubPullRequestIssues = pgTable(
1723
1837
  );
1724
1838
 
1725
1839
  // src/issue-outcomes/store.ts
1726
- var githubIssueOutcomeInputSchema = z9.object({
1727
- candidateOwned: z9.boolean(),
1728
- closedAt: z9.date().optional(),
1729
- issueId: z9.string().min(1),
1730
- number: z9.number().int().positive(),
1731
- openedAt: z9.date(),
1732
- repositoryFullName: z9.string().min(1),
1733
- repositoryId: z9.string().min(1),
1840
+ var githubIssueOutcomeInputSchema = z10.object({
1841
+ candidateOwned: z10.boolean(),
1842
+ closedAt: z10.date().optional(),
1843
+ issueId: z10.string().min(1),
1844
+ number: z10.number().int().positive(),
1845
+ openedAt: z10.date(),
1846
+ repositoryFullName: z10.string().min(1),
1847
+ repositoryId: z10.string().min(1),
1734
1848
  state: githubIssueStateSchema,
1735
1849
  stateReason: githubIssueStateReasonSchema.optional(),
1736
- updatedAt: z9.date()
1850
+ updatedAt: z10.date()
1737
1851
  }).strict();
1738
- var githubIssueConversationsInputSchema = z9.object({
1739
- conversationIds: z9.array(z9.string().min(1)).min(1),
1740
- issueId: z9.string().min(1)
1852
+ var githubIssueConversationsInputSchema = z10.object({
1853
+ conversationIds: z10.array(z10.string().min(1)).min(1),
1854
+ issueId: z10.string().min(1)
1741
1855
  }).strict();
1742
1856
  function projectionValues(input) {
1743
1857
  return {
@@ -1790,32 +1904,32 @@ async function recordGitHubIssueConversations(db, input) {
1790
1904
 
1791
1905
  // src/pull-request-outcomes/store.ts
1792
1906
  import { and as and2, eq as eq2, lte as lte2, sql as sql3 } from "drizzle-orm";
1793
- import { z as z10 } from "zod";
1794
- var githubPullRequestOutcomeInputSchema = z10.object({
1795
- candidateOwned: z10.boolean(),
1796
- closedAt: z10.date().optional(),
1907
+ import { z as z11 } from "zod";
1908
+ var githubPullRequestOutcomeInputSchema = z11.object({
1909
+ candidateOwned: z11.boolean(),
1910
+ closedAt: z11.date().optional(),
1797
1911
  commitComposition: githubPullRequestCommitCompositionSchema.optional(),
1798
- mergedAt: z10.date().optional(),
1799
- number: z10.number().int().positive(),
1800
- openedAt: z10.date(),
1801
- pullRequestId: z10.string().min(1),
1802
- repositoryFullName: z10.string().min(1),
1803
- repositoryId: z10.string().min(1),
1912
+ mergedAt: z11.date().optional(),
1913
+ number: z11.number().int().positive(),
1914
+ openedAt: z11.date(),
1915
+ pullRequestId: z11.string().min(1),
1916
+ repositoryFullName: z11.string().min(1),
1917
+ repositoryId: z11.string().min(1),
1804
1918
  state: githubPullRequestStateSchema,
1805
- updatedAt: z10.date()
1919
+ updatedAt: z11.date()
1806
1920
  }).strict();
1807
- var githubPullRequestConversationsInputSchema = z10.object({
1808
- conversationIds: z10.array(z10.string().min(1)).min(1),
1809
- pullRequestId: z10.string().min(1)
1921
+ var githubPullRequestConversationsInputSchema = z11.object({
1922
+ conversationIds: z11.array(z11.string().min(1)).min(1),
1923
+ pullRequestId: z11.string().min(1)
1810
1924
  }).strict();
1811
- var githubPullRequestLinkedIssuesInputSchema = z10.object({
1812
- linkedIssues: z10.array(
1813
- z10.object({
1814
- number: z10.number().int().positive(),
1815
- repositoryFullName: z10.string().min(1)
1925
+ var githubPullRequestLinkedIssuesInputSchema = z11.object({
1926
+ linkedIssues: z11.array(
1927
+ z11.object({
1928
+ number: z11.number().int().positive(),
1929
+ repositoryFullName: z11.string().min(1)
1816
1930
  }).strict()
1817
1931
  ).min(1),
1818
- pullRequestId: z10.string().min(1)
1932
+ pullRequestId: z11.string().min(1)
1819
1933
  }).strict();
1820
1934
  function projectionValues2(input) {
1821
1935
  return {
@@ -1905,7 +2019,7 @@ async function recordGitHubPullRequestLinkedIssues(db, input) {
1905
2019
  }
1906
2020
 
1907
2021
  // src/webhooks/issue-outcome.ts
1908
- import { z as z11 } from "zod";
2022
+ import { z as z12 } from "zod";
1909
2023
 
1910
2024
  // src/webhooks/ownership.ts
1911
2025
  var GITHUB_NOREPLY_DOMAIN = "users.noreply.github.com";
@@ -1922,38 +2036,38 @@ function botLoginFromEmail(value) {
1922
2036
  }
1923
2037
 
1924
2038
  // src/webhooks/issue-outcome.ts
1925
- var canonicalIssueOutcomeSchema = z11.object({
1926
- action: z11.enum(["opened", "closed", "reopened"]),
1927
- issue: z11.object({
1928
- body: z11.string().nullable().optional(),
1929
- closed_at: z11.string().nullable().optional(),
1930
- created_at: z11.string(),
1931
- id: z11.number().int().positive(),
1932
- number: z11.number().int().positive(),
2039
+ var canonicalIssueOutcomeSchema = z12.object({
2040
+ action: z12.enum(["opened", "closed", "reopened"]),
2041
+ issue: z12.object({
2042
+ body: z12.string().nullable().optional(),
2043
+ closed_at: z12.string().nullable().optional(),
2044
+ created_at: z12.string(),
2045
+ id: z12.number().int().positive(),
2046
+ number: z12.number().int().positive(),
1933
2047
  state_reason: githubIssueStateReasonSchema.nullable().optional(),
1934
- updated_at: z11.string(),
1935
- user: z11.object({ login: z11.string().min(1) }).strict()
2048
+ updated_at: z12.string(),
2049
+ user: z12.object({ login: z12.string().min(1) }).strict()
1936
2050
  }).strict(),
1937
- repository: z11.object({
1938
- full_name: z11.string().min(1),
1939
- id: z11.number().int().positive()
2051
+ repository: z12.object({
2052
+ full_name: z12.string().min(1),
2053
+ id: z12.number().int().positive()
1940
2054
  }).strict()
1941
2055
  }).strict();
1942
- var issueOutcomeSchema = z11.object({
1943
- action: z11.enum(["opened", "closed", "reopened"]),
1944
- issue: z11.object({
1945
- body: z11.string().nullable().optional(),
1946
- closed_at: z11.string().nullable().optional(),
1947
- created_at: z11.string(),
1948
- id: z11.number().int().positive(),
1949
- number: z11.number().int().positive(),
2056
+ var issueOutcomeSchema = z12.object({
2057
+ action: z12.enum(["opened", "closed", "reopened"]),
2058
+ issue: z12.object({
2059
+ body: z12.string().nullable().optional(),
2060
+ closed_at: z12.string().nullable().optional(),
2061
+ created_at: z12.string(),
2062
+ id: z12.number().int().positive(),
2063
+ number: z12.number().int().positive(),
1950
2064
  state_reason: githubIssueStateReasonSchema.nullable().optional(),
1951
- updated_at: z11.string(),
1952
- user: z11.object({ login: z11.string().min(1) }).passthrough()
2065
+ updated_at: z12.string(),
2066
+ user: z12.object({ login: z12.string().min(1) }).passthrough()
1953
2067
  }).passthrough(),
1954
- repository: z11.object({
1955
- full_name: z11.string().min(1),
1956
- id: z11.number().int().positive()
2068
+ repository: z12.object({
2069
+ full_name: z12.string().min(1),
2070
+ id: z12.number().int().positive()
1957
2071
  }).passthrough()
1958
2072
  }).passthrough().transform(
1959
2073
  (provider) => canonicalIssueOutcomeSchema.parse({
@@ -1974,7 +2088,7 @@ var issueOutcomeSchema = z11.object({
1974
2088
  }
1975
2089
  })
1976
2090
  );
1977
- var issueLifecycleActionSchema = z11.object({ action: z11.string() }).passthrough();
2091
+ var issueLifecycleActionSchema = z12.object({ action: z12.string() }).passthrough();
1978
2092
  function timestamp2(value) {
1979
2093
  if (!value) return void 0;
1980
2094
  const parsed = new Date(value);
@@ -2020,21 +2134,21 @@ function normalizeGitHubIssueOutcome(args) {
2020
2134
  updatedAt
2021
2135
  };
2022
2136
  }
2023
- var canonicalIssueConversationSchema = z11.object({
2024
- issue: z11.object({
2025
- body: z11.string().nullable().optional(),
2026
- id: z11.number().int().positive(),
2027
- user: z11.object({ login: z11.string().min(1) }).strict()
2137
+ var canonicalIssueConversationSchema = z12.object({
2138
+ issue: z12.object({
2139
+ body: z12.string().nullable().optional(),
2140
+ id: z12.number().int().positive(),
2141
+ user: z12.object({ login: z12.string().min(1) }).strict()
2028
2142
  }).strict(),
2029
- sender: z11.object({ login: z11.string().min(1) }).strict().optional()
2143
+ sender: z12.object({ login: z12.string().min(1) }).strict().optional()
2030
2144
  }).strict();
2031
- var issueConversationSchema = z11.object({
2032
- issue: z11.object({
2033
- body: z11.string().nullable().optional(),
2034
- id: z11.number().int().positive(),
2035
- user: z11.object({ login: z11.string().min(1) }).passthrough()
2145
+ var issueConversationSchema = z12.object({
2146
+ issue: z12.object({
2147
+ body: z12.string().nullable().optional(),
2148
+ id: z12.number().int().positive(),
2149
+ user: z12.object({ login: z12.string().min(1) }).passthrough()
2036
2150
  }).passthrough(),
2037
- sender: z11.object({ login: z11.string().min(1) }).passthrough().optional()
2151
+ sender: z12.object({ login: z12.string().min(1) }).passthrough().optional()
2038
2152
  }).passthrough().transform(
2039
2153
  (provider) => canonicalIssueConversationSchema.parse({
2040
2154
  issue: {
@@ -2061,41 +2175,41 @@ function normalizeGitHubIssueConversations(args) {
2061
2175
  }
2062
2176
 
2063
2177
  // src/webhooks/pull-request-outcome.ts
2064
- import { z as z12 } from "zod";
2065
- var canonicalPullRequestOutcomeSchema = z12.object({
2066
- action: z12.enum(["opened", "closed", "reopened"]),
2067
- pull_request: z12.object({
2068
- body: z12.string().nullable().optional(),
2069
- closed_at: z12.string().nullable().optional(),
2070
- created_at: z12.string(),
2071
- id: z12.number().int().positive(),
2072
- merged: z12.boolean(),
2073
- merged_at: z12.string().nullable().optional(),
2074
- number: z12.number().int().positive(),
2075
- updated_at: z12.string(),
2076
- user: z12.object({ login: z12.string().min(1) }).strict()
2178
+ import { z as z13 } from "zod";
2179
+ var canonicalPullRequestOutcomeSchema = z13.object({
2180
+ action: z13.enum(["opened", "closed", "reopened"]),
2181
+ pull_request: z13.object({
2182
+ body: z13.string().nullable().optional(),
2183
+ closed_at: z13.string().nullable().optional(),
2184
+ created_at: z13.string(),
2185
+ id: z13.number().int().positive(),
2186
+ merged: z13.boolean(),
2187
+ merged_at: z13.string().nullable().optional(),
2188
+ number: z13.number().int().positive(),
2189
+ updated_at: z13.string(),
2190
+ user: z13.object({ login: z13.string().min(1) }).strict()
2077
2191
  }).strict(),
2078
- repository: z12.object({
2079
- full_name: z12.string().min(1),
2080
- id: z12.number().int().positive()
2192
+ repository: z13.object({
2193
+ full_name: z13.string().min(1),
2194
+ id: z13.number().int().positive()
2081
2195
  }).strict()
2082
2196
  }).strict();
2083
- var pullRequestOutcomeSchema = z12.object({
2084
- action: z12.enum(["opened", "closed", "reopened"]),
2085
- pull_request: z12.object({
2086
- body: z12.string().nullable().optional(),
2087
- closed_at: z12.string().nullable().optional(),
2088
- created_at: z12.string(),
2089
- id: z12.number().int().positive(),
2090
- merged: z12.boolean(),
2091
- merged_at: z12.string().nullable().optional(),
2092
- number: z12.number().int().positive(),
2093
- updated_at: z12.string(),
2094
- user: z12.object({ login: z12.string().min(1) }).passthrough()
2197
+ var pullRequestOutcomeSchema = z13.object({
2198
+ action: z13.enum(["opened", "closed", "reopened"]),
2199
+ pull_request: z13.object({
2200
+ body: z13.string().nullable().optional(),
2201
+ closed_at: z13.string().nullable().optional(),
2202
+ created_at: z13.string(),
2203
+ id: z13.number().int().positive(),
2204
+ merged: z13.boolean(),
2205
+ merged_at: z13.string().nullable().optional(),
2206
+ number: z13.number().int().positive(),
2207
+ updated_at: z13.string(),
2208
+ user: z13.object({ login: z13.string().min(1) }).passthrough()
2095
2209
  }).passthrough(),
2096
- repository: z12.object({
2097
- full_name: z12.string().min(1),
2098
- id: z12.number().int().positive()
2210
+ repository: z13.object({
2211
+ full_name: z13.string().min(1),
2212
+ id: z13.number().int().positive()
2099
2213
  }).passthrough()
2100
2214
  }).passthrough().transform(
2101
2215
  (provider) => canonicalPullRequestOutcomeSchema.parse({
@@ -2117,24 +2231,24 @@ var pullRequestOutcomeSchema = z12.object({
2117
2231
  }
2118
2232
  })
2119
2233
  );
2120
- var pullRequestLifecycleActionSchema = z12.object({ action: z12.string() }).passthrough();
2121
- var canonicalPullRequestConversationSchema = z12.object({
2122
- pull_request: z12.object({
2123
- body: z12.string().nullable().optional(),
2124
- id: z12.number().int().positive(),
2125
- user: z12.object({ login: z12.string().min(1) }).strict()
2234
+ var pullRequestLifecycleActionSchema = z13.object({ action: z13.string() }).passthrough();
2235
+ var canonicalPullRequestConversationSchema = z13.object({
2236
+ pull_request: z13.object({
2237
+ body: z13.string().nullable().optional(),
2238
+ id: z13.number().int().positive(),
2239
+ user: z13.object({ login: z13.string().min(1) }).strict()
2126
2240
  }).strict(),
2127
- repository: z12.object({ full_name: z12.string().min(1) }).strict(),
2128
- sender: z12.object({ login: z12.string().min(1) }).strict()
2241
+ repository: z13.object({ full_name: z13.string().min(1) }).strict(),
2242
+ sender: z13.object({ login: z13.string().min(1) }).strict()
2129
2243
  }).strict();
2130
- var pullRequestConversationSchema = z12.object({
2131
- pull_request: z12.object({
2132
- body: z12.string().nullable().optional(),
2133
- id: z12.number().int().positive(),
2134
- user: z12.object({ login: z12.string().min(1) }).passthrough()
2244
+ var pullRequestConversationSchema = z13.object({
2245
+ pull_request: z13.object({
2246
+ body: z13.string().nullable().optional(),
2247
+ id: z13.number().int().positive(),
2248
+ user: z13.object({ login: z13.string().min(1) }).passthrough()
2135
2249
  }).passthrough(),
2136
- repository: z12.object({ full_name: z12.string().min(1) }).passthrough(),
2137
- sender: z12.object({ login: z12.string().min(1) }).passthrough()
2250
+ repository: z13.object({ full_name: z13.string().min(1) }).passthrough(),
2251
+ sender: z13.object({ login: z13.string().min(1) }).passthrough()
2138
2252
  }).passthrough().transform(
2139
2253
  (provider) => canonicalPullRequestConversationSchema.parse({
2140
2254
  pull_request: {
@@ -2342,18 +2456,18 @@ function createGitHubWebhookRoute(args) {
2342
2456
 
2343
2457
  // src/outcomes/report.ts
2344
2458
  import { sql as sql5 } from "drizzle-orm";
2345
- import { z as z14 } from "zod";
2459
+ import { z as z15 } from "zod";
2346
2460
 
2347
2461
  // src/outcomes/cost.ts
2348
2462
  import { sql as sql4 } from "drizzle-orm";
2349
- import { z as z13 } from "zod";
2463
+ import { z as z14 } from "zod";
2350
2464
  var DAY_MS = 24 * 60 * 60 * 1e3;
2351
- var costWindowSchema = z13.object({
2352
- days: z13.number().int().positive(),
2353
- issueCostUsd: z13.number().nonnegative().nullable(),
2354
- medianIssueCostUsd: z13.number().nonnegative().nullable(),
2355
- medianPullRequestCostUsd: z13.number().nonnegative().nullable(),
2356
- pullRequestCostUsd: z13.number().nonnegative().nullable()
2465
+ var costWindowSchema = z14.object({
2466
+ days: z14.number().int().positive(),
2467
+ issueCostUsd: z14.number().nonnegative().nullable(),
2468
+ medianIssueCostUsd: z14.number().nonnegative().nullable(),
2469
+ medianPullRequestCostUsd: z14.number().nonnegative().nullable(),
2470
+ pullRequestCostUsd: z14.number().nonnegative().nullable()
2357
2471
  }).strict().transform((row) => ({
2358
2472
  days: row.days,
2359
2473
  issueCostUsd: row.issueCostUsd ?? void 0,
@@ -2361,12 +2475,12 @@ var costWindowSchema = z13.object({
2361
2475
  medianPullRequestCostUsd: row.medianPullRequestCostUsd ?? void 0,
2362
2476
  pullRequestCostUsd: row.pullRequestCostUsd ?? void 0
2363
2477
  }));
2364
- var repositoryCostSchema = z13.object({
2365
- issueCostUsd: z13.number().nonnegative().nullable(),
2366
- medianIssueCostUsd: z13.number().nonnegative().nullable(),
2367
- medianPullRequestCostUsd: z13.number().nonnegative().nullable(),
2368
- pullRequestCostUsd: z13.number().nonnegative().nullable(),
2369
- repository: z13.string().min(1)
2478
+ var repositoryCostSchema = z14.object({
2479
+ issueCostUsd: z14.number().nonnegative().nullable(),
2480
+ medianIssueCostUsd: z14.number().nonnegative().nullable(),
2481
+ medianPullRequestCostUsd: z14.number().nonnegative().nullable(),
2482
+ pullRequestCostUsd: z14.number().nonnegative().nullable(),
2483
+ repository: z14.string().min(1)
2370
2484
  }).strict().transform((row) => ({
2371
2485
  issueCostUsd: row.issueCostUsd ?? void 0,
2372
2486
  medianIssueCostUsd: row.medianIssueCostUsd ?? void 0,
@@ -2571,7 +2685,7 @@ async function aggregateGitHubCostWindows(args) {
2571
2685
  INNER JOIN issue_window ON issue_window.days = pull_request_window.days
2572
2686
  ORDER BY pull_request_window.days
2573
2687
  `);
2574
- return z13.array(costWindowSchema).parse(queryRows(result));
2688
+ return z14.array(costWindowSchema).parse(queryRows(result));
2575
2689
  }
2576
2690
  async function aggregateGitHubRepositoryCosts(args) {
2577
2691
  if (!await hasConversationUsageTable(args.db)) {
@@ -2669,7 +2783,7 @@ async function aggregateGitHubRepositoryCosts(args) {
2669
2783
  ON issue_totals.repository = repositories.repository
2670
2784
  ORDER BY "repository" ASC
2671
2785
  `);
2672
- return z13.array(repositoryCostSchema).parse(queryRows(result));
2786
+ return z14.array(repositoryCostSchema).parse(queryRows(result));
2673
2787
  }
2674
2788
  function formatCostUsd(value) {
2675
2789
  if (value === void 0) return "\u2014";
@@ -2684,12 +2798,12 @@ function formatCostUsd(value) {
2684
2798
  // src/outcomes/report.ts
2685
2799
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
2686
2800
  var WINDOWS = [7, 30, 90];
2687
- var pullRequestStatsSchema = z14.object({
2688
- closed: z14.number().int().nonnegative(),
2689
- created: z14.number().int().nonnegative(),
2690
- days: z14.number().int().positive(),
2691
- medianMergeTimeMs: z14.number().nonnegative().nullable(),
2692
- merged: z14.number().int().nonnegative()
2801
+ var pullRequestStatsSchema = z15.object({
2802
+ closed: z15.number().int().nonnegative(),
2803
+ created: z15.number().int().nonnegative(),
2804
+ days: z15.number().int().positive(),
2805
+ medianMergeTimeMs: z15.number().nonnegative().nullable(),
2806
+ merged: z15.number().int().nonnegative()
2693
2807
  }).strict().transform((row) => {
2694
2808
  const terminal = row.merged + row.closed;
2695
2809
  return {
@@ -2698,12 +2812,12 @@ var pullRequestStatsSchema = z14.object({
2698
2812
  mergeRate: terminal > 0 ? row.merged / terminal : void 0
2699
2813
  };
2700
2814
  });
2701
- var pullRequestRepositoryStatsSchema = z14.object({
2702
- closed: z14.number().int().nonnegative(),
2703
- created: z14.number().int().nonnegative(),
2704
- juniorOnly: z14.number().int().nonnegative(),
2705
- merged: z14.number().int().nonnegative(),
2706
- repository: z14.string().min(1)
2815
+ var pullRequestRepositoryStatsSchema = z15.object({
2816
+ closed: z15.number().int().nonnegative(),
2817
+ created: z15.number().int().nonnegative(),
2818
+ juniorOnly: z15.number().int().nonnegative(),
2819
+ merged: z15.number().int().nonnegative(),
2820
+ repository: z15.string().min(1)
2707
2821
  }).strict().transform((row) => {
2708
2822
  const terminal = row.merged + row.closed;
2709
2823
  return {
@@ -2711,33 +2825,33 @@ var pullRequestRepositoryStatsSchema = z14.object({
2711
2825
  mergeRate: terminal > 0 ? row.merged / terminal : void 0
2712
2826
  };
2713
2827
  });
2714
- var issueStatsSchema = z14.object({
2715
- closedCompleted: z14.number().int().nonnegative(),
2716
- closedDuplicate: z14.number().int().nonnegative(),
2717
- closedNotPlanned: z14.number().int().nonnegative(),
2718
- closedUnknown: z14.number().int().nonnegative(),
2719
- created: z14.number().int().nonnegative(),
2720
- days: z14.number().int().positive(),
2721
- medianCloseTimeMs: z14.number().nonnegative().nullable()
2828
+ var issueStatsSchema = z15.object({
2829
+ closedCompleted: z15.number().int().nonnegative(),
2830
+ closedDuplicate: z15.number().int().nonnegative(),
2831
+ closedNotPlanned: z15.number().int().nonnegative(),
2832
+ closedUnknown: z15.number().int().nonnegative(),
2833
+ created: z15.number().int().nonnegative(),
2834
+ days: z15.number().int().positive(),
2835
+ medianCloseTimeMs: z15.number().nonnegative().nullable()
2722
2836
  }).strict().transform((row) => ({
2723
2837
  ...row,
2724
2838
  medianCloseTimeMs: row.medianCloseTimeMs ?? void 0
2725
2839
  }));
2726
- var pullRequestDaySchema = z14.object({
2727
- created: z14.number().int().nonnegative(),
2728
- date: z14.string().date()
2840
+ var pullRequestDaySchema = z15.object({
2841
+ created: z15.number().int().nonnegative(),
2842
+ date: z15.string().date()
2729
2843
  }).strict();
2730
- var issueDaySchema = z14.object({
2731
- created: z14.number().int().nonnegative(),
2732
- date: z14.string().date()
2844
+ var issueDaySchema = z15.object({
2845
+ created: z15.number().int().nonnegative(),
2846
+ date: z15.string().date()
2733
2847
  }).strict();
2734
- var issueRepositoryStatsSchema = z14.object({
2735
- closedCompleted: z14.number().int().nonnegative(),
2736
- closedDuplicate: z14.number().int().nonnegative(),
2737
- closedNotPlanned: z14.number().int().nonnegative(),
2738
- closedUnknown: z14.number().int().nonnegative(),
2739
- created: z14.number().int().nonnegative(),
2740
- repository: z14.string().min(1)
2848
+ var issueRepositoryStatsSchema = z15.object({
2849
+ closedCompleted: z15.number().int().nonnegative(),
2850
+ closedDuplicate: z15.number().int().nonnegative(),
2851
+ closedNotPlanned: z15.number().int().nonnegative(),
2852
+ closedUnknown: z15.number().int().nonnegative(),
2853
+ created: z15.number().int().nonnegative(),
2854
+ repository: z15.string().min(1)
2741
2855
  }).strict();
2742
2856
  function queryRows2(result) {
2743
2857
  if (typeof result !== "object" || result === null || !("rows" in result) || !Array.isArray(result.rows)) {
@@ -2801,7 +2915,7 @@ async function aggregatePullRequestWindows(args) {
2801
2915
  GROUP BY windows.days
2802
2916
  ORDER BY windows.days
2803
2917
  `);
2804
- return z14.array(pullRequestStatsSchema).parse(queryRows2(result));
2918
+ return z15.array(pullRequestStatsSchema).parse(queryRows2(result));
2805
2919
  }
2806
2920
  async function aggregatePullRequestDays(args) {
2807
2921
  const end = new Date(args.nowMs);
@@ -2829,7 +2943,7 @@ async function aggregatePullRequestDays(args) {
2829
2943
  LEFT JOIN daily ON daily.day = days.day
2830
2944
  ORDER BY days.day
2831
2945
  `);
2832
- return z14.array(pullRequestDaySchema).parse(queryRows2(result));
2946
+ return z15.array(pullRequestDaySchema).parse(queryRows2(result));
2833
2947
  }
2834
2948
  async function aggregatePullRequestRepositories(args) {
2835
2949
  const start = new Date(args.nowMs - 30 * DAY_MS2);
@@ -2859,7 +2973,7 @@ async function aggregatePullRequestRepositories(args) {
2859
2973
  ORDER BY "merged" DESC, "created" DESC, "repository" ASC
2860
2974
  LIMIT 25
2861
2975
  `);
2862
- return z14.array(pullRequestRepositoryStatsSchema).parse(queryRows2(result));
2976
+ return z15.array(pullRequestRepositoryStatsSchema).parse(queryRows2(result));
2863
2977
  }
2864
2978
  async function aggregateIssueWindows(args) {
2865
2979
  const starts = WINDOWS.map(
@@ -2928,7 +3042,7 @@ async function aggregateIssueWindows(args) {
2928
3042
  GROUP BY windows.days
2929
3043
  ORDER BY windows.days
2930
3044
  `);
2931
- return z14.array(issueStatsSchema).parse(queryRows2(result));
3045
+ return z15.array(issueStatsSchema).parse(queryRows2(result));
2932
3046
  }
2933
3047
  async function aggregateIssueDays(args) {
2934
3048
  const end = new Date(args.nowMs);
@@ -2956,7 +3070,7 @@ async function aggregateIssueDays(args) {
2956
3070
  LEFT JOIN daily ON daily.day = days.day
2957
3071
  ORDER BY days.day
2958
3072
  `);
2959
- return z14.array(issueDaySchema).parse(queryRows2(result));
3073
+ return z15.array(issueDaySchema).parse(queryRows2(result));
2960
3074
  }
2961
3075
  async function aggregateIssueRepositories(args) {
2962
3076
  const start = new Date(args.nowMs - 30 * DAY_MS2);
@@ -2993,7 +3107,7 @@ async function aggregateIssueRepositories(args) {
2993
3107
  ORDER BY "created" DESC, "closedCompleted" DESC, "repository" ASC
2994
3108
  LIMIT 25
2995
3109
  `);
2996
- return z14.array(issueRepositoryStatsSchema).parse(queryRows2(result));
3110
+ return z15.array(issueRepositoryStatsSchema).parse(queryRows2(result));
2997
3111
  }
2998
3112
  function formatPercent(value) {
2999
3113
  return value === void 0 ? "\u2014" : `${Math.round(value * 100)}%`;
@@ -3157,18 +3271,18 @@ async function buildGitHubOutcomeReport(args) {
3157
3271
  }
3158
3272
 
3159
3273
  // src/pull-request-outcomes/commit-composition.ts
3160
- import { z as z15 } from "zod";
3161
- var canonicalCommitSchema = z15.object({
3162
- authorEmail: z15.string().nullable(),
3163
- authorLogin: z15.string().nullable()
3274
+ import { z as z16 } from "zod";
3275
+ var canonicalCommitSchema = z16.object({
3276
+ authorEmail: z16.string().nullable(),
3277
+ authorLogin: z16.string().nullable()
3164
3278
  }).strict();
3165
- var providerCommitSchema = z15.object({
3166
- author: z15.object({ login: z15.string() }).passthrough().nullable(),
3167
- commit: z15.object({
3168
- author: z15.object({ email: z15.string() }).passthrough().nullable()
3279
+ var providerCommitSchema = z16.object({
3280
+ author: z16.object({ login: z16.string() }).passthrough().nullable(),
3281
+ commit: z16.object({
3282
+ author: z16.object({ email: z16.string() }).passthrough().nullable()
3169
3283
  }).passthrough()
3170
3284
  }).passthrough();
3171
- var commitPageSchema = z15.array(providerCommitSchema).transform(
3285
+ var commitPageSchema = z16.array(providerCommitSchema).transform(
3172
3286
  (commits) => commits.map(
3173
3287
  (commit) => canonicalCommitSchema.parse({
3174
3288
  authorEmail: commit.commit.author?.email ?? null,
@@ -4192,10 +4306,18 @@ function githubApiWriteGrantName(method, upstreamUrl) {
4192
4306
  if ((method === "POST" || method === "DELETE") && /^\/repos\/[^/]+\/[^/]+\/pulls\/[^/]+\/requested_reviewers$/.test(pathname)) {
4193
4307
  return "installation-write";
4194
4308
  }
4309
+ if (method === "POST" && /^\/repos\/[^/]+\/[^/]+\/pulls\/[^/]+\/comments(?:\/[^/]+\/replies)?$/.test(
4310
+ pathname
4311
+ )) {
4312
+ return "installation-write";
4313
+ }
4314
+ if ((method === "PATCH" || method === "DELETE") && /^\/repos\/[^/]+\/[^/]+\/pulls\/comments\/[^/]+$/.test(pathname)) {
4315
+ return "installation-write";
4316
+ }
4195
4317
  if (/^\/repos\/[^/]+\/[^/]+\/pulls\/[^/]+\/reviews(?:\/[^/]+(?:\/(events|dismissals))?)?$/.test(
4196
4318
  pathname
4197
4319
  ) && !HTTP_READ_METHODS.has(method)) {
4198
- return "user-write";
4320
+ return "installation-write";
4199
4321
  }
4200
4322
  return void 0;
4201
4323
  }