@vercel/factory 0.0.14 → 0.0.16

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 (510) hide show
  1. package/CHANGELOG.md +356 -0
  2. package/README.md +96 -2
  3. package/dist/agent-routes.d.mts +113 -0
  4. package/dist/agent-routes.mjs +91 -0
  5. package/dist/agent-routes.mjs.map +1 -0
  6. package/dist/api-contracts.d.mts +1768 -0
  7. package/dist/api-contracts.mjs +119 -0
  8. package/dist/api-contracts.mjs.map +1 -0
  9. package/dist/api-images.d.mts +30 -0
  10. package/dist/api-images.mjs +28 -0
  11. package/dist/api-images.mjs.map +1 -0
  12. package/dist/api-task-graph.mjs +57 -0
  13. package/dist/api-task-graph.mjs.map +1 -0
  14. package/dist/api.d.mts +111 -216
  15. package/dist/api.mjs +1063 -99
  16. package/dist/api.mjs.map +1 -1
  17. package/dist/approval-access.d.mts +39 -0
  18. package/dist/approval-access.mjs +62 -0
  19. package/dist/approval-access.mjs.map +1 -0
  20. package/dist/approval-contracts.d.mts +698 -0
  21. package/dist/approval-contracts.mjs +27 -0
  22. package/dist/approval-contracts.mjs.map +1 -0
  23. package/dist/approval.d.mts +49 -0
  24. package/dist/approval.mjs +39 -0
  25. package/dist/approval.mjs.map +1 -0
  26. package/dist/blob/artifacts.d.mts +37 -0
  27. package/dist/blob/artifacts.mjs +45 -0
  28. package/dist/blob/artifacts.mjs.map +1 -0
  29. package/dist/blob/index.d.mts +84 -12
  30. package/dist/blob/index.mjs +179 -45
  31. package/dist/blob/index.mjs.map +1 -1
  32. package/dist/budget.d.mts +115 -0
  33. package/dist/budget.mjs +147 -0
  34. package/dist/budget.mjs.map +1 -0
  35. package/dist/budgets.d.mts +4 -0
  36. package/dist/budgets.mjs +4 -0
  37. package/dist/build-factory.d.mts +7 -4
  38. package/dist/build-factory.mjs +2 -1
  39. package/dist/build-factory.mjs.map +1 -1
  40. package/dist/change-verification/brief.d.mts +9 -0
  41. package/dist/change-verification/brief.mjs +13 -0
  42. package/dist/change-verification/brief.mjs.map +1 -0
  43. package/dist/change-verification/dispatch.d.mts +37 -0
  44. package/dist/change-verification/dispatch.mjs +83 -0
  45. package/dist/change-verification/dispatch.mjs.map +1 -0
  46. package/dist/change-verification/eve-tool.d.mts +61 -0
  47. package/dist/change-verification/eve-tool.mjs +89 -0
  48. package/dist/change-verification/eve-tool.mjs.map +1 -0
  49. package/dist/change-verification/result.mjs +130 -0
  50. package/dist/change-verification/result.mjs.map +1 -0
  51. package/dist/changes/eve-record-change.d.mts +56 -0
  52. package/dist/changes/eve-record-change.mjs +131 -0
  53. package/dist/changes/eve-record-change.mjs.map +1 -0
  54. package/dist/changes/presentation.d.mts +14 -0
  55. package/dist/changes.d.mts +24 -0
  56. package/dist/changes.mjs +29 -0
  57. package/dist/changes.mjs.map +1 -0
  58. package/dist/client-events.d.mts +25 -0
  59. package/dist/client-events.mjs +45 -0
  60. package/dist/client-events.mjs.map +1 -0
  61. package/dist/client-stream.d.mts +28 -0
  62. package/dist/client-stream.mjs +210 -0
  63. package/dist/client-stream.mjs.map +1 -0
  64. package/dist/client-transcript.d.mts +41 -0
  65. package/dist/client-transcript.mjs +233 -0
  66. package/dist/client-transcript.mjs.map +1 -0
  67. package/dist/client.d.mts +343 -0
  68. package/dist/client.mjs +366 -0
  69. package/dist/client.mjs.map +1 -0
  70. package/dist/code-review/contracts.d.mts +27 -0
  71. package/dist/code-review/eve-post-review.d.mts +70 -0
  72. package/dist/code-review/eve-post-review.mjs +195 -0
  73. package/dist/code-review/eve-post-review.mjs.map +1 -0
  74. package/dist/code-review/eve-review-comments.d.mts +75 -0
  75. package/dist/code-review/eve-review-comments.mjs +193 -0
  76. package/dist/code-review/eve-review-comments.mjs.map +1 -0
  77. package/dist/code-review/github-contracts.d.mts +10 -0
  78. package/dist/code-review/github-reporter.d.mts +46 -0
  79. package/dist/code-review/github-reporter.mjs +262 -0
  80. package/dist/code-review/github-reporter.mjs.map +1 -0
  81. package/dist/code-review/preparation.d.mts +34 -0
  82. package/dist/code-review/preparation.mjs +23 -0
  83. package/dist/code-review/preparation.mjs.map +1 -0
  84. package/dist/code-review/stall.d.mts +17 -0
  85. package/dist/code-review/stall.mjs +30 -0
  86. package/dist/code-review/stall.mjs.map +1 -0
  87. package/dist/code-review.d.mts +7 -0
  88. package/dist/code-review.mjs +5 -0
  89. package/dist/communication.d.mts +9 -0
  90. package/dist/communication.mjs +9 -0
  91. package/dist/connectors/github.d.mts +26 -0
  92. package/dist/connectors/github.mjs +55 -0
  93. package/dist/connectors/github.mjs.map +1 -0
  94. package/dist/connectors/index.d.mts +35 -3
  95. package/dist/connectors/index.mjs +3 -52
  96. package/dist/connectors/index.mjs.map +1 -1
  97. package/dist/connectors/outbox.d.mts +34 -0
  98. package/dist/connectors/outbox.mjs +50 -0
  99. package/dist/connectors/outbox.mjs.map +1 -0
  100. package/dist/connectors/slack-approval-blocks.mjs +136 -0
  101. package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
  102. package/dist/connectors/slack-approvals.d.mts +29 -0
  103. package/dist/connectors/slack-approvals.mjs +346 -0
  104. package/dist/connectors/slack-approvals.mjs.map +1 -0
  105. package/dist/connectors/slack.d.mts +35 -52
  106. package/dist/connectors/slack.mjs +13 -85
  107. package/dist/connectors/slack.mjs.map +1 -1
  108. package/dist/deepsec/eve-tool.d.mts +110 -0
  109. package/dist/deepsec/eve-tool.mjs +166 -0
  110. package/dist/deepsec/eve-tool.mjs.map +1 -0
  111. package/dist/deepsec/finding.d.mts +84 -0
  112. package/dist/deepsec/finding.mjs +56 -0
  113. package/dist/deepsec/finding.mjs.map +1 -0
  114. package/dist/deepsec.d.mts +3 -0
  115. package/dist/delivery-metrics/metrics.d.mts +93 -0
  116. package/dist/delivery-metrics/metrics.mjs +200 -0
  117. package/dist/delivery-metrics/metrics.mjs.map +1 -0
  118. package/dist/delivery-metrics.d.mts +2 -0
  119. package/dist/delivery-metrics.mjs +2 -0
  120. package/dist/dispatch.d.mts +152 -0
  121. package/dist/dispatch.mjs +199 -0
  122. package/dist/dispatch.mjs.map +1 -0
  123. package/dist/errors.d.mts +15 -0
  124. package/dist/errors.mjs +38 -0
  125. package/dist/errors.mjs.map +1 -0
  126. package/dist/eve/index.d.mts +209 -1277
  127. package/dist/eve/index.mjs +312 -1073
  128. package/dist/eve/index.mjs.map +1 -1
  129. package/dist/eve/invoke.d.mts +144 -0
  130. package/dist/eve/invoke.mjs +254 -0
  131. package/dist/eve/invoke.mjs.map +1 -0
  132. package/dist/eve/session-client.d.mts +186 -0
  133. package/dist/eve/session-client.mjs +245 -0
  134. package/dist/eve/session-client.mjs.map +1 -0
  135. package/dist/eve/task-execution.d.mts +380 -0
  136. package/dist/eve/task-execution.mjs +73 -0
  137. package/dist/eve/task-execution.mjs.map +1 -0
  138. package/dist/eve/task-session.d.mts +129 -0
  139. package/dist/eve/task-session.mjs +245 -0
  140. package/dist/eve/task-session.mjs.map +1 -0
  141. package/dist/eve/transcript.d.mts +37 -0
  142. package/dist/eve/transcript.mjs +69 -0
  143. package/dist/eve/transcript.mjs.map +1 -0
  144. package/dist/execution-public.d.mts +8 -0
  145. package/dist/execution-public.mjs +7 -0
  146. package/dist/execution.d.mts +183 -0
  147. package/dist/execution.mjs +223 -0
  148. package/dist/execution.mjs.map +1 -0
  149. package/dist/finding-remediation/admission.d.mts +53 -0
  150. package/dist/finding-remediation/admission.mjs +90 -0
  151. package/dist/finding-remediation/admission.mjs.map +1 -0
  152. package/dist/finding-remediation/brief.d.mts +14 -0
  153. package/dist/finding-remediation/brief.mjs +25 -0
  154. package/dist/finding-remediation/brief.mjs.map +1 -0
  155. package/dist/finding-remediation/eve-tool.d.mts +29 -0
  156. package/dist/finding-remediation/eve-tool.mjs +34 -0
  157. package/dist/finding-remediation/eve-tool.mjs.map +1 -0
  158. package/dist/findings/fingerprint.d.mts +14 -0
  159. package/dist/findings/fingerprint.mjs +28 -0
  160. package/dist/findings/fingerprint.mjs.map +1 -0
  161. package/dist/findings.d.mts +7 -0
  162. package/dist/findings.mjs +6 -0
  163. package/dist/github-app.d.mts +54 -0
  164. package/dist/github-app.mjs +121 -0
  165. package/dist/github-app.mjs.map +1 -0
  166. package/dist/github-publication.d.mts +199 -0
  167. package/dist/github-publication.mjs +442 -0
  168. package/dist/github-publication.mjs.map +1 -0
  169. package/dist/github-transfer.d.mts +81 -0
  170. package/dist/github-transfer.mjs +273 -0
  171. package/dist/github-transfer.mjs.map +1 -0
  172. package/dist/github.d.mts +446 -2
  173. package/dist/github.mjs +357 -56
  174. package/dist/github.mjs.map +1 -1
  175. package/dist/image-input.d.mts +51 -0
  176. package/dist/image-input.mjs +63 -0
  177. package/dist/image-input.mjs.map +1 -0
  178. package/dist/inbox-activity.d.mts +53 -0
  179. package/dist/inbox-activity.mjs +41 -0
  180. package/dist/inbox-activity.mjs.map +1 -0
  181. package/dist/index.d.mts +16 -484
  182. package/dist/index.mjs +15 -522
  183. package/dist/intake-contracts.d.mts +55 -0
  184. package/dist/intake-contracts.mjs +33 -0
  185. package/dist/intake-contracts.mjs.map +1 -0
  186. package/dist/integrations/deepsec.d.mts +5 -0
  187. package/dist/integrations/deepsec.mjs +3 -0
  188. package/dist/integrations/github.d.mts +11 -0
  189. package/dist/integrations/github.mjs +9 -0
  190. package/dist/integrations/slack.d.mts +5 -0
  191. package/dist/integrations/slack.mjs +5 -0
  192. package/dist/integrations/vercel.d.mts +5 -0
  193. package/dist/integrations/vercel.mjs +4 -0
  194. package/dist/merge-resolution/contracts.d.mts +17 -0
  195. package/dist/merge-resolution/contracts.mjs +19 -0
  196. package/dist/merge-resolution/contracts.mjs.map +1 -0
  197. package/dist/merge-resolution/eve-tools.d.mts +47 -0
  198. package/dist/merge-resolution/eve-tools.mjs +122 -0
  199. package/dist/merge-resolution/eve-tools.mjs.map +1 -0
  200. package/dist/model-settings.d.mts +41 -0
  201. package/dist/model-settings.mjs +35 -0
  202. package/dist/model-settings.mjs.map +1 -0
  203. package/dist/multi-repository-changes/coordination.d.mts +49 -0
  204. package/dist/multi-repository-changes/coordination.mjs +115 -0
  205. package/dist/multi-repository-changes/coordination.mjs.map +1 -0
  206. package/dist/planning/cancellation.mjs +82 -0
  207. package/dist/planning/cancellation.mjs.map +1 -0
  208. package/dist/planning/configuration.d.mts +23 -0
  209. package/dist/planning/configuration.mjs +56 -0
  210. package/dist/planning/configuration.mjs.map +1 -0
  211. package/dist/planning/contracts.d.mts +136 -0
  212. package/dist/planning/contracts.mjs +42 -0
  213. package/dist/planning/contracts.mjs.map +1 -0
  214. package/dist/planning/dependencies.mjs +44 -0
  215. package/dist/planning/dependencies.mjs.map +1 -0
  216. package/dist/planning/effects.mjs +122 -0
  217. package/dist/planning/effects.mjs.map +1 -0
  218. package/dist/planning/reconcile.mjs +279 -0
  219. package/dist/planning/reconcile.mjs.map +1 -0
  220. package/dist/planning/runtime.d.mts +27 -0
  221. package/dist/planning/runtime.mjs +25 -0
  222. package/dist/planning/runtime.mjs.map +1 -0
  223. package/dist/planning/state.mjs +92 -0
  224. package/dist/planning/state.mjs.map +1 -0
  225. package/dist/planning/turns.mjs +262 -0
  226. package/dist/planning/turns.mjs.map +1 -0
  227. package/dist/planning/validation.mjs +106 -0
  228. package/dist/planning/validation.mjs.map +1 -0
  229. package/dist/postgres/index.d.mts +48 -1
  230. package/dist/postgres/index.mjs +45 -3
  231. package/dist/postgres/index.mjs.map +1 -1
  232. package/dist/presets/software-development/approval.d.mts +14 -0
  233. package/dist/presets/software-development/approval.mjs +21 -0
  234. package/dist/presets/software-development/approval.mjs.map +1 -0
  235. package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
  236. package/dist/presets/software-development/deepsec-brief.mjs +14 -0
  237. package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
  238. package/dist/presets/software-development/dispatch.d.mts +56 -0
  239. package/dist/presets/software-development/dispatch.mjs +67 -0
  240. package/dist/presets/software-development/dispatch.mjs.map +1 -0
  241. package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
  242. package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
  243. package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
  244. package/dist/presets/software-development/eve.d.mts +18 -0
  245. package/dist/presets/software-development/eve.mjs +19 -0
  246. package/dist/presets/software-development/eve.mjs.map +1 -0
  247. package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
  248. package/dist/presets/software-development/finish-task-policy.mjs +9 -0
  249. package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
  250. package/dist/presets/software-development/recovery.d.mts +32 -0
  251. package/dist/presets/software-development/recovery.mjs +120 -0
  252. package/dist/presets/software-development/recovery.mjs.map +1 -0
  253. package/dist/presets/software-development/task-communication.d.mts +24 -0
  254. package/dist/presets/software-development/task-communication.mjs +157 -0
  255. package/dist/presets/software-development/task-communication.mjs.map +1 -0
  256. package/dist/presets/software-development.d.mts +10 -0
  257. package/dist/presets/software-development.mjs +9 -0
  258. package/dist/pull-requests/contracts.d.mts +72 -0
  259. package/dist/pull-requests/eve-fetch.d.mts +57 -0
  260. package/dist/pull-requests/eve-fetch.mjs +151 -0
  261. package/dist/pull-requests/eve-fetch.mjs.map +1 -0
  262. package/dist/pull-requests/github-label-manager.d.mts +27 -0
  263. package/dist/pull-requests/github-label-manager.mjs +40 -0
  264. package/dist/pull-requests/github-label-manager.mjs.map +1 -0
  265. package/dist/pull-requests/github-publisher.d.mts +67 -0
  266. package/dist/pull-requests/github-publisher.mjs +405 -0
  267. package/dist/pull-requests/github-publisher.mjs.map +1 -0
  268. package/dist/pull-requests.d.mts +6 -0
  269. package/dist/pull-requests.mjs +4 -0
  270. package/dist/receipts.d.mts +4 -0
  271. package/dist/receipts.mjs +3 -0
  272. package/dist/repositories.d.mts +18 -0
  273. package/dist/repositories.mjs +33 -0
  274. package/dist/repositories.mjs.map +1 -0
  275. package/dist/sandbox/command.d.mts +18 -0
  276. package/dist/sandbox/execution-abort.d.mts +16 -0
  277. package/dist/sandbox/execution-abort.mjs +49 -0
  278. package/dist/sandbox/execution-abort.mjs.map +1 -0
  279. package/dist/sandbox/execution-environment.d.mts +25 -0
  280. package/dist/sandbox/execution-run-ledger.d.mts +115 -0
  281. package/dist/sandbox/execution-run-ledger.mjs +209 -0
  282. package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
  283. package/dist/sandbox/execution.d.mts +54 -0
  284. package/dist/sandbox/execution.mjs +228 -0
  285. package/dist/sandbox/execution.mjs.map +1 -0
  286. package/dist/sandbox/harness-runner.d.mts +79 -0
  287. package/dist/sandbox/harness-runner.mjs +162 -0
  288. package/dist/sandbox/harness-runner.mjs.map +1 -0
  289. package/dist/sandbox/index.d.mts +10 -0
  290. package/dist/sandbox/index.mjs +7 -0
  291. package/dist/sandbox/task-environment.d.mts +50 -0
  292. package/dist/sandbox/task-environment.mjs +140 -0
  293. package/dist/sandbox/task-environment.mjs.map +1 -0
  294. package/dist/sandbox/workspace.d.mts +29 -0
  295. package/dist/sandbox/workspace.mjs +28 -0
  296. package/dist/sandbox/workspace.mjs.map +1 -0
  297. package/dist/schema/agent-route.d.mts +40 -0
  298. package/dist/schema/agent-route.mjs +33 -0
  299. package/dist/schema/agent-route.mjs.map +1 -0
  300. package/dist/schema/answer.d.mts +23 -0
  301. package/dist/schema/answer.mjs +21 -0
  302. package/dist/schema/answer.mjs.map +1 -0
  303. package/dist/schema/budget.d.mts +38 -0
  304. package/dist/schema/budget.mjs +30 -0
  305. package/dist/schema/budget.mjs.map +1 -0
  306. package/dist/schema/catalog.mjs +72 -0
  307. package/dist/schema/catalog.mjs.map +1 -0
  308. package/dist/schema/change.d.mts +117 -0
  309. package/dist/schema/change.mjs +68 -0
  310. package/dist/schema/change.mjs.map +1 -0
  311. package/dist/schema/common.d.mts +33 -0
  312. package/dist/{id-BLIkCVue.mjs → schema/common.mjs} +7 -16
  313. package/dist/schema/common.mjs.map +1 -0
  314. package/dist/schema/communication.d.mts +52 -0
  315. package/dist/{communication-Kd9nU5RP.mjs → schema/communication.mjs} +8 -3
  316. package/dist/schema/communication.mjs.map +1 -0
  317. package/dist/schema/execution.d.mts +101 -0
  318. package/dist/schema/execution.mjs +86 -0
  319. package/dist/schema/execution.mjs.map +1 -0
  320. package/dist/schema/factory-config.d.mts +122 -0
  321. package/dist/schema/factory-config.mjs +90 -0
  322. package/dist/schema/factory-config.mjs.map +1 -0
  323. package/dist/schema/finding.d.mts +125 -0
  324. package/dist/schema/finding.mjs +67 -0
  325. package/dist/schema/finding.mjs.map +1 -0
  326. package/dist/schema/id.d.mts +43 -0
  327. package/dist/schema/id.mjs +32 -0
  328. package/dist/schema/id.mjs.map +1 -0
  329. package/dist/schema/outbox.d.mts +240 -0
  330. package/dist/schema/outbox.mjs +53 -0
  331. package/dist/schema/outbox.mjs.map +1 -0
  332. package/dist/schema/question-route.mjs +16 -0
  333. package/dist/schema/question-route.mjs.map +1 -0
  334. package/dist/schema/receipt.d.mts +81 -0
  335. package/dist/schema/receipt.mjs +94 -0
  336. package/dist/schema/receipt.mjs.map +1 -0
  337. package/dist/schema/repository.d.mts +30 -0
  338. package/dist/schema/repository.mjs +29 -0
  339. package/dist/schema/repository.mjs.map +1 -0
  340. package/dist/schema/session.d.mts +136 -0
  341. package/dist/schema/session.mjs +54 -0
  342. package/dist/schema/session.mjs.map +1 -0
  343. package/dist/schema/signal.d.mts +105 -0
  344. package/dist/schema/signal.mjs +81 -0
  345. package/dist/schema/signal.mjs.map +1 -0
  346. package/dist/schema/slack-pr-notifications.d.mts +12 -0
  347. package/dist/schema/slack-pr-notifications.mjs +11 -0
  348. package/dist/schema/slack-pr-notifications.mjs.map +1 -0
  349. package/dist/schema/stored-session.mjs +10 -0
  350. package/dist/schema/stored-session.mjs.map +1 -0
  351. package/dist/schema/stored-task.mjs +20 -0
  352. package/dist/schema/stored-task.mjs.map +1 -0
  353. package/dist/schema/task-effect.d.mts +39 -0
  354. package/dist/schema/task-effect.mjs +29 -0
  355. package/dist/schema/task-effect.mjs.map +1 -0
  356. package/dist/schema/task-graph.d.mts +3173 -0
  357. package/dist/schema/task-graph.mjs +97 -0
  358. package/dist/schema/task-graph.mjs.map +1 -0
  359. package/dist/schema/task-message.d.mts +254 -0
  360. package/dist/schema/task-message.mjs +189 -0
  361. package/dist/schema/task-message.mjs.map +1 -0
  362. package/dist/schema/task.d.mts +273 -0
  363. package/dist/schema/task.mjs +200 -0
  364. package/dist/schema/task.mjs.map +1 -0
  365. package/dist/schema/transcript.d.mts +176 -0
  366. package/dist/schema/transcript.mjs +87 -0
  367. package/dist/schema/transcript.mjs.map +1 -0
  368. package/dist/schema/transitions.d.mts +50 -0
  369. package/dist/schema/transitions.mjs +303 -0
  370. package/dist/schema/transitions.mjs.map +1 -0
  371. package/dist/schema/work.d.mts +150 -0
  372. package/dist/schema/work.mjs +102 -0
  373. package/dist/schema/work.mjs.map +1 -0
  374. package/dist/session-previews.d.mts +76 -0
  375. package/dist/session-previews.mjs +55 -0
  376. package/dist/session-previews.mjs.map +1 -0
  377. package/dist/session-review.d.mts +120 -0
  378. package/dist/session-review.mjs +79 -0
  379. package/dist/session-review.mjs.map +1 -0
  380. package/dist/signal-triage.d.mts +20 -0
  381. package/dist/signal-triage.mjs +85 -0
  382. package/dist/signal-triage.mjs.map +1 -0
  383. package/dist/signals.d.mts +20 -0
  384. package/dist/signals.mjs +19 -0
  385. package/dist/signals.mjs.map +1 -0
  386. package/dist/stall.d.mts +41 -0
  387. package/dist/stall.mjs +83 -0
  388. package/dist/stall.mjs.map +1 -0
  389. package/dist/storage.d.mts +4 -0
  390. package/dist/storage.mjs +4 -0
  391. package/dist/store/driver.d.mts +65 -0
  392. package/dist/store/driver.mjs +42 -0
  393. package/dist/store/driver.mjs.map +1 -0
  394. package/dist/store/engine.d.mts +683 -0
  395. package/dist/store/engine.mjs +2309 -0
  396. package/dist/store/engine.mjs.map +1 -0
  397. package/dist/store/memory.d.mts +24 -0
  398. package/dist/store/memory.mjs +69 -0
  399. package/dist/store/memory.mjs.map +1 -0
  400. package/dist/store/slack-pr-notifications.d.mts +44 -0
  401. package/dist/store/slack-pr-notifications.mjs +121 -0
  402. package/dist/store/slack-pr-notifications.mjs.map +1 -0
  403. package/dist/store/task-effects.d.mts +38 -0
  404. package/dist/store/task-effects.mjs +118 -0
  405. package/dist/store/task-effects.mjs.map +1 -0
  406. package/dist/store/task-graphs.d.mts +60 -0
  407. package/dist/store/task-graphs.mjs +212 -0
  408. package/dist/store/task-graphs.mjs.map +1 -0
  409. package/dist/store/task-messages.d.mts +136 -0
  410. package/dist/store/task-messages.mjs +475 -0
  411. package/dist/store/task-messages.mjs.map +1 -0
  412. package/dist/store/task-work.d.mts +180 -0
  413. package/dist/store/task-work.mjs +137 -0
  414. package/dist/store/task-work.mjs.map +1 -0
  415. package/dist/store/work-notifications.d.mts +19 -0
  416. package/dist/store/work-notifications.mjs +48 -0
  417. package/dist/store/work-notifications.mjs.map +1 -0
  418. package/dist/sweep.d.mts +79 -0
  419. package/dist/sweep.mjs +171 -0
  420. package/dist/sweep.mjs.map +1 -0
  421. package/dist/task-communication.d.mts +35 -0
  422. package/dist/task-communication.mjs +47 -0
  423. package/dist/task-communication.mjs.map +1 -0
  424. package/dist/task-graph-view.d.mts +267 -0
  425. package/dist/task-graph-view.mjs +17 -0
  426. package/dist/task-graph-view.mjs.map +1 -0
  427. package/dist/task-message-processing.d.mts +60 -0
  428. package/dist/task-message-processing.mjs +200 -0
  429. package/dist/task-message-processing.mjs.map +1 -0
  430. package/dist/task-protocols.d.mts +80 -0
  431. package/dist/task-protocols.mjs +47 -0
  432. package/dist/task-protocols.mjs.map +1 -0
  433. package/dist/tasks.d.mts +17 -0
  434. package/dist/tasks.mjs +17 -0
  435. package/dist/vercel-git.d.mts +53 -0
  436. package/dist/vercel-git.mjs +344 -0
  437. package/dist/vercel-git.mjs.map +1 -0
  438. package/dist/vercel-github-api.d.mts +103 -0
  439. package/dist/vercel-github-api.mjs +363 -0
  440. package/dist/vercel-github-api.mjs.map +1 -0
  441. package/dist/vercel.d.mts +34 -2
  442. package/dist/vercel.mjs +49 -3
  443. package/dist/vercel.mjs.map +1 -1
  444. package/dist/work-triage/eve-tool.d.mts +29 -0
  445. package/dist/work-triage/eve-tool.mjs +32 -0
  446. package/dist/work-triage/eve-tool.mjs.map +1 -0
  447. package/dist/work-triage/find-existing-work.d.mts +32 -0
  448. package/dist/work-triage/find-existing-work.mjs +31 -0
  449. package/dist/work-triage/find-existing-work.mjs.map +1 -0
  450. package/dist/work-triage/github.d.mts +15 -0
  451. package/dist/work-triage/github.mjs +14 -0
  452. package/dist/work-triage/github.mjs.map +1 -0
  453. package/dist/work-triage.d.mts +4 -0
  454. package/dist/work-triage.mjs +3 -0
  455. package/dist/workflows.d.mts +146 -0
  456. package/dist/workflows.mjs +139 -0
  457. package/dist/workflows.mjs.map +1 -0
  458. package/dist/workspace-diff-assembly.d.mts +33 -0
  459. package/dist/workspace-diff-assembly.mjs +95 -0
  460. package/dist/workspace-diff-assembly.mjs.map +1 -0
  461. package/dist/workspace-diff.d.mts +90 -0
  462. package/dist/workspace-diff.mjs +61 -0
  463. package/dist/workspace-diff.mjs.map +1 -0
  464. package/dist/workspace-files-git.d.mts +15 -0
  465. package/dist/workspace-files-git.mjs +61 -0
  466. package/dist/workspace-files-git.mjs.map +1 -0
  467. package/dist/workspace-files.d.mts +107 -0
  468. package/dist/workspace-files.mjs +74 -0
  469. package/dist/workspace-files.mjs.map +1 -0
  470. package/dist/workspace-snapshot.d.mts +26 -0
  471. package/dist/workspace-snapshot.mjs +80 -0
  472. package/dist/workspace-snapshot.mjs.map +1 -0
  473. package/docs/getting-started.md +104 -0
  474. package/docs/index.md +100 -0
  475. package/docs/recipes/cancellation.md +215 -0
  476. package/docs/recipes/custom-workflow.md +153 -0
  477. package/docs/recipes/dependent-tasks.md +207 -0
  478. package/docs/recipes/eve-agent.md +277 -0
  479. package/docs/recipes/human-input.md +204 -0
  480. package/docs/recipes/persistence-recovery.md +268 -0
  481. package/docs/recipes/retry-recovery.md +241 -0
  482. package/docs/recipes/task-messaging.md +215 -0
  483. package/docs/recipes/typed-eve-result.md +161 -0
  484. package/docs/runtime-integration.md +137 -0
  485. package/package.json +142 -46
  486. package/dist/approval-JX2Px9IC.mjs +0 -132
  487. package/dist/approval-JX2Px9IC.mjs.map +0 -1
  488. package/dist/budget-DzSiIA4t.mjs +0 -42
  489. package/dist/budget-DzSiIA4t.mjs.map +0 -1
  490. package/dist/change-D2U6v7Ek.mjs +0 -554
  491. package/dist/change-D2U6v7Ek.mjs.map +0 -1
  492. package/dist/communication-Kd9nU5RP.mjs.map +0 -1
  493. package/dist/coordination-Cq08hb1l.mjs +0 -76
  494. package/dist/coordination-Cq08hb1l.mjs.map +0 -1
  495. package/dist/dispatch-BaZS3PT8.d.mts +0 -76
  496. package/dist/driver-BC0Mt5KG.d.mts +0 -34
  497. package/dist/driver-Bbd25rNM.mjs +0 -23
  498. package/dist/driver-Bbd25rNM.mjs.map +0 -1
  499. package/dist/engine-DFHU2Pe-.d.mts +0 -781
  500. package/dist/engine-WaUM2cGA.mjs +0 -1068
  501. package/dist/engine-WaUM2cGA.mjs.map +0 -1
  502. package/dist/factory-config-BoRXOw43.mjs +0 -50
  503. package/dist/factory-config-BoRXOw43.mjs.map +0 -1
  504. package/dist/factory-config-D2yU3G0c.d.mts +0 -58
  505. package/dist/github-C5HNBN6p.d.mts +0 -279
  506. package/dist/id-BLIkCVue.mjs.map +0 -1
  507. package/dist/index-Bw6hggoH.d.mts +0 -40
  508. package/dist/index.mjs.map +0 -1
  509. package/dist/task-CcOyOJ3k.mjs +0 -154
  510. package/dist/task-CcOyOJ3k.mjs.map +0 -1
