@vercel/factory 0.0.15 → 0.0.17

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.
Files changed (214) hide show
  1. package/CHANGELOG.md +362 -0
  2. package/README.md +49 -261
  3. package/dist/agent-routes.d.mts +47 -3
  4. package/dist/agent-routes.mjs +28 -1
  5. package/dist/agent-routes.mjs.map +1 -1
  6. package/dist/api-contracts.d.mts +20 -1
  7. package/dist/api-contracts.mjs +2 -1
  8. package/dist/api-contracts.mjs.map +1 -1
  9. package/dist/api.d.mts +45 -2
  10. package/dist/api.mjs +199 -10
  11. package/dist/api.mjs.map +1 -1
  12. package/dist/approval-contracts.d.mts +6 -0
  13. package/dist/blob/index.d.mts +51 -14
  14. package/dist/blob/index.mjs +26 -10
  15. package/dist/blob/index.mjs.map +1 -1
  16. package/dist/budget.d.mts +7 -0
  17. package/dist/budget.mjs +6 -0
  18. package/dist/budget.mjs.map +1 -1
  19. package/dist/build-factory.d.mts +1 -0
  20. package/dist/change-verification/dispatch.d.mts +16 -3
  21. package/dist/change-verification/dispatch.mjs +45 -7
  22. package/dist/change-verification/dispatch.mjs.map +1 -1
  23. package/dist/change-verification/eve-tool.d.mts +2 -1
  24. package/dist/change-verification/eve-tool.mjs +35 -47
  25. package/dist/change-verification/eve-tool.mjs.map +1 -1
  26. package/dist/change-verification/result.mjs +130 -0
  27. package/dist/change-verification/result.mjs.map +1 -0
  28. package/dist/changes/eve-record-change.d.mts +2 -2
  29. package/dist/changes/eve-record-change.mjs +43 -9
  30. package/dist/changes/eve-record-change.mjs.map +1 -1
  31. package/dist/changes.d.mts +4 -3
  32. package/dist/changes.mjs +2 -2
  33. package/dist/changes.mjs.map +1 -1
  34. package/dist/client-events.d.mts +10 -3
  35. package/dist/client-events.mjs +6 -2
  36. package/dist/client-events.mjs.map +1 -1
  37. package/dist/client-stream.mjs +8 -2
  38. package/dist/client-stream.mjs.map +1 -1
  39. package/dist/client-transcript.mjs +5 -1
  40. package/dist/client-transcript.mjs.map +1 -1
  41. package/dist/client.d.mts +121 -12
  42. package/dist/client.mjs +117 -9
  43. package/dist/client.mjs.map +1 -1
  44. package/dist/code-review/contracts.d.mts +1 -0
  45. package/dist/code-review/eve-post-review.d.mts +4 -4
  46. package/dist/code-review/eve-post-review.mjs +29 -17
  47. package/dist/code-review/eve-post-review.mjs.map +1 -1
  48. package/dist/code-review/eve-review-comments.d.mts +13 -2
  49. package/dist/code-review/eve-review-comments.mjs +45 -11
  50. package/dist/code-review/eve-review-comments.mjs.map +1 -1
  51. package/dist/code-review/github-reporter.d.mts +2 -0
  52. package/dist/code-review/github-reporter.mjs +7 -5
  53. package/dist/code-review/github-reporter.mjs.map +1 -1
  54. package/dist/code-review.d.mts +3 -2
  55. package/dist/deepsec/eve-tool.mjs +3 -1
  56. package/dist/deepsec/eve-tool.mjs.map +1 -1
  57. package/dist/dispatch.d.mts +79 -8
  58. package/dist/dispatch.mjs +68 -9
  59. package/dist/dispatch.mjs.map +1 -1
  60. package/dist/eve/index.d.mts +70 -10
  61. package/dist/eve/index.mjs +93 -22
  62. package/dist/eve/index.mjs.map +1 -1
  63. package/dist/eve/invoke.mjs +24 -11
  64. package/dist/eve/invoke.mjs.map +1 -1
  65. package/dist/eve/session-client.d.mts +122 -4
  66. package/dist/eve/session-client.mjs +127 -13
  67. package/dist/eve/session-client.mjs.map +1 -1
  68. package/dist/eve/task-execution.d.mts +380 -0
  69. package/dist/eve/task-execution.mjs +57 -2
  70. package/dist/eve/task-execution.mjs.map +1 -1
  71. package/dist/eve/task-session.d.mts +44 -2
  72. package/dist/eve/task-session.mjs +44 -2
  73. package/dist/eve/task-session.mjs.map +1 -1
  74. package/dist/eve/transcript.mjs +5 -1
  75. package/dist/eve/transcript.mjs.map +1 -1
  76. package/dist/execution.d.mts +117 -9
  77. package/dist/execution.mjs +76 -6
  78. package/dist/execution.mjs.map +1 -1
  79. package/dist/finding-remediation/admission.d.mts +2 -0
  80. package/dist/finding-remediation/admission.mjs +4 -1
  81. package/dist/finding-remediation/admission.mjs.map +1 -1
  82. package/dist/findings.d.mts +1 -0
  83. package/dist/github-publication.d.mts +1 -0
  84. package/dist/github-publication.mjs +97 -84
  85. package/dist/github-publication.mjs.map +1 -1
  86. package/dist/github-transfer.d.mts +15 -6
  87. package/dist/github-transfer.mjs +214 -66
  88. package/dist/github-transfer.mjs.map +1 -1
  89. package/dist/github.d.mts +51 -11
  90. package/dist/github.mjs +126 -24
  91. package/dist/github.mjs.map +1 -1
  92. package/dist/inbox-activity.d.mts +53 -0
  93. package/dist/inbox-activity.mjs +41 -0
  94. package/dist/inbox-activity.mjs.map +1 -0
  95. package/dist/index.d.mts +3 -1
  96. package/dist/index.mjs +3 -2
  97. package/dist/intake-contracts.d.mts +0 -1
  98. package/dist/integrations/deepsec.d.mts +1 -0
  99. package/dist/integrations/github.d.mts +2 -2
  100. package/dist/integrations/github.mjs +2 -2
  101. package/dist/integrations/slack.d.mts +3 -1
  102. package/dist/integrations/slack.mjs +3 -1
  103. package/dist/integrations/vercel.d.mts +4 -2
  104. package/dist/integrations/vercel.mjs +3 -2
  105. package/dist/merge-resolution/eve-tools.d.mts +1 -0
  106. package/dist/merge-resolution/eve-tools.mjs +7 -2
  107. package/dist/merge-resolution/eve-tools.mjs.map +1 -1
  108. package/dist/model-settings.d.mts +41 -0
  109. package/dist/model-settings.mjs +35 -0
  110. package/dist/model-settings.mjs.map +1 -0
  111. package/dist/planning/reconcile.mjs +6 -0
  112. package/dist/planning/reconcile.mjs.map +1 -1
  113. package/dist/postgres/index.d.mts +43 -2
  114. package/dist/postgres/index.mjs +40 -2
  115. package/dist/postgres/index.mjs.map +1 -1
  116. package/dist/presets/software-development/dispatch.d.mts +4 -1
  117. package/dist/presets/software-development/dispatch.mjs +2 -1
  118. package/dist/presets/software-development/dispatch.mjs.map +1 -1
  119. package/dist/presets/software-development/task-communication.d.mts +1 -0
  120. package/dist/presets/software-development/task-communication.mjs +48 -11
  121. package/dist/presets/software-development/task-communication.mjs.map +1 -1
  122. package/dist/presets/software-development.d.mts +1 -0
  123. package/dist/pull-requests/github-publisher.d.mts +15 -1
  124. package/dist/pull-requests/github-publisher.mjs +61 -1
  125. package/dist/pull-requests/github-publisher.mjs.map +1 -1
  126. package/dist/pull-requests.d.mts +1 -0
  127. package/dist/sandbox/index.d.mts +1 -0
  128. package/dist/schema/agent-route.d.mts +19 -1
  129. package/dist/schema/agent-route.mjs +19 -1
  130. package/dist/schema/agent-route.mjs.map +1 -1
  131. package/dist/schema/factory-config.d.mts +27 -0
  132. package/dist/schema/factory-config.mjs +33 -3
  133. package/dist/schema/factory-config.mjs.map +1 -1
  134. package/dist/schema/repository.d.mts +4 -0
  135. package/dist/schema/repository.mjs +5 -1
  136. package/dist/schema/repository.mjs.map +1 -1
  137. package/dist/schema/session.d.mts +1 -0
  138. package/dist/schema/session.mjs +1 -0
  139. package/dist/schema/session.mjs.map +1 -1
  140. package/dist/schema/slack-pr-notifications.d.mts +12 -0
  141. package/dist/schema/slack-pr-notifications.mjs +11 -0
  142. package/dist/schema/slack-pr-notifications.mjs.map +1 -0
  143. package/dist/schema/task-graph.d.mts +39 -0
  144. package/dist/schema/task.d.mts +1 -0
  145. package/dist/schema/task.mjs +2 -1
  146. package/dist/schema/task.mjs.map +1 -1
  147. package/dist/schema/transcript.d.mts +6 -0
  148. package/dist/schema/transcript.mjs +2 -1
  149. package/dist/schema/transcript.mjs.map +1 -1
  150. package/dist/schema/work.d.mts +52 -3
  151. package/dist/schema/work.mjs.map +1 -1
  152. package/dist/session-previews.d.mts +76 -0
  153. package/dist/session-previews.mjs +55 -0
  154. package/dist/session-previews.mjs.map +1 -0
  155. package/dist/session-review.d.mts +120 -0
  156. package/dist/session-review.mjs +79 -0
  157. package/dist/session-review.mjs.map +1 -0
  158. package/dist/signal-triage.mjs +1 -1
  159. package/dist/signals.d.mts +1 -0
  160. package/dist/stall.d.mts +4 -1
  161. package/dist/stall.mjs +6 -2
  162. package/dist/stall.mjs.map +1 -1
  163. package/dist/store/driver.d.mts +1 -1
  164. package/dist/store/driver.mjs.map +1 -1
  165. package/dist/store/engine.d.mts +206 -8
  166. package/dist/store/engine.mjs +147 -13
  167. package/dist/store/engine.mjs.map +1 -1
  168. package/dist/store/memory.d.mts +18 -1
  169. package/dist/store/memory.mjs +18 -1
  170. package/dist/store/memory.mjs.map +1 -1
  171. package/dist/store/slack-pr-notifications.d.mts +44 -0
  172. package/dist/store/slack-pr-notifications.mjs +121 -0
  173. package/dist/store/slack-pr-notifications.mjs.map +1 -0
  174. package/dist/store/task-work.d.mts +121 -6
  175. package/dist/store/task-work.mjs +7 -4
  176. package/dist/store/task-work.mjs.map +1 -1
  177. package/dist/sweep.d.mts +28 -6
  178. package/dist/sweep.mjs +34 -6
  179. package/dist/sweep.mjs.map +1 -1
  180. package/dist/task-graph-view.d.mts +3 -0
  181. package/dist/tasks.d.mts +3 -3
  182. package/dist/tasks.mjs +3 -3
  183. package/dist/vercel-git.d.mts +35 -3
  184. package/dist/vercel-git.mjs +265 -33
  185. package/dist/vercel-git.mjs.map +1 -1
  186. package/dist/vercel-github-api.d.mts +103 -0
  187. package/dist/vercel-github-api.mjs +363 -0
  188. package/dist/vercel-github-api.mjs.map +1 -0
  189. package/dist/vercel.d.mts +3 -2
  190. package/dist/vercel.mjs +3 -2
  191. package/dist/vercel.mjs.map +1 -1
  192. package/dist/work-triage.d.mts +1 -0
  193. package/dist/workflows.d.mts +102 -4
  194. package/dist/workflows.mjs +55 -2
  195. package/dist/workflows.mjs.map +1 -1
  196. package/dist/workspace-files-git.d.mts +15 -0
  197. package/dist/workspace-files-git.mjs +61 -0
  198. package/dist/workspace-files-git.mjs.map +1 -0
  199. package/dist/workspace-files.d.mts +107 -0
  200. package/dist/workspace-files.mjs +74 -0
  201. package/dist/workspace-files.mjs.map +1 -0
  202. package/docs/getting-started.md +104 -0
  203. package/docs/index.md +100 -0
  204. package/docs/recipes/cancellation.md +215 -0
  205. package/docs/recipes/custom-workflow.md +153 -0
  206. package/docs/recipes/dependent-tasks.md +207 -0
  207. package/docs/recipes/eve-agent.md +277 -0
  208. package/docs/recipes/human-input.md +204 -0
  209. package/docs/recipes/persistence-recovery.md +268 -0
  210. package/docs/recipes/retry-recovery.md +241 -0
  211. package/docs/recipes/task-messaging.md +215 -0
  212. package/docs/recipes/typed-eve-result.md +161 -0
  213. package/docs/runtime-integration.md +137 -0
  214. package/package.json +20 -6