package/dist/github.mjs CHANGED
@@ -1,27 +1,136 @@
1
- import { z } from "zod";
1
+ import { repositorySlugSchema } from "./schema/repository.mjs";
2
+ import { mintGitHubAppInstallationToken } from "./github-app.mjs";
3
+ import { GitHubCheckoutConflictError, GitHubPublicationApiError, checkoutGitHubRepository, createGitHubPublicationClient, factorySessionBranch, factoryTaskBranch, isSafeGitRef, readCommittedGitChange, runSandboxGit } from "./github-publication.mjs";
2
4
  import { createHmac, timingSafeEqual } from "node:crypto";
5
+ import { z } from "zod";
3
6
  //#region src/github.ts
4
7
  const gitHubApiUrl = "https://api.github.com";
5
- const repositorySlugPattern = /^[^/\s]+\/[^/\s]+$/;
8
+ const gitHubRepositorySlugSchema = z.string().min(1).transform((value) => value.toLowerCase()).pipe(repositorySlugSchema);
9
+ const factoryReviewCommentEventSchema = z.looseObject({
10
+ action: z.literal("created"),
11
+ comment: z.looseObject({
12
+ id: z.number().int().positive(),
13
+ body: z.string(),
14
+ html_url: z.url(),
15
+ in_reply_to_id: z.number().int().positive().nullish()
16
+ }),
17
+ pull_request: z.looseObject({
18
+ number: z.number().int().positive(),
19
+ html_url: z.url(),
20
+ user: z.looseObject({ login: z.string().min(1) })
21
+ }),
22
+ repository: z.looseObject({ full_name: gitHubRepositorySlugSchema })
23
+ });
24
+ const factoryQuestionReplyEventSchema = z.looseObject({
25
+ action: z.literal("created"),
26
+ comment: z.looseObject({
27
+ body: z.string(),
28
+ html_url: z.url(),
29
+ id: z.number().int().positive()
30
+ }),
31
+ issue: z.looseObject({
32
+ number: z.number().int().positive(),
33
+ pull_request: z.unknown().optional()
34
+ }),
35
+ repository: z.looseObject({ full_name: gitHubRepositorySlugSchema }),
36
+ sender: z.looseObject({
37
+ login: z.string().min(1),
38
+ type: z.string().min(1)
39
+ })
40
+ });
41
+ const defaultReviewMentions = ["factory"];
42
+ const defaultQuestionMentions = [
43
+ "agent-factory",
44
+ "agent-factory[bot]",
45
+ "factory"
46
+ ];
47
+ function stripMention(body, mentions) {
48
+ const trimmed = body.trimStart();
49
+ for (const mention of mentions) {
50
+ const prefix = `@${mention.trim()}`;
51
+ if (prefix === "@" || trimmed.slice(0, prefix.length).toLowerCase() !== prefix.toLowerCase()) continue;
52
+ const remainder = trimmed.slice(prefix.length);
53
+ if (!/^[\s,:-]/u.test(remainder)) continue;
54
+ return remainder.replace(/^[\s,:-]*/u, "").trim();
55
+ }
56
+ return null;
57
+ }
58
+ /** Select the one configured repository consistently identified by a provider delivery. */
59
+ function configuredEventRepositorySlug(input) {
60
+ const { configuredSlugs, eventSlugs } = input;
61
+ const distinctEventSlugs = [...new Set(eventSlugs.filter((slug) => slug !== null))];
62
+ const eventSlug = distinctEventSlugs[0];
63
+ return distinctEventSlugs.length === 1 && eventSlug !== void 0 && configuredSlugs.includes(eventSlug) ? eventSlug : null;
64
+ }
65
+ /** Normalize addressed inline comments or opt-in reply candidates; callers must authenticate them. */
66
+ function normalizeFactoryReviewComment(input) {
67
+ if (input.event !== "pull_request_review_comment") return null;
68
+ const parsed = factoryReviewCommentEventSchema.safeParse(input.payload);
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;
70
+ return {
71
+ repositorySlug: parsed.data.repository.full_name,
72
+ pullRequestNumber: parsed.data.pull_request.number,
73
+ pullRequestUrl: parsed.data.pull_request.html_url,
74
+ pullRequestAuthor: parsed.data.pull_request.user.login,
75
+ commentId: parsed.data.comment.id,
76
+ commentUrl: parsed.data.comment.html_url
77
+ };
78
+ }
79
+ /**
80
+ * Strip the Factory mention from an issue comment body, returning null when the
81
+ * comment does not address Factory. Exported so a caller reconciling a delivery
82
+ * against GitHub's own copy of the comment applies the same rule the normalizer
83
+ * applied to the payload.
84
+ */
85
+ function stripFactoryQuestionMention(body, options = {}) {
86
+ return stripMention(body, options.mentions ?? defaultQuestionMentions);
87
+ }
88
+ /** Normalize a mentioned issue comment that can answer a persisted Factory QuestionTask. */
89
+ function normalizeFactoryQuestionReply(input) {
90
+ if (input.event !== "issue_comment") return null;
91
+ const parsed = factoryQuestionReplyEventSchema.safeParse(input.payload);
92
+ if (!parsed.success || parsed.data.sender.type.toLowerCase() === "bot") return null;
93
+ const answer = stripMention(parsed.data.comment.body, input.mentions ?? defaultQuestionMentions);
94
+ if (answer === null || answer === "") return null;
95
+ if (parsed.data.issue.pull_request !== void 0) return null;
96
+ const repositorySlug = parsed.data.repository.full_name;
97
+ return {
98
+ repositorySlug,
99
+ replyAddress: `${repositorySlug}#${parsed.data.issue.number}`,
100
+ author: parsed.data.sender.login,
101
+ answer,
102
+ commentId: parsed.data.comment.id,
103
+ issueNumber: parsed.data.issue.number,
104
+ commentUrl: parsed.data.comment.html_url
105
+ };
106
+ }
6
107
  const pullRequestSchema = z.object({
7
108
  number: z.number().int().positive(),
8
109
  html_url: z.url()
9
110
  });
10
111
  const readablePullRequestSchema = pullRequestSchema.extend({
11
112
  state: z.enum(["open", "closed"]),
12
- user: z.object({ login: z.string().min(1) })
113
+ user: z.object({
114
+ login: z.string().min(1),
115
+ type: z.string().optional()
116
+ })
13
117
  });
14
118
  const pullRequestHeadSchema = z.object({ head: z.object({
15
119
  ref: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._/-]*$/).refine((value) => !value.includes("..")),
16
120
  sha: z.string().regex(/^[0-9a-f]{40}$/),
17
- repo: z.object({ full_name: z.string().min(1) })
121
+ repo: z.object({ full_name: gitHubRepositorySlugSchema })
18
122
  }) });
19
123
  const reviewCommentSchema = z.object({
20
124
  id: z.number().int().positive(),
21
125
  body: z.string(),
22
126
  html_url: z.url(),
23
- user: z.object({ login: z.string().min(1) }),
24
- in_reply_to_id: z.number().int().positive().nullish()
127
+ pull_request_url: z.url(),
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()
25
134
  });
26
135
  const submittedReviewSchema = z.object({
27
136
  id: z.number().int().positive(),
@@ -39,7 +148,7 @@ const issueCommentSchema = z.object({
39
148
  "User",
40
149
  "Organization"
41
150
  ])
42
- })
151
+ }).nullable()
43
152
  });