package/dist/github.d.mts CHANGED
@@ -14,12 +14,16 @@ interface NormalizeFactoryCommentInput extends FactoryMentionOptions {
14
14
  event: string;
15
15
  payload: unknown;
16
16
  }
17
+ /** Select addressed comments and optionally reply candidates whose ownership the caller must verify. */
18
+ interface NormalizeFactoryReviewCommentInput extends NormalizeFactoryCommentInput {
19
+ includeReplies?: boolean;
20
+ }
17
21
  /** Configured repositories and provider observations used to select one trusted repository. */
18
22
  interface ConfiguredEventRepositoryInput {
19
23
  configuredSlugs: readonly RepositorySlug[];
20
24
  eventSlugs: readonly (RepositorySlug | null)[];
21
25
  }
22
- /** Routing metadata extracted from an explicitly addressed pull-request review comment. */
26
+ /** Routing metadata extracted from an addressed inline comment or an opt-in reply candidate. */
23
27
  interface FactoryReviewComment {
24
28
  repositorySlug: RepositorySlug;
25
29
  pullRequestNumber: number;
@@ -40,8 +44,8 @@ interface FactoryQuestionReply {
40
44
  }
41
45
  /** Select the one configured repository consistently identified by a provider delivery. */
42
46
  declare function configuredEventRepositorySlug(input: ConfiguredEventRepositoryInput): RepositorySlug | null;
43
- /** Normalize an explicitly addressed inline review comment into trusted routing fields. */
44
- declare function normalizeFactoryReviewComment(input: NormalizeFactoryCommentInput): FactoryReviewComment | null;
47
+ /** Normalize addressed inline comments or opt-in reply candidates; callers must authenticate them. */
48
+ declare function normalizeFactoryReviewComment(input: NormalizeFactoryReviewCommentInput): FactoryReviewComment | null;
45
49
  /**
46
50
  * Strip the Factory mention from an issue comment body, returning null when the
47
51
  * comment does not address Factory. Exported so a caller reconciling a delivery
@@ -90,14 +94,17 @@ interface ReviewCommentTrustInput {
90
94
  interface ReadReviewCommentInput extends GitHubPullRequestTarget, ReviewCommentTrustInput {
91
95
  commentId: number;
92
96
  }
93
- /** Normalized inline review comment returned by GitHub. */
97
+ /** Normalized inline review comment, with a null author when GitHub no longer exposes it. */
94
98
  interface GitHubReviewComment {
95
99
  id: number;
96
100
  pullRequestNumber: number;
97
101
  body: string;
98
102
  url: string;
99
- author: string;
103
+ author: string | null;
104
+ /** GitHub account type when available, used to distinguish human requests from bot activity. */
105
+ authorType: string | null;
100
106
  inReplyToId: number | null;
107
+ reviewId: number | null;
101
108
  }
102
109
  /** Trusted inline comment and reply content used to post a threaded answer. */
103
110
  interface AnswerReviewCommentInput extends GitHubPullRequestTarget, ReviewCommentTrustInput {
@@ -122,6 +129,7 @@ type PullRequestReviewEvent = "APPROVE" | "REQUEST_CHANGES" | "COMMENT";
122
129
  /** One inline finding attached to a submitted pull-request review. */
123
130
  interface PullRequestReviewComment {
124
131
  path: string;
132
+ startLine?: number;
125
133
  line: number;
126
134
  body: string;
127
135
  }
@@ -138,13 +146,35 @@ interface SubmittedPullRequestReview {
138
146
  url: string;
139
147
  state: string;
140
148
  }
141
- /** Normalized issue-style comment from a pull-request conversation. */
149
+ /** Issue-style PR comment, with null author metadata when GitHub no longer exposes it. */
142
150
  interface GitHubIssueComment {
143
151
  id: number;
144
152
  body: string;
145
153
  url: string;
146
- author: string;
147
- authorType: "Bot" | "User" | "Organization";
154
+ author: string | null;
155
+ authorType: "Bot" | "User" | "Organization" | null;
156
+ }
157
+ /** Inline discussion entry with its review and source location, including replies. */
158
+ interface GitHubPullRequestDiscussionComment extends GitHubReviewComment {
159
+ path: string;
160
+ line: number | null;
161
+ }
162
+ /** Existing PR verdict, retaining null author or commit metadata when unavailable on GitHub. */
163
+ interface GitHubPullRequestDiscussionReview extends SubmittedPullRequestReview {
164
+ author: string | null;
165
+ body: string;
166
+ commitId: string | null;
167
+ }
168
+ /** One bounded page of untrusted PR conversation, inline comments, and prior verdicts. */
169
+ interface GitHubPullRequestDiscussionPage {
170
+ comments: readonly GitHubIssueComment[];
171
+ reviewComments: readonly GitHubPullRequestDiscussionComment[];
172
+ reviews: readonly GitHubPullRequestDiscussionReview[];
173
+ nextPage: number | null;
174
+ }
175
+ /** Pull request and one-based discussion page to read; each collection returns up to 50 entries. */
176
+ interface ListPullRequestDiscussionInput extends GitHubPullRequestTarget {
177
+ page?: number;
148
178
  }
149
179
  /** Repository and pull request whose issue-style comments should be listed. */
150
180
  type ListPullRequestCommentsInput = GitHubPullRequestTarget;
@@ -161,6 +191,12 @@ interface UpdatePullRequestCommentInput extends GitHubRepositoryRequest {
161
191
  interface PullRequestLabelInput extends GitHubPullRequestTarget {
162
192
  label: string;
163
193
  }
194
+ /** Repository label to create when absent, retaining any existing color and description. */
195
+ interface EnsureGitHubLabelInput extends GitHubRepositoryRequest {
196
+ name: string;
197
+ color: string;
198
+ description: string;
199
+ }
164
200
  /** Open Factory-authored pull request GitHub currently reports as conflicted. */
165
201
  interface ConflictedGitHubPullRequest extends GitHubPullRequestReference {
166
202
  headBranch: string;
@@ -249,8 +285,8 @@ interface GitHubCheckRun {
249
285
  }
250
286
  /** Refusal raised when an inline review-comment author lacks repository write access. */
251
287
  declare class GitHubReviewCommentAuthorError extends Error {
252
- readonly author: string;
253
- constructor(author: string);
288
+ readonly author: string | null;
289
+ constructor(author: string | null);
254
290
  }
255
291
  /**
256
292
  * The pull request advanced past the commit a review or fix was prepared
@@ -276,6 +312,8 @@ declare function updateCheckRun(input: UpdateCheckRunInput): Promise<GitHubCheck
276
312
  declare function listCheckRunsForRef(input: ListCheckRunsForRefInput): Promise<readonly GitHubCheckRun[]>;
277
313
  /** List every issue-style comment in a pull request conversation. */
278
314
  declare function listPullRequestComments(input: ListPullRequestCommentsInput): Promise<readonly GitHubIssueComment[]>;
315
+ /** Read a page of all PR discussion types without treating any author's text as authorization. */
316
+ declare function listPullRequestDiscussion(input: ListPullRequestDiscussionInput): Promise<GitHubPullRequestDiscussionPage>;
279
317
  /** Add one issue-style comment to a pull request conversation. */
280
318
  declare function createPullRequestComment(input: CreatePullRequestCommentInput): Promise<GitHubIssueComment>;
281
319
  /** Edit one issue-style pull request comment. */
@@ -308,6 +346,8 @@ declare function closePullRequest(input: GitHubPullRequestTarget): Promise<GitHu
308
346
  declare function listConflictedPullRequests(input: ListConflictedPullRequestsInput): Promise<readonly ConflictedGitHubPullRequest[]>;
309
347
  /** List open pull requests in a repository, newest first, to check for existing work before triage. */
310
348
  declare function listOpenPullRequests(input: ListOpenPullRequestsInput): Promise<readonly OpenPullRequest[]>;
349
+ /** Ensure a repository label exists, including when another publisher creates it concurrently. */
350
+ declare function ensureGitHubLabel(input: EnsureGitHubLabelInput): Promise<void>;
311
351
  /** Add one label to a pull request. */
312
352
  declare function addLabel(input: PullRequestLabelInput): Promise<readonly string[]>;
313
353
  /** Remove one label from a pull request. */
@@ -402,5 +442,5 @@ declare function normalizeGitHubPullRequestClosed(options: WebhookEvent): GitHub
402
442
  /** Normalize a completed, unsuccessful GitHub Actions run into a CI failure signal. */
403
443
  declare function normalizeGitHubWorkflowRunFailure(options: WebhookEvent): GitHubCiFailureSignal | null;
404
444
  //#endregion
405
- export { AnswerReviewCommentInput, CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunFields, CheckRunOutput, CheckRunProgressStatus, type CheckoutGitHubRepositoryInput, type CommittedGitChange, CompletedCheckRunFields, ConfiguredEventRepositoryInput, ConflictedGitHubPullRequest, CreateCheckRunInput, type CreateGitHubBranchInput, type CreateGitHubCommitInput, type CreateGitHubPublicationPullRequestInput, type CreateGitHubTreeInput, CreatePullRequestCommentInput, CreatePullRequestInput, type CreatedGitHubPublicationPullRequest, CreatedGitHubPullRequest, FactoryMentionOptions, FactoryQuestionReply, FactoryReviewComment, type FetchGitHubBundleInput, type FetchGitHubRefsInput, type GitHubAppFactoryInput, type GitHubAppInstallationToken, type GitHubAppLike, type GitHubAppPermissions, GitHubCheckRun, GitHubCheckoutConflictError, GitHubCiFailureSignal, type GitHubCommit, GitHubDefaultBranchPush, type GitHubGitTransport, GitHubIssueComment, GitHubIssueCommentRecord, GitHubIssueSignal, GitHubPublicationApiError, type GitHubPublicationClient, type GitHubPublicationClientOptions, type GitHubPublicationLimits, type GitHubPublicationPullRequest, GitHubPullRequest, GitHubPullRequestClosed, GitHubPullRequestHead, GitHubPullRequestReference, GitHubPullRequestSignal, GitHubPullRequestTarget, type GitHubRefMapping, GitHubRepositoryAuthorRequest, type GitHubRepositoryBundle, GitHubRepositoryRequest, GitHubReviewComment, GitHubReviewCommentAuthorError, type GitHubTreeDeletion, type GitHubTreeEntry, type GitHubTreeUpsert, type GitTransferSandbox, IncompleteCheckRunFields, ListCheckRunsForRefInput, ListConflictedPullRequestsInput, type ListGitHubPublicationPullRequestsInput, ListOpenPullRequestsInput, ListPullRequestCommentsInput, type MarkGitHubPullRequestReadyInput, type MintGitHubAppInstallationTokenInput, NormalizeFactoryCommentInput, ObservedCheckRunStatus, PullRequestLabelInput, PullRequestReviewComment, PullRequestReviewEvent, type PushGitHubBundleInput, type PushGitHubHeadInput, type ReadCommittedGitChangeInput, type ReadGitHubBranchHeadInput, type ReadGitHubCommitInput, type ReadGitHubPullRequestInput, type ReadGitTransferFileInput, ReadReviewCommentInput, ReviewCommentAuthorPolicy, type RunSandboxGitInput, type SandboxGit, type SandboxGitCommandInput, type SandboxGitCommandResult, StalePullRequestHeadError, SubmitPullRequestReviewInput, SubmittedPullRequestReview, UpdateCheckRunInput, type UpdateGitHubBranchInput, UpdatePullRequestCommentInput, VerifyGitHubSignatureInput, type WithSandboxGitBundleInput, type WriteGitTransferFileInput, addLabel, answerReviewComment, checkoutGitHubRepository, closePullRequest, configuredEventRepositorySlug, createCheckRun, createGitHubPublicationClient, createPullRequest, createPullRequestComment, factorySessionBranch, factoryTaskBranch, hasGitHubRepositoryWriteAccess, isSafeGitRef, listCheckRunsForRef, listConflictedPullRequests, listOpenPullRequests, listPullRequestComments, mintGitHubAppInstallationToken, normalizeFactoryQuestionReply, normalizeFactoryReviewComment, normalizeGitHubDefaultBranchPush, normalizeGitHubIssueOpened, normalizeGitHubPullRequest, normalizeGitHubPullRequestClosed, normalizeGitHubWorkflowRunFailure, readCommittedGitChange, readIssueComment, readPullRequest, readPullRequestHead, readReviewComment, removeLabel, runSandboxGit, stripFactoryQuestionMention, submitPullRequestReview, updateCheckRun, updatePullRequestComment, verifyGitHubSignature };
445
+ export { AnswerReviewCommentInput, CheckRunAnnotation, CheckRunAnnotationLevel, CheckRunConclusion, CheckRunFields, CheckRunOutput, CheckRunProgressStatus, type CheckoutGitHubRepositoryInput, type CommittedGitChange, CompletedCheckRunFields, ConfiguredEventRepositoryInput, ConflictedGitHubPullRequest, CreateCheckRunInput, type CreateGitHubBranchInput, type CreateGitHubCommitInput, type CreateGitHubPublicationPullRequestInput, type CreateGitHubTreeInput, CreatePullRequestCommentInput, CreatePullRequestInput, type CreatedGitHubPublicationPullRequest, CreatedGitHubPullRequest, EnsureGitHubLabelInput, FactoryMentionOptions, FactoryQuestionReply, FactoryReviewComment, type FetchGitHubBundleInput, type FetchGitHubRefsInput, type GitHubAppFactoryInput, type GitHubAppInstallationToken, type GitHubAppLike, type GitHubAppPermissions, GitHubCheckRun, GitHubCheckoutConflictError, GitHubCiFailureSignal, type GitHubCommit, GitHubDefaultBranchPush, type GitHubGitTransport, GitHubIssueComment, GitHubIssueCommentRecord, GitHubIssueSignal, GitHubPublicationApiError, type GitHubPublicationClient, type GitHubPublicationClientOptions, type GitHubPublicationLimits, type GitHubPublicationPullRequest, GitHubPullRequest, GitHubPullRequestClosed, GitHubPullRequestDiscussionComment, GitHubPullRequestDiscussionPage, GitHubPullRequestDiscussionReview, GitHubPullRequestHead, GitHubPullRequestReference, GitHubPullRequestSignal, GitHubPullRequestTarget, type GitHubRefMapping, GitHubRepositoryAuthorRequest, type GitHubRepositoryBundle, GitHubRepositoryRequest, GitHubReviewComment, GitHubReviewCommentAuthorError, type GitHubTreeDeletion, type GitHubTreeEntry, type GitHubTreeUpsert, type GitTransferSandbox, IncompleteCheckRunFields, ListCheckRunsForRefInput, ListConflictedPullRequestsInput, type ListGitHubPublicationPullRequestsInput, ListOpenPullRequestsInput, ListPullRequestCommentsInput, ListPullRequestDiscussionInput, type MarkGitHubPullRequestReadyInput, type MintGitHubAppInstallationTokenInput, NormalizeFactoryCommentInput, NormalizeFactoryReviewCommentInput, ObservedCheckRunStatus, PullRequestLabelInput, PullRequestReviewComment, PullRequestReviewEvent, type PushGitHubBundleInput, type PushGitHubHeadInput, type ReadCommittedGitChangeInput, type ReadGitHubBranchHeadInput, type ReadGitHubCommitInput, type ReadGitHubPullRequestInput, type ReadGitTransferFileInput, ReadReviewCommentInput, ReviewCommentAuthorPolicy, type RunSandboxGitInput, type SandboxGit, type SandboxGitCommandInput, type SandboxGitCommandResult, StalePullRequestHeadError, SubmitPullRequestReviewInput, SubmittedPullRequestReview, UpdateCheckRunInput, type UpdateGitHubBranchInput, UpdatePullRequestCommentInput, VerifyGitHubSignatureInput, type WithSandboxGitBundleInput, type WriteGitTransferFileInput, addLabel, answerReviewComment, checkoutGitHubRepository, closePullRequest, configuredEventRepositorySlug, createCheckRun, createGitHubPublicationClient, createPullRequest, createPullRequestComment, ensureGitHubLabel, factorySessionBranch, factoryTaskBranch, hasGitHubRepositoryWriteAccess, isSafeGitRef, listCheckRunsForRef, listConflictedPullRequests, listOpenPullRequests, listPullRequestComments, listPullRequestDiscussion, mintGitHubAppInstallationToken, normalizeFactoryQuestionReply, normalizeFactoryReviewComment, normalizeGitHubDefaultBranchPush, normalizeGitHubIssueOpened, normalizeGitHubPullRequest, normalizeGitHubPullRequestClosed, normalizeGitHubWorkflowRunFailure, readCommittedGitChange, readIssueComment, readPullRequest, readPullRequestHead, readReviewComment, removeLabel, runSandboxGit, stripFactoryQuestionMention, submitPullRequestReview, updateCheckRun, updatePullRequestComment, verifyGitHubSignature };
406
446
  //# sourceMappingURL=github.d.mts.map
package/dist/github.mjs CHANGED
@@ -11,7 +11,8 @@ const factoryReviewCommentEventSchema = z.looseObject({
11
11
  comment: z.looseObject({
12
12
  id: z.number().int().positive(),
13
13
  body: z.string(),
14
- html_url: z.url()
14
+ html_url: z.url(),
15
+ in_reply_to_id: z.number().int().positive().nullish()
15
16
  }),
16
17
  pull_request: z.looseObject({
17
18
  number: z.number().int().positive(),
@@ -61,11 +62,11 @@ function configuredEventRepositorySlug(input) {
61
62
  const eventSlug = distinctEventSlugs[0];
62
63
  return distinctEventSlugs.length === 1 && eventSlug !== void 0 && configuredSlugs.includes(eventSlug) ? eventSlug : null;
63
64
  }
64
- /** Normalize an explicitly addressed inline review comment into trusted routing fields. */
65
+ /** Normalize addressed inline comments or opt-in reply candidates; callers must authenticate them. */
65
66
  function normalizeFactoryReviewComment(input) {
66
67
  if (input.event !== "pull_request_review_comment") return null;
67
68
  const parsed = factoryReviewCommentEventSchema.safeParse(input.payload);
68
- if (!parsed.success || stripMention(parsed.data.comment.body, input.mentions ?? defaultReviewMentions) === null) return null;
69
+ if (!parsed.success || stripMention(parsed.data.comment.body, input.mentions ?? defaultReviewMentions) === null && !(input.includeReplies && parsed.data.comment.in_reply_to_id != null)) return null;
69
70
  return {
70
71
  repositorySlug: parsed.data.repository.full_name,
71
72
  pullRequestNumber: parsed.data.pull_request.number,
@@ -124,8 +125,12 @@ const reviewCommentSchema = z.object({
124
125
  body: z.string(),
125
126
  html_url: z.url(),
126
127
  pull_request_url: z.url(),
127
- user: z.object({ login: z.string().min(1) }),
128
- in_reply_to_id: z.number().int().positive().nullish()
128
+ user: z.object({
129
+ login: z.string().min(1),
130
+ type: z.string().optional()
131
+ }).nullable(),
132
+ in_reply_to_id: z.number().int().positive().nullish(),
133
+ pull_request_review_id: z.number().int().positive().nullish()
129
134
  });
130
135
  const submittedReviewSchema = z.object({
131
136
  id: z.number().int().positive(),
@@ -143,7 +148,7 @@ const issueCommentSchema = z.object({
143
148
  "User",
144
149
  "Organization"
145
150
  ])
146
- })
151
+ }).nullable()
147
152
  });
148
153
  const checkRunSchema = z.object({
149
154
  id: z.number().int().positive(),
@@ -220,7 +225,7 @@ const writePermissions = /* @__PURE__ */ new Set([
220
225
  var GitHubReviewCommentAuthorError = class extends Error {
221
226
  author;
222
227
  constructor(author) {
223
- super(`GitHub user ${author} does not have write access to the repository`);
228
+ super(author === null ? "GitHub review comment has no author to verify for repository write access" : `GitHub user ${author} does not have write access to the repository`);
224
229
  this.name = "GitHubReviewCommentAuthorError";
225
230
  this.author = author;
226
231
  }
@@ -302,6 +307,51 @@ async function listPullRequestComments(input) {
302
307
  if (response.length < 100) return comments;
303
308
  }
304
309
  }
310
+ /** Read a page of all PR discussion types without treating any author's text as authorization. */
311
+ async function listPullRequestDiscussion(input) {
312
+ const page = z.number().int().positive().parse(input.page ?? 1);
313
+ const number = positiveInteger(input.pullRequestNumber, "pullRequestNumber");
314
+ const query = `per_page=50&page=${page}`;
315
+ const [comments, reviewComments, reviews] = await Promise.all([
316
+ gitHubRequest(input, `/issues/${number}/comments?${query}`).then((value) => z.array(issueCommentSchema).max(50).parse(value).map(parseIssueComment)),
317
+ gitHubRequest(input, `/pulls/${number}/comments?${query}`).then((value) => z.array(reviewCommentSchema.extend({
318
+ pull_request_review_id: z.number().int().positive().nullable(),
319
+ path: z.string().min(1),
320
+ line: z.number().int().positive().nullish()
321
+ })).max(50).parse(value).map((entry) => {
322
+ const comment = parseReviewComment(entry);
323
+ assertReviewCommentPullRequest(input, comment);
324
+ return {
325
+ ...comment,
326
+ reviewId: entry.pull_request_review_id,
327
+ path: entry.path,
328
+ line: entry.line ?? null
329
+ };
330
+ })),
331
+ gitHubRequest(input, `/pulls/${number}/reviews?${query}`).then((value) => z.array(submittedReviewSchema.extend({
332
+ user: z.object({ login: z.string().min(1) }).nullable(),
333
+ body: z.string(),
334
+ commit_id: z.string().regex(/^[0-9a-f]{40}$/).nullable()
335
+ })).max(50).parse(value).map((review) => ({
336
+ id: review.id,
337
+ url: review.html_url,
338
+ state: review.state,
339
+ author: review.user?.login ?? null,
340
+ body: review.body,
341
+ commitId: review.commit_id
342
+ })))
343
+ ]);
344
+ return {
345
+ comments,
346
+ reviewComments,
347
+ reviews,
348
+ nextPage: [
349
+ comments,
350
+ reviewComments,
351
+ reviews
352
+ ].some((entries) => entries.length === 50) ? page + 1 : null
353
+ };
354
+ }
305
355
  /** Add one issue-style comment to a pull request conversation. */
306
356
  async function createPullRequestComment(input) {
307
357
  return parseIssueComment(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/comments`, {
@@ -329,8 +379,8 @@ async function readIssueComment(input) {
329
379
  return {
330
380
  id: comment.id,
331
381
  url: comment.html_url,
332
- author: comment.user.login,
333
- authorType: comment.user.type,
382
+ author: comment.user?.login ?? null,
383
+ authorType: comment.user?.type ?? null,
334
384
  body: comment.body,
335
385
  issueNumber
336
386
  };
@@ -344,8 +394,14 @@ async function readReviewComment(input) {
344
394
  }
345
395
  /** Reply to an inline review comment after applying the author policy, which requires write access by default. */
346
396
  async function answerReviewComment(input) {
347
- await readReviewComment(input);
348
- const reply = parseReviewComment(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/comments/${positiveInteger(input.commentId, "commentId")}/replies`, {
397
+ const comment = await readReviewComment(input);
398
+ const rootId = comment.inReplyToId ?? comment.id;
399
+ if (rootId !== comment.id) await readReviewComment({
400
+ ...input,
401
+ commentId: rootId,
402
+ authorPolicy: "any"
403
+ });
404
+ const reply = parseReviewComment(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/comments/${positiveInteger(rootId, "commentId")}/replies`, {
349
405
  method: "POST",
350
406
  body: JSON.stringify({ body: input.body })
351
407
  }));
@@ -355,6 +411,21 @@ async function answerReviewComment(input) {
355
411
  /** Submit a summary and optional inline comments against a reviewed pull request commit. */
356
412
  async function submitPullRequestReview(input) {
357
413
  const commitId = z.string().regex(/^[0-9a-f]{40}$/).parse(input.commitId);
414
+ const comments = (input.comments ?? []).map((comment) => {
415
+ const line = positiveInteger(comment.line, "comment line");
416
+ const startLine = comment.startLine === void 0 ? void 0 : positiveInteger(comment.startLine, "comment startLine");
417
+ if (startLine !== void 0 && startLine >= line) throw new Error("comment startLine must precede line; omit it for a single-line finding");
418
+ return {
419
+ path: comment.path,
420
+ line,
421
+ side: "RIGHT",
422
+ ...startLine === void 0 ? {} : {
423
+ start_line: startLine,
424
+ start_side: "RIGHT"
425
+ },
426
+ body: comment.body
427
+ };
428
+ });
358
429
  const head = await readPullRequestHead(input);
359
430
  if (head.sha !== commitId) throw new StalePullRequestHeadError(commitId, head.sha);
360
431
  const review = submittedReviewSchema.parse(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/reviews`, {
@@ -363,12 +434,7 @@ async function submitPullRequestReview(input) {
363
434
  commit_id: commitId,
364
435
  event: input.event,
365
436
  body: input.body,
366
- comments: (input.comments ?? []).map((comment) => ({
367
- path: comment.path,
368
- line: positiveInteger(comment.line, "comment line"),
369
- side: "RIGHT",
370
- body: comment.body
371
- }))
437
+ comments
372
438
  })
373
439
  }));
374
440
  return {
@@ -439,6 +505,33 @@ async function listOpenPullRequests(input) {
439
505
  draft: pull.draft
440
506
  }));
441
507
  }
508
+ /** Ensure a repository label exists, including when another publisher creates it concurrently. */
509
+ async function ensureGitHubLabel(input) {
510
+ const label = z.object({
511
+ name: z.string().trim().min(1).max(50),
512
+ color: z.string().regex(/^[a-fA-F0-9]{6}$/u),
513
+ description: z.string().max(100)
514
+ }).parse(input);
515
+ const path = `/labels/${encodeURIComponent(label.name)}`;
516
+ const read = async () => {
517
+ if (z.object({ name: z.string() }).parse(await gitHubRequest(input, path)).name.toLowerCase() !== label.name.toLowerCase()) throw new Error("GitHub returned a different repository label");
518
+ };
519
+ try {
520
+ await read();
521
+ return;
522
+ } catch (error) {
523
+ if (!(error instanceof GitHubRequestError) || error.status !== 404) throw error;
524
+ }
525
+ try {
526
+ await gitHubRequest(input, "/labels", {
527
+ method: "POST",
528
+ body: JSON.stringify(label)
529
+ });
530
+ } catch (error) {
531
+ if (!(error instanceof GitHubRequestError) || error.status !== 422) throw error;
532
+ await read();
533
+ }
534
+ }
442
535
  /** Add one label to a pull request. */
443
536
  async function addLabel(input) {
444
537
  return parseLabels(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/labels`, {
@@ -450,6 +543,13 @@ async function addLabel(input) {
450
543
  async function removeLabel(input) {
451
544
  return parseLabels(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/labels/${encodeURIComponent(input.label)}`, { method: "DELETE" }));
452
545
  }
546
+ var GitHubRequestError = class extends Error {
547
+ status;
548
+ constructor(status, message) {
549
+ super(`GitHub API request failed (${status}): ${message}`);
550
+ this.status = status;
551
+ }
552
+ };
453
553
  async function gitHubRequest(input, path, init = {}) {
454
554
  const repository = repositorySlugSchema.parse(input.repository);
455
555
  const response = await (input.fetch ?? globalThis.fetch)(`${gitHubApiUrl}/repos/${repository}${path}`, {
@@ -465,7 +565,7 @@ async function gitHubRequest(input, path, init = {}) {
465
565
  const body = await response.json();
466
566
  if (!response.ok) {
467
567
  const message = z.object({ message: z.string() }).safeParse(body);
468
- throw new Error(`GitHub API request failed (${response.status}): ${message.success ? message.data.message : response.statusText}`);
568
+ throw new GitHubRequestError(response.status, message.success ? message.data.message : response.statusText);
469
569
  }
470
570
  return body;
471
571
  }
@@ -478,8 +578,10 @@ function parseReviewComment(value) {
478
578
  pullRequestNumber: positiveInteger(Number(pullRequestMatch[1]), "pullRequestNumber"),
479
579
  body: comment.body,
480
580
  url: comment.html_url,
481
- author: comment.user.login,
482
- inReplyToId: comment.in_reply_to_id ?? null
581
+ author: comment.user?.login ?? null,
582
+ authorType: comment.user?.type ?? null,
583
+ inReplyToId: comment.in_reply_to_id ?? null,
584
+ reviewId: comment.pull_request_review_id ?? null
483
585
  };
484
586
  }
485
587
  function assertReviewCommentPullRequest(input, comment) {
@@ -492,8 +594,8 @@ function parseIssueComment(value) {
492
594
  id: comment.id,
493
595
  body: comment.body,
494
596
  url: comment.html_url,
495
- author: comment.user.login,
496
- authorType: comment.user.type
597
+ author: comment.user?.login ?? null,
598
+ authorType: comment.user?.type ?? null
497
599
  };
498
600
  }
499
601
  function parseLabels(value) {
@@ -553,7 +655,7 @@ function checkRunOutput(output) {
553
655
  }
554
656
  async function assertReviewCommentAuthor(input, author) {
555
657
  if (input.authorPolicy === "any") return;
556
- if (!await hasGitHubRepositoryWriteAccess({
658
+ if (author === null || !await hasGitHubRepositoryWriteAccess({
557
659
  ...input,
558
660
  author
559
661
  })) throw new GitHubReviewCommentAuthorError(author);
@@ -782,6 +884,6 @@ function normalizeGitHubWorkflowRunFailure(options) {
782
884
  };
783
885
  }
784
886
  //#endregion
785
- export { GitHubCheckoutConflictError, GitHubPublicationApiError, GitHubReviewCommentAuthorError, StalePullRequestHeadError, addLabel, answerReviewComment, checkoutGitHubRepository, closePullRequest, configuredEventRepositorySlug, createCheckRun, createGitHubPublicationClient, createPullRequest, createPullRequestComment, factorySessionBranch, factoryTaskBranch, hasGitHubRepositoryWriteAccess, isSafeGitRef, listCheckRunsForRef, listConflictedPullRequests, listOpenPullRequests, listPullRequestComments, mintGitHubAppInstallationToken, normalizeFactoryQuestionReply, normalizeFactoryReviewComment, normalizeGitHubDefaultBranchPush, normalizeGitHubIssueOpened, normalizeGitHubPullRequest, normalizeGitHubPullRequestClosed, normalizeGitHubWorkflowRunFailure, readCommittedGitChange, readIssueComment, readPullRequest, readPullRequestHead, readReviewComment, removeLabel, runSandboxGit, stripFactoryQuestionMention, submitPullRequestReview, updateCheckRun, updatePullRequestComment, verifyGitHubSignature };
887
+ export { GitHubCheckoutConflictError, GitHubPublicationApiError, GitHubReviewCommentAuthorError, StalePullRequestHeadError, addLabel, answerReviewComment, checkoutGitHubRepository, closePullRequest, configuredEventRepositorySlug, createCheckRun, createGitHubPublicationClient, createPullRequest, createPullRequestComment, ensureGitHubLabel, factorySessionBranch, factoryTaskBranch, hasGitHubRepositoryWriteAccess, isSafeGitRef, listCheckRunsForRef, listConflictedPullRequests, listOpenPullRequests, listPullRequestComments, listPullRequestDiscussion, mintGitHubAppInstallationToken, normalizeFactoryQuestionReply, normalizeFactoryReviewComment, normalizeGitHubDefaultBranchPush, normalizeGitHubIssueOpened, normalizeGitHubPullRequest, normalizeGitHubPullRequestClosed, normalizeGitHubWorkflowRunFailure, readCommittedGitChange, readIssueComment, readPullRequest, readPullRequestHead, readReviewComment, removeLabel, runSandboxGit, stripFactoryQuestionMention, submitPullRequestReview, updateCheckRun, updatePullRequestComment, verifyGitHubSignature };
786
888
 
787
889
  //# sourceMappingURL=github.mjs.map