44
153
  const checkRunSchema = z.object({
45
154
  id: z.number().int().positive(),
@@ -77,7 +186,7 @@ const pullRequestCandidateSchema = z.object({
77
186
  user: z.object({ type: z.string().min(1) }),
78
187
  head: z.object({
79
188
  ref: z.string().min(1),
80
- repo: z.object({ full_name: z.string().min(1) })
189
+ repo: z.object({ full_name: gitHubRepositorySlugSchema })
81
190
  })
82
191
  });
83
192
  const openPullRequestsSchema = z.array(pullRequestCandidateSchema);
@@ -91,6 +200,14 @@ const pullRequestDetailSchema = pullRequestCandidateSchema.extend({
91
200
  sha: z.string().min(1)
92
201
  })
93
202
  });
203
+ const openPullRequestSummarySchema = z.object({
204
+ number: z.number().int().positive(),
205
+ html_url: z.url(),
206
+ title: z.string().min(1),
207
+ user: z.object({ login: z.string().min(1) }),
208
+ head: z.object({ ref: z.string().min(1) }),
209
+ draft: z.boolean()
210
+ });
94
211
  const collaboratorPermissionSchema = z.object({ permission: z.enum([
95
212
  "admin",
96
213
  "maintain",
@@ -104,14 +221,37 @@ const writePermissions = /* @__PURE__ */ new Set([
104
221
  "maintain",
105
222
  "write"
106
223
  ]);
224
+ /** Refusal raised when an inline review-comment author lacks repository write access. */
107
225
  var GitHubReviewCommentAuthorError = class extends Error {
108
226
  author;
109
227
  constructor(author) {
110
- 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`);
111
229
  this.name = "GitHubReviewCommentAuthorError";
112
230
  this.author = author;
113
231
  }
114
232
  };
233
+ /**
234
+ * The pull request advanced past the commit a review or fix was prepared
235
+ * against. Callers that reviewed a task keyed to a specific commit (for
236
+ * example `record_post_review`) can use `expectedSha`/`actualSha` to resolve
237
+ * the task as superseded instead of leaving it running for the stall
238
+ * watchdog to eventually -- and misleadingly -- report as "stalled".
239
+ */
240
+ var StalePullRequestHeadError = class extends Error {
241
+ expectedSha;
242
+ actualSha;
243
+ constructor(expectedSha, actualSha) {
244
+ super(`pull request changed after review: expected ${expectedSha}, found ${actualSha}`);
245
+ this.name = "StalePullRequestHeadError";
246
+ this.expectedSha = expectedSha;
247
+ this.actualSha = actualSha;
248
+ }
249
+ };
250
+ /** Whether a GitHub user may make repository-scoped Factory decisions. */
251
+ async function hasGitHubRepositoryWriteAccess(input) {
252
+ const { permission } = collaboratorPermissionSchema.parse(await gitHubRequest(input, `/collaborators/${encodeURIComponent(input.author)}/permission`));
253
+ return writePermissions.has(permission);
254
+ }
115
255
  /** Create a pull request from an existing head branch. */
116
256
  async function createPullRequest(input) {
117
257
  const pull = pullRequestSchema.parse(await gitHubRequest(input, "/pulls", {
@@ -125,14 +265,13 @@ async function createPullRequest(input) {
125
265
  })
126
266
  }));
127
267
  return {
128
- prNumber: pull.number,
129
- prUrl: pull.html_url
268
+ pullRequestNumber: pull.number,
269
+ pullRequestUrl: pull.html_url
130
270
  };
131
271
  }
132
272
  /** Create a check run for one commit. Requires a GitHub App token with checks:write. */
133
273
  async function createCheckRun(input) {
134
- if (input.status === "completed" && input.conclusion === void 0) throw new Error("completed check runs require a conclusion");
135
- if (input.status !== "completed" && input.conclusion !== void 0) throw new Error("creating a check run with a conclusion requires completed status");
274
+ assertCheckRunFields(input);
136
275
  return parseCheckRun(await gitHubRequest(input, "/check-runs", {
137
276
  method: "POST",
138
277
  body: JSON.stringify({
@@ -144,7 +283,7 @@ async function createCheckRun(input) {
144
283
  }
145
284
  /** Update a check run previously created by the authenticated GitHub App. */
146
285
  async function updateCheckRun(input) {
147
- if (input.status !== void 0 && input.status !== "completed" && input.conclusion !== void 0) throw new Error("a check run conclusion conflicts with an incomplete status");
286
+ assertCheckRunFields(input);
148
287
  return parseCheckRun(await gitHubRequest(input, `/check-runs/${positiveInteger(input.checkRunId, "checkRunId")}`, {
149
288
  method: "PATCH",
150
289
  body: JSON.stringify({
@@ -168,6 +307,51 @@ async function listPullRequestComments(input) {
168
307
  if (response.length < 100) return comments;
169
308
  }
170
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
+ }
171
355
  /** Add one issue-style comment to a pull request conversation. */
172
356
  async function createPullRequestComment(input) {
173
357
  return parseIssueComment(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/comments`, {
@@ -182,37 +366,75 @@ async function updatePullRequestComment(input) {
182
366
  body: JSON.stringify({ body: input.body })
183
367
  }));
184
368
  }
369
+ const readIssueCommentSchema = issueCommentSchema.extend({ issue_url: z.string().min(1) });
370
+ /**
371
+ * Read one issue comment from GitHub. A delivery authenticated as a workload
372
+ * rather than by body signature can name any author and any text, so the
373
+ * comment it refers to has to be read back before either is believed.
374
+ */
375
+ async function readIssueComment(input) {
376
+ const comment = readIssueCommentSchema.parse(await gitHubRequest(input, `/issues/comments/${positiveInteger(input.commentId, "commentId")}`));
377
+ const issueNumber = Number(comment.issue_url.split("/").pop());
378
+ if (!Number.isSafeInteger(issueNumber) || issueNumber < 1) throw new Error("GitHub returned an issue comment without a usable issue reference.");
379
+ return {
380
+ id: comment.id,
381
+ url: comment.html_url,
382
+ author: comment.user?.login ?? null,
383
+ authorType: comment.user?.type ?? null,
384
+ body: comment.body,
385
+ issueNumber
386
+ };
387
+ }
185
388
  /** Read one inline review comment after applying the author policy, which requires write access by default. */
186
389
  async function readReviewComment(input) {
187
390
  const comment = parseReviewComment(await gitHubRequest(input, `/pulls/comments/${positiveInteger(input.commentId, "commentId")}`));
391
+ assertReviewCommentPullRequest(input, comment);
188
392
  await assertReviewCommentAuthor(input, comment.author);
189
393
  return comment;
190
394
  }
191
395
  /** Reply to an inline review comment after applying the author policy, which requires write access by default. */
192
396
  async function answerReviewComment(input) {
193
- await readReviewComment(input);
194
- return 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`, {
195
405
  method: "POST",
196
406
  body: JSON.stringify({ body: input.body })
197
407
  }));
408
+ assertReviewCommentPullRequest(input, reply);
409
+ return reply;
198
410
  }
199
411
  /** Submit a summary and optional inline comments against a reviewed pull request commit. */
200
412
  async function submitPullRequestReview(input) {
201
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
+ });
202
429
  const head = await readPullRequestHead(input);
203
- if (head.sha !== commitId) throw new Error(`pull request changed after review: expected ${commitId}, found ${head.sha}`);
430
+ if (head.sha !== commitId) throw new StalePullRequestHeadError(commitId, head.sha);
204
431
  const review = submittedReviewSchema.parse(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/reviews`, {
205
432
  method: "POST",
206
433
  body: JSON.stringify({
207
434
  commit_id: commitId,
208
435
  event: input.event,
209
436
  body: input.body,
210
- comments: (input.comments ?? []).map((comment) => ({
211
- path: comment.path,
212
- line: positiveInteger(comment.line, "comment line"),
213
- side: "RIGHT",
214
- body: comment.body
215
- }))
437
+ comments
216
438
  })
217
439
  }));
218
440
  return {
@@ -227,16 +449,31 @@ async function readPullRequestHead(input) {
227
449
  return {
228
450
  branch: pull.head.ref,
229
451
  sha: pull.head.sha,
230
- repository: pull.head.repo.full_name.toLowerCase()
452
+ repository: pull.head.repo.full_name
231
453
  };
232
454
  }
233
455
  /** Read the provider-owned identity and lifecycle of one pull request. */
234
456
  async function readPullRequest(input) {
235
457
  const pull = readablePullRequestSchema.parse(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}`));
236
458
  return {
237
- number: pull.number,
238
- url: pull.html_url,
459
+ pullRequestNumber: pull.number,
460
+ pullRequestUrl: pull.html_url,
239
461
  author: pull.user.login,
462
+ authorType: pull.user.type,
463
+ state: pull.state
464
+ };
465
+ }
466
+ /** Close an open pull request without merging it. */
467
+ async function closePullRequest(input) {
468
+ const pull = readablePullRequestSchema.parse(await gitHubRequest(input, `/pulls/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}`, {
469
+ method: "PATCH",
470
+ body: JSON.stringify({ state: "closed" })
471
+ }));
472
+ return {
473
+ pullRequestNumber: pull.number,
474
+ pullRequestUrl: pull.html_url,
475
+ author: pull.user.login,
476
+ authorType: pull.user.type,
240
477
  state: pull.state
241
478
  };
242
479
  }
@@ -247,8 +484,8 @@ async function listConflictedPullRequests(input) {
247
484
  for (const candidate of candidates) {
248
485
  const pull = pullRequestDetailSchema.parse(await gitHubRequest(input, `/pulls/${candidate.number}`));
249
486
  if (pull.mergeable === false || pull.mergeable_state === "dirty") conflicted.push({
250
- prNumber: pull.number,
251
- prUrl: pull.html_url,
487
+ pullRequestNumber: pull.number,
488
+ pullRequestUrl: pull.html_url,
252
489
  headBranch: pull.head.ref,
253
490
  headSha: pull.head.sha,
254
491
  baseBranch: pull.base.ref,
@@ -257,6 +494,44 @@ async function listConflictedPullRequests(input) {
257
494
  }
258
495
  return conflicted;
259
496
  }
497
+ /** List open pull requests in a repository, newest first, to check for existing work before triage. */
498
+ async function listOpenPullRequests(input) {
499
+ return z.array(openPullRequestSummarySchema).parse(await gitHubRequest(input, `/pulls?state=open&per_page=100&sort=created&direction=desc`)).map((pull) => ({
500
+ prNumber: pull.number,
501
+ prUrl: pull.html_url,
502
+ title: pull.title,
503
+ author: pull.user.login,
504
+ headBranch: pull.head.ref,
505
+ draft: pull.draft
506
+ }));
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
+ }
260
535
  /** Add one label to a pull request. */
261
536
  async function addLabel(input) {
262
537
  return parseLabels(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/labels`, {
@@ -268,9 +543,16 @@ async function addLabel(input) {
268
543
  async function removeLabel(input) {
269
544
  return parseLabels(await gitHubRequest(input, `/issues/${positiveInteger(input.pullRequestNumber, "pullRequestNumber")}/labels/${encodeURIComponent(input.label)}`, { method: "DELETE" }));
270
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
+ };
271
553
  async function gitHubRequest(input, path, init = {}) {
272
- if (!repositorySlugPattern.test(input.repository)) throw new Error(`invalid GitHub repository slug: ${input.repository}`);
273
- const response = await (input.fetch ?? globalThis.fetch)(`${gitHubApiUrl}/repos/${input.repository}${path}`, {
554
+ const repository = repositorySlugSchema.parse(input.repository);
555
+ const response = await (input.fetch ?? globalThis.fetch)(`${gitHubApiUrl}/repos/${repository}${path}`, {
274
556
  ...init,
275
557
  headers: {
276
558
  Accept: "application/vnd.github+json",
@@ -283,28 +565,37 @@ async function gitHubRequest(input, path, init = {}) {
283
565
  const body = await response.json();
284
566
  if (!response.ok) {
285
567
  const message = z.object({ message: z.string() }).safeParse(body);
286
- 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);
287
569
  }
288
570
  return body;
289
571
  }
290
572
  function parseReviewComment(value) {
291
573
  const comment = reviewCommentSchema.parse(value);
574
+ const pullRequestMatch = /\/pulls\/([1-9]\d*)\/?$/.exec(new URL(comment.pull_request_url).pathname);
575
+ if (pullRequestMatch?.[1] === void 0) throw new Error("GitHub review comment has an invalid pull request URL");
292
576
  return {
293
577
  id: comment.id,
578
+ pullRequestNumber: positiveInteger(Number(pullRequestMatch[1]), "pullRequestNumber"),
294
579
  body: comment.body,
295
580
  url: comment.html_url,
296
- author: comment.user.login,
297
- 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
298
585
  };
299
586
  }
587
+ function assertReviewCommentPullRequest(input, comment) {
588
+ const expected = positiveInteger(input.pullRequestNumber, "pullRequestNumber");
589
+ if (comment.pullRequestNumber !== expected) throw new Error(`GitHub review comment ${comment.id} does not belong to pull request ${expected}`);
590
+ }
300
591
  function parseIssueComment(value) {
301
592
  const comment = issueCommentSchema.parse(value);
302
593
  return {
303
594
  id: comment.id,
304
595
  body: comment.body,
305
596
  url: comment.html_url,
306
- author: comment.user.login,
307
- authorType: comment.user.type
597
+ author: comment.user?.login ?? null,
598
+ authorType: comment.user?.type ?? null
308
599
  };
309
600
  }
310
601
  function parseLabels(value) {
@@ -336,6 +627,14 @@ function checkRunFields(input) {
336
627
  ...input.output === void 0 ? {} : { output: checkRunOutput(input.output) }
337
628
  };
338
629
  }
630
+ function assertCheckRunFields(input) {
631
+ if (input.status === "completed") {
632
+ if (input.conclusion === void 0) throw new Error("completed check runs require a conclusion");
633
+ return;
634
+ }
635
+ if (input.conclusion !== void 0) throw new Error("a check run conclusion requires completed status");
636
+ if (input.completedAt !== void 0) throw new Error("a check run completion time requires completed status");
637
+ }
339
638
  function checkRunOutput(output) {
340
639
  return {
341
640
  title: output.title,
@@ -356,8 +655,10 @@ function checkRunOutput(output) {
356
655
  }
357
656
  async function assertReviewCommentAuthor(input, author) {
358
657
  if (input.authorPolicy === "any") return;
359
- const { permission } = collaboratorPermissionSchema.parse(await gitHubRequest(input, `/collaborators/${encodeURIComponent(author)}/permission`));
360
- if (!writePermissions.has(permission)) throw new GitHubReviewCommentAuthorError(author);
658
+ if (author === null || !await hasGitHubRepositoryWriteAccess({
659
+ ...input,
660
+ author
661
+ })) throw new GitHubReviewCommentAuthorError(author);
361
662
  }
362
663
  function positiveInteger(value, name) {
363
664
  if (!Number.isInteger(value) || value < 1) throw new Error(`${name} must be a positive integer`);
@@ -383,7 +684,7 @@ const pushEventSchema = z.looseObject({
383
684
  ref: z.string().min(1),
384
685
  repository: z.looseObject({
385
686
  default_branch: z.string().min(1),
386
- full_name: z.string().min(1)
687
+ full_name: gitHubRepositorySlugSchema
387
688
  })
388
689
  });
389
690
  /** Normalize a push to a repository's default branch for deterministic reconciliation. */
@@ -394,7 +695,7 @@ function normalizeGitHubDefaultBranchPush(options) {
394
695
  return {
395
696
  source: "github_default_branch_push",
396
697
  deliveryId: options.deliveryId,
397
- repositorySlug: parsed.data.repository.full_name.toLowerCase(),
698
+ repositorySlug: parsed.data.repository.full_name,
398
699
  defaultBranch: parsed.data.repository.default_branch
399
700
  };
400
701
  }
@@ -408,14 +709,14 @@ const pullRequestEventSchema = z.looseObject({
408
709
  head: z.looseObject({
409
710
  sha: z.string().regex(/^[0-9a-f]{40}$/),
410
711
  ref: z.string().min(1),
411
- repo: z.looseObject({ full_name: z.string().min(1) })
712
+ repo: z.looseObject({ full_name: gitHubRepositorySlugSchema })
412
713
  }),
413
714
  base: z.looseObject({
414
715
  sha: z.string().regex(/^[0-9a-f]{40}$/),
415
716
  ref: z.string().min(1)
416
717
  })
417
718
  }),
418
- repository: z.looseObject({ full_name: z.string().min(1) }),
719
+ repository: z.looseObject({ full_name: gitHubRepositorySlugSchema }),
419
720
  sender: z.looseObject({ login: z.string().min(1) })
420
721
  });
421
722
  const reviewablePullRequestActions = /* @__PURE__ */ new Set([
@@ -430,7 +731,7 @@ function normalizeGitHubPullRequest(options) {
430
731
  const parsed = pullRequestEventSchema.safeParse(options.payload);
431
732
  if (!parsed.success || !reviewablePullRequestActions.has(parsed.data.action)) return null;
432
733
  if (parsed.data.pull_request.draft && parsed.data.action !== "ready_for_review") return null;
433
- const slug = parsed.data.repository.full_name.toLowerCase();
734
+ const slug = parsed.data.repository.full_name;
434
735
  const pull = parsed.data.pull_request;
435
736
  return {
436
737
  source: "github_pr",
@@ -441,13 +742,13 @@ function normalizeGitHubPullRequest(options) {
441
742
  address: `${slug}/pull/${parsed.data.number}`
442
743
  },
443
744
  pullRequest: {
444
- number: parsed.data.number,
445
- url: pull.html_url,
745
+ pullRequestNumber: parsed.data.number,
746
+ pullRequestUrl: pull.html_url,
446
747
  author: pull.user.login,
447
748
  draft: pull.draft,
448
749
  headSha: pull.head.sha,
449
750
  headBranch: pull.head.ref,
450
- headRepositorySlug: pull.head.repo.full_name.toLowerCase(),
751
+ headRepositorySlug: pull.head.repo.full_name,
451
752
  baseSha: pull.base.sha,
452
753
  baseBranch: pull.base.ref,
453
754
  sender: parsed.data.sender.login
@@ -462,7 +763,7 @@ const issueEventSchema = z.looseObject({
462
763
  title: z.string(),
463
764
  body: z.string().nullable()
464
765
  }),
465
- repository: z.looseObject({ full_name: z.string().min(1) })
766
+ repository: z.looseObject({ full_name: gitHubRepositorySlugSchema })
466
767
  });
467
768
  const failedWorkflowConclusions = /* @__PURE__ */ new Set([
468
769
  "action_required",
@@ -475,14 +776,14 @@ const workflowRunEventSchema = z.looseObject({
475
776
  action: z.string(),
476
777
  repository: z.looseObject({
477
778
  default_branch: z.string().min(1),
478
- full_name: z.string().min(1)
779
+ full_name: gitHubRepositorySlugSchema
479
780
  }),
480
781
  workflow_run: z.looseObject({
481
782
  id: z.number().int().min(1),
482
783
  name: z.string().min(1),
483
784
  event: z.string().min(1),
484
785
  head_branch: z.string().min(1).nullable(),
485
- head_repository: z.looseObject({ full_name: z.string().min(1) }).nullable(),
786
+ head_repository: z.looseObject({ full_name: gitHubRepositorySlugSchema }).nullable(),
486
787
  head_sha: z.string().min(1),
487
788
  html_url: z.url(),
488
789
  conclusion: z.string().nullable(),
@@ -498,7 +799,7 @@ function normalizeGitHubIssueOpened(options) {
498
799
  if (options.event !== "issues") return null;
499
800
  const parsed = issueEventSchema.safeParse(options.payload);
500
801
  if (!parsed.success || parsed.data.action !== "opened") return null;
501
- const slug = parsed.data.repository.full_name.toLowerCase();
802
+ const slug = parsed.data.repository.full_name;
502
803
  const { number, title, body } = parsed.data.issue;
503
804
  return {
504
805
  source: "github_issue",
@@ -525,7 +826,7 @@ const pullRequestClosedSchema = z.looseObject({
525
826
  merged_by: z.looseObject({ login: z.string().min(1) }).nullable().optional(),
526
827
  merge_commit_sha: z.string().regex(/^[0-9a-f]{40}$/).nullable().optional()
527
828
  }),
528
- repository: z.looseObject({ full_name: z.string().min(1) }),
829
+ repository: z.looseObject({ full_name: gitHubRepositorySlugSchema }),
529
830
  sender: z.looseObject({ login: z.string().min(1) })
530
831
  });
531
832
  /**
@@ -542,9 +843,9 @@ function normalizeGitHubPullRequestClosed(options) {
542
843
  return {
543
844
  source: "github_pull_request_closed",
544
845
  deliveryId: options.deliveryId,
545
- repositorySlug: parsed.data.repository.full_name.toLowerCase(),
546
- prNumber: pr.number,
547
- prUrl: pr.html_url,
846
+ repositorySlug: parsed.data.repository.full_name,
847
+ pullRequestNumber: pr.number,
848
+ pullRequestUrl: pr.html_url,
548
849
  merged: pr.merged,
549
850
  mergeCommitSha: pr.merged ? pr.merge_commit_sha ?? null : null,
550
851
  decidedBy: pr.merged ? pr.merged_by?.login ?? sender : sender
@@ -558,7 +859,7 @@ function normalizeGitHubWorkflowRunFailure(options) {
558
859
  const run = parsed.data.workflow_run;
559
860
  const conclusion = run.conclusion;
560
861
  if (conclusion === null || !failedWorkflowConclusions.has(conclusion)) return null;
561
- const slug = parsed.data.repository.full_name.toLowerCase();
862
+ const slug = parsed.data.repository.full_name;
562
863
  return {
563
864
  source: "github_ci_failure",
564
865
  deliveryId: options.deliveryId,
@@ -573,7 +874,7 @@ function normalizeGitHubWorkflowRunFailure(options) {
573
874
  name: run.name,
574
875
  trigger: run.event,
575
876
  branch: run.head_branch,
576
- headRepositorySlug: run.head_repository?.full_name.toLowerCase() ?? null,
877
+ headRepositorySlug: run.head_repository?.full_name ?? null,
577
878
  headSha: run.head_sha,
578
879
  url: run.html_url,
579
880
  conclusion,
@@ -583,6 +884,6 @@ function normalizeGitHubWorkflowRunFailure(options) {
583
884
  };
584
885
  }
585
886
  //#endregion
586
- export { GitHubReviewCommentAuthorError, addLabel, answerReviewComment, createCheckRun, createPullRequest, createPullRequestComment, listCheckRunsForRef, listConflictedPullRequests, listPullRequestComments, normalizeGitHubDefaultBranchPush, normalizeGitHubIssueOpened, normalizeGitHubPullRequest, normalizeGitHubPullRequestClosed, normalizeGitHubWorkflowRunFailure, readPullRequest, readPullRequestHead, readReviewComment, removeLabel, 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 };
587
888
 
588
889
  //# sourceMappingURL=github.mjs.